安卓线刷升级, flash factory image for android

安卓线刷升级, flash factory image for android download factory image from https://developers.google.com/android/nexus/images https://developer.android.com/preview/get https://developers.google.com/android/images https://developer.android.com/about/versions/12/download wget https://dl.google.com/dl/android/aosp/angler-opr6.170623.013-factory-a63b2f21.zip #edit flash-all.sh and remove the -w command for linux https://wiki.archlinux.org/index.php/android#Detect_the_device 开发者模式 … unlock 开发者模式>oem unlock adb reboot bootloader fastboot flashing unlock # 按方向键切换到unlock # 按电源键解锁 手机开启 开发者模式,打开usb调试,oem unlock 将手机连接到电脑 # 进入root sudo -s #restart adb: adb kill-server adb start-server adb devices #reboot to bootloader: adb reboot bootloader #不用sudo会一直waiting device, 另外一种waiting device的情况 是连接 电脑的typc线有问题,比如只有充电功能...我的pixelbook带的线就不能刷机用。 ./flash-all.sh if failed, flash image manually ...

2015-01-29 · 2 min · 292 words · -

安卓查看WIFI密码

安卓查看WIFI密码 打开Root Exploere,进入data/misc/wifi/wpa_supplicant.conf

2015-01-28 · 1 min · 3 words · -

抽奖概率-三种算法

抽奖概率-三种算法 http://www.cnblogs.com/younggun/p/3249772.html 一、逢"几"中奖 逢"几"中奖,即通过预估抽奖人数和奖品数来判断,“几”=(抽奖人数/奖品数)*N。这是一种最简单抽奖算法,适合抽奖人数众多,而且互相无联系的情况。如今大为流行的微博转发得奖就常常使用这种算法,即根据转发次数来决定奖品归属,透明而且具有激励性。 当然这个"几"也不单只次数,还可能是时间,逢某个时间点就可以抽中,不过这种方案可能产生无人中奖和很多人中奖的情况,时间点的安排很关键!这个时间点一旦公布出去,那就是秒杀,霍霍。。 逢"几"中奖有很多弊端,但是非常简单,很容易实现,被很多抽奖活动所采用,有些会公布抽奖规则,激励抽奖,有些则不会公布,其实后台运行的可能也是这个算法,简单高效又不失公平。在信息不透明的情况下,鬼知道你是第几个抽奖的,哈哈。。 二、概率抽奖 所谓概率抽奖是最容易想到的抽奖算法了,这个概率可以是一成不变的,也可以是一直在变化调整的,最难的是采用多大的概率,何种情况下采用何种概率。这个也没有什么通用的方案,不同的应用场景,所用的概率算法不同。下面介绍一种算法,根据奖品的过期日期来计算它当前时间的中奖率,当时间逐渐接近奖品过期时间时,中奖概率会逐渐发生变化,如果设为1表示线性衰减,2为平方衰减,以此类推。 importjava.util.Date; importjava.util.Random; publicclass LotteryTool { private double factor; private double probability; private Random rand; private LotteryTool(double probability, long expireTime, int reduce){ this.factor = (double) System.currentTimeMillis() / expireTime; this.probability = probability * Math.pow(factor, reduce); this.rand = new Random(System.currentTimeMillis()); } public static LotteryTool getInstance(double probability, longexpireTime, int reduce) { return new LotteryTool(probability, expireTime, reduce); } public boolean isLucky(long expected) { long token = generateLong(); expected = expected % (int) (1 / probability); ...

2015-01-26 · 1 min · 180 words · -

BeanFactory, ApplicationContext

BeanFactory, ApplicationContext http://blog.csdn.net/liaomin416100569/article/details/4924183 org.springframework.beans.factory.BeanFactory 是Spring IoC容器的实际代表者, IoC容器负责容纳此前所描述的bean,并对bean进行管理。 在Spring中,BeanFactory是IoC容器的核心接口。 它的职责包括: 实例化、定位、配置 应用程序中的对象及建立这些对象间的依赖。 Spring为我们提供了许多易用的BeanFactory实现, XmlBeanFactory就是最常用的一个。 该实现将以XML方式描述组成应用的对象 以 及对象间的依赖关系。XmlBeanFactory类将获取此XML配 置元数据,并用它来构建一个完 全可配置的系统或应用。 BeanFactory 提供的高级配置机制,使得管理各种对象成为可能。 ApplicationContext 是BeanFactory的扩展,功能得到了进一步增强,比如更易 与Spring AOP集成、资源处理 (国际化处理)、事件传递及各种不同应用层的context实现 (如针对web应用的WebApplicationContext)。 简而言之,BeanFactory提供了配制框架及基本功能,而 ApplicationContext 则增加了 更多支持企业核心内容的功能。 ApplicationContext完全由BeanFactory扩展而来, 因而BeanFactory所具备的能力和行为也适用于ApplicationContext。 使用getBean(String) 方法就可以取得bean的实例;BeanFactory 提供的方法极其简单。 BeanFactory接口提供 了非常多的方法,但是对于我们的应用来说,最好永远不要调用它们,当然也包括 使用getBean(String)方法,这样可以避免我们对 Spring API的依赖。 BeanFactory 同时也不具备 编译spring配置文件的功能 在容器初始化时 如果applicationContext出现错误时 BeanFactory并不能及时察觉,必须等待第一次获取bean的实例时才能抛出异常 比如实例化 BeanFactory Resource res = new FileSystemResource(“applicationContext.xml”); BeanFactory factory = new XmlBeanFactory(res); Resource resClasspath = new ClassPathResource(“applicationContext.xml.xml”); BeanFactory factory2 = new XmlBeanFactory(resClasspath); 获得BeanFactory实例时 不能检查错误 User u=(User)u.getBean(“user”); ...

2015-01-26 · 1 min · 79 words · -

java vs javaw vs javaws

java vs javaw vs javaws http://javapapers.com/core-java/java-vs-javaw-vs-javaws/ This article gives an awareness tip. Do you know the difference between java, javaw and javaws tools. All these three are java application launchers. We know well about java.exe which we use quite often. Our command line friend, mostly we use it for convenience to execute small java programs. javaw is rare for us. Sometimes we have seen that in running application list in windows task manager. javaws is web start utility. ...

2015-01-22 · 3 min · 548 words · -

JaveEE

JaveEE http://www.iteye.com/topic/153734 1.MVC的各个部分都有那些技术来实现?如何实现? 答: MVC是Model-View-Controller的简写。“Model” 代表的是应用的业务逻辑 (通过JavaBean,EJB组件实现) , “View” 是应用的表示面 (由JSP页面产生) ,“Controller” 是提供应用的处理过程控制 (一般是一个Servlet) ,通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。 2.J2EE是什么? 答: Je22是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application model).在这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同计算机上,并且处于相应的层次(tier)中。所属层次包括客户层(clietn tier)组件,web层和组件,Business层和组件,企业信息系统(EIS)层。 http://www.wiloon.com/?p=1057 3.J2EE是技术还是平台还是框架? 答: J2EE本身是一个标准,一个为企业分布式应用的开发提供的标准平台。 J2EE也是一个框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技术。 4.STRUTS的应用(如STRUTS架构) 答: Struts是采用Java Servlet/JavaServer Pages技术,开发Web应用程序的开放源码的framework。 采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。 Struts有如下的主要功能: 一.包含一个controller servlet,能将用户的请求发送到相应的Action对象。 二.JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。 三.提供了一系列实用对象: XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。 5.WEB SERVICE名词解释。JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。 答: Web ServiceWeb Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。 JAXP(Java API for XML Parsing) 定义了在Java中使用DOM, SAX, XSLT的通用的接口。这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改代码。 JAXM(Java API for XML Messaging) 是为SOAP通信提供访问方法和传输机制的API。 WSDL是一种 XML 格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点 (服务) 。 SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。 ...

2015-01-22 · 2 min · 220 words · -

JSR303

JSR303 http://blog.csdn.net/caihaijiang/article/details/7463514 JSR 303 – Bean Validation 是一个数据验证的规范。 在任何时候,当你要处理一个应用程序的业务逻辑时,必须要考虑数据校验,确保输入进来的数据从语 义上来讲是正确的。在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余、不利于维护等问题。使用Bean Validation,将验证逻辑与相应的域模型进行绑定,能够很好的避免发生这样的问题。 Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如@NotNull,@Max,@Size, 就可以确保数据模型 (JavaBean) 的正确性。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。 Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。借助Hibernate Validator,可以很好的进行参数验证。 例子如下 (摘自参考文档2的内容) : maven依赖: <dependency> <groupId>com.alibaba.external</groupId> <artifactId>sourceforge.hibernate.validator</artifactId> <version>4.0.2.GA</version> </dependency> <dependency> <groupId>com.alibaba.external</groupId> <artifactId>java.validation.api</artifactId> <version>1.0.0.GA</version> </dependency> <dependency> <groupId>com.alibaba.external</groupId> <artifactId>org.slf4j.slf4j-api</artifactId> <version>1.5.6</version> </dependency> <dependency> <groupId>com.alibaba.external</groupId> <artifactId>org.slf4j.slf4j-log4j12</artifactId> <version>1.5.6</version> </dependency> <dependency> <groupId>com.alibaba.external</groupId> <artifactId>jakarta.log4j</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>com.alibaba.external</groupId> <artifactId>sourceforge.spring</artifactId> <version>2.5.6</version> </dependency> 2. 要校验的Java Bean ```java package com.mycompany; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public class Car { @NotNull private String manufacturer; @NotNull @Size(min = 2, max = 14) private String licensePlate; @Min(2) private int seatCount; public Car(String manufacturer, String licencePlate, int seatCount) { this.manufacturer = manufacturer; this.licensePlate = licencePlate; this.seatCount = seatCount; } //getters and setters ... } 3. 进行的校验 ```java import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.junit.BeforeClass; import org.junit.Test; public class CarTest { private static Validator validator; @BeforeClass public static void setUp() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } @Test public void manufacturerIsNull() { Car car = new Car(null, "DD-AB-123", 4); Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); assertEquals(1, constraintViolations.size()); assertEquals("may not be null", constraintViolations.iterator().next().getMessage()); } @Test public void licensePlateTooShort() { Car car = new Car("Morris", "D", 4); Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); assertEquals(1, constraintViolations.size()); assertEquals("size must be between 2 and 14", constraintViolations.iterator().next().getMessage()); } } 更详细的使用,请看参考文档2. 参考文档: 1. JSR 303: http://jcp.org/en/jsr/summary?id=303 2. HIBERNATE Validator: http://docs.jboss.org/hibernate/validator/4.2/reference/en-US/pdf/hibernate_validator_reference.pdf 3. 中文版的: http://docs.jboss.org/hibernate/validator/4.2/reference/zh-CN/html/validator-usingvalidator.html

2015-01-22 · 2 min · 236 words · -

SSH 端口转发, ssh port forward

SSH 端口转发, ssh port forward 端口转发, ssh port forward 比如在一台远程主机上运行着 Grafana: 192.168.50.100:32178, 但是 192.168.50.100 只对 192.168.50.50 开放了 22 端口, 我想从 192.168.50.50 访问 192.168.50.100 的 Grafana 就可以用 ssh 的端口转发 # -L: local port forwarding # 在 192.168.50.50 上执行 ssh -L 32179:192.168.50.100:32178 192.168.50.100 -l user0 # 32179 本地端口, 用户可以在 192.168.50.50 上用浏览器直接访问本地的 32179 端口的 grafana, http://127.0.0.1:32179 # 192.168.50.100:32178, 要访问的 ip 和 端口, 在 192.168.50.50 上访问 127.0.0.1:32179 就相当于访问 192.168.50.100:32178 # 192.168.50.100 -l user0, ssh 连接的主机和用户名, 这里用了默认的 ssh 22 端口 ssh -L 2000:192.168.50.11:5432 192.168.50.10 -l root # 2000 本地端口 # 192.168.50.11 目标主机 # 5432 目标端口 # 192.168.50.10 跳板机, 运行 ssh 服务端的主机, 并且 从192.168.50.10 能访问 192.168.50.11:5432 https://wangdoc.com/ssh/port-forwarding.html ...

2015-01-18 · 2 min · 386 words · -

git submodule

git submodule 有 submodule 的 git 仓库根目录会有 .gitmodules 文件。 # check submodule with command git submodule status # 有输出就是有 submodule 当你在一个 Git 项目上工作时,你需要在其中使用另外一个Git 项目。也许它是一个第三方开发的Git 库或者是你独立开发和并在多个父项目中使用的。这个情况下一个常见的问题产生了: 你想将两个项目单独处理但是又需要在其中一个中使用另外一个。 在 Git 中你可以用子模块 submodule 来管理这些项目,submodule 允许你将一个 Git 仓库当作另外一个 Git 仓库的子目录。这允许你克隆另外一个仓库到你的项目中并且保持你的提交相对独立。 主仓库切换分支之后,子仓库并不会跟着一起切换, 得在主仓库上执行一次 git submodule update git submodule update –init 将 git submodule init 和 git submodule update 合并成一步。如果还要初始化、抓取并检出任何嵌套的子模块, 请使用简明的 git submodule update –init –recursive。 # 添加 submodule # 为已有的 git 仓库增加子模块, 命令执行完成,会在当前工程根路径下生成一个名为“.gitmodules”的文件 # enx: 子模块的目录名 git submodule add git@github.com:wiloon/enx.git enx # 已经配置子模块的仓库, 主项目和子模块一起克隆 git clone -b branch_0 git@github.com:foo/bar.git --recursive # 查看子模块, 如果 git submodule 返回的 hash 前面有一个减号, 代表子模块还没有检出, 加号代表 submodule 距离上一次跟主仓库关联的 commit id 有新的 commit, 这时在主仓库里对 submodule 所在的目录做 git add folder0 之后 git submodule 命令返回的数据不再有加号. # git submodule 返回的 commit id 是当前 submodule 目录当前的 commit id # commit id 前面 的加号代表远程仓库关联的submodule 有更新, 执行 git submodule update 之后 , submodule 的版本会更新到与远程主仓库关联的submodule commit id 一致. git submodule # 比如只克隆了主仓库, submodule 所在的目录肯定是空的, 要用这个命令初始化一下 submodule, 然后再执行 git submodule update, submodule 目录就克隆下来了. git submodule init # 把submodule 更新到跟远程主仓库关联的 commit id 一致, git status 应该是 clear 的 git submodule update # 更新指定的 submodule 到远程仓库的最新版本 git submodule update --init --remote <submodule_path> # 把 submodule 更新到子仓库最新的 commit id, 这个 commit 有可能跟之前关联的 commit id 不一样, 一般会比之前 关联的 commit id 更新, git status 会看到 submodule 有变更需要提交, 需要更新 关联的 commit id. git submodule update --remote # 拉取子模块 的代码 git submodule update --init --recursive 使用 submodule, 主仓库 git pull 之后, submodule 不会自动更新, 还要检查一下 submodule 的版本, 可能需要执行git submodule update 更新 一下. ...

2015-01-18 · 2 min · 253 words · -

affect, influence 与 impact 的区别

affect, influence 与 impact 的区别 http://blog.sina.com.cn/s/blog_90bb205c0101ceza.html (2013-02-26 15:47:23) 转载▼ 标签: affect influence impact 分类: 词汇学习 affect 作主语通常是物而不是人,指一物对另一物产生的消极影响。 The tax increases have affected us all. 加税已经影响了我们所有的人。《简明英汉词典》 The dampness began to affect my health. 潮气开始影响我的健康。《新牛津英汉双解大词典》 Your attitude will affect how successful you are. 你的态度会影响你成功的程度。《新牛津英汉双解大词典》 influence 侧重在思想、性格、行为等方面所产生的潜移默化的影响,也可指自然力的影响。 The labour enthusiasm of the workers strongly influenced us. 工人们的劳动热情强烈地感染了我们。《简明英汉词典》 It’s all too easy to be influenced by our parents. 我们容易受父母的影响。《简明英汉词典》 The weather influences crops. 天气影响农作物。 ...

2015-01-18 · 1 min · 137 words · -

sqlite command

sqlite command 在列模式下,每条记录在一个单独地行中以数据列对齐的方式显示。列如: sqlite> .mode column 显示 列名.header on 查出所有的表: select name from sqlite_master where type=‘table’ order by name; 通过以下语句可查询出某个表的所有字段信息 PRAGMA table_info([tablename]) cur.execute(“PRAGMA table_info(table)”) print cur.fetchall() http://duduhehe.iteye.com/blog/1344858 http://www.cnblogs.com/riskyer/p/3333809.html Go sqlite import ( "database/sql" "fmt" _ "github.com/mattn/go-sqlite3" "rssx/utils/logger" ) func test() { db, err := sql.Open("sqlite3", "./foo.db") checkErr(err) createTable := `CREATE TABLE if not exists users ( id char(36) PRIMARY KEY NOT NULL, name varchar(50) DEFAULT NULL, create_time timestamp DEFAULT NULL ); ` r, err := db.Exec(createTable) checkErr(err) logger.Infof("%+v", r) stmt, err := db.Prepare("INSERT INTO `users` VALUES (?,?,?);") checkErr(err) res, err := stmt.Exec(0, "wiloon", "2017-12-07 22:10:49") checkErr(err) id, err := res.LastInsertId() checkErr(err) fmt.Println(id) db.Close() } func checkErr(err error) { if err != nil { logger.Errorf("err: %v", err) } } 导出, export, dump, 导入, import, read # export sqlite3 db/boardsprofile.db ".dump" > /var/ftp/profile.sql # import sqlite3 test.db ".read /var/ftp/profile.sql"

2015-01-17 · 1 min · 137 words · -

Go bufio

golang bufio bufio 对 io 进行了包装, 提供了缓冲. bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。 简单的说就是bufio会把文件内容读取到缓存中 (内存),然后再取读取需要的内容的时候,直接在缓存中读取,避免文件的i/o操作。同样,通过bufio写入内容,也是先写入到缓存中 (内存),然后由缓存写入到文件。避免多次小内容的写入操作I/O。 bufio.Read(p []byte) 的思路如下: 1、当缓存区有内容的时,将缓存区内容全部填入p并清空缓存区 2、当缓存区没有内容的时候且len(p)>len(buf),即要读取的内容比缓存区还要大,直接去文件读取即可 3、当缓存区没有内容的时候且len(p)<len(buf),即要读取的内容比缓存区小,缓存区从文件读取内容充满缓存区,并将p填满 (此时缓存区有剩余内容) 4、以后再次读取时缓存区有内容,将缓存区内容全部填入p并清空缓存区 (此时和情况1一样) https://www.cnblogs.com/ricklz/p/13188188.html http://www.cnblogs.com/golove/p/3282667.html // bufio 包实现了带缓存的 I/O 操作 type Reader struct { … } // NewReaderSize 将 rd 封装成一个带缓存的 bufio.Reader 对象, // 缓存大小由 size 指定 (如果小于 16 则会被设置为 16) 。 // 如果 rd 的基类型就是有足够缓存的 bufio.Reader 类型,则直接将 // rd 转换为基类型返回。 func NewReaderSize(rd io.Reader, size int) *Reader // NewReader 相当于 NewReaderSize(rd, 4096) func NewReader(rd io.Reader) *Reader ...

2015-01-16 · 7 min · 1357 words · -

httpcomponent, httpclient proxy setting

httpcomponent, httpclient proxy setting http://www.jianshu.com/p/f38a62efaa96 HttpHost proxy = new HttpHost("localhost",8888); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultRequestConfig(RequestConfig.custom() .setProxy(proxy).build()).build();

2015-01-16 · 1 min · 16 words · -

zookeeper

zookeeper [16/11/21 03:20:30:030 CST] main-SendThread(192.168.50.100:2181) WARN zookeeper.ClientCnxn: Session 0x0 for server 192.168.50.100/:2181, unexpected error, closing socket connection and attempting reconnect 检查zookeeper包版本和连接的服务端版本,有可能是版本不一致 https://blog.csdn.net/richie696/article/details/112910751 向 zookeeper 发送 stat 命令 查询 zookeeper版本 echo stat | socat - TCP:192.168.50.100:2181 server # docker docker run \ --name zookeeper \ -p 2181:2181 \ -v /etc/localtime:/etc/localtime:ro \ -v zookeeper-conf:/conf \ -v zookeeper-data:/data \ -v zookeeper-datalog:/datalog \ -d \ zookeeper # podman podman run \ --name zookeeper \ -p 2181:2181 \ -v /etc/localtime:/etc/localtime:ro \ -e ZOO_4LW_COMMANDS_WHITELIST=* \ -d \ zookeeper # conf, data volume podman run \ --name zookeeper \ -p 2181:2181 \ -v /etc/localtime:/etc/localtime:ro \ -v zookeeper-conf:/conf \ -v zookeeper-data:/data \ -v zookeeper-datalog:/datalog \ -e ZOO_4LW_COMMANDS_WHITELIST=* \ -d \ zookeeper:3.7.0 # client docker run -it --rm zookeeper zkCli.sh -server 127.0.0.1 #zkCli.sh #连接zookeeper bin/zkCli.sh -server localhost:2181 #创建节点 create /k0 v0 # 删除一个节点 delete /k0 install download zookeeper cp zoo_sample.cfg zoo.cfg ...

2015-01-14 · 2 min · 425 words · -

thread join

thread join thread join 之后,主线程的状态是waiting 一、在研究join的用法之前,先明确两件事情。 1.join方法定义在Thread类中,则调用者必须是一个线程, 例如: Thread t = new CustomThread();//这里一般是自定义的线程类 t.start();//线程起动 t.join();//此处会抛出InterruptedException异常 2.上面的两行代码也是在一个线程里面执行的。 以上出现了两个线程,一个是我们自定义的线程类,我们实现了run方法,做一些我们需要的工作;另外一个线程,生成我们自定义线程类的对象,然后执行 customThread.start(); customThread.join(); 在这种情况下,两个线程的关系是一个线程由另外一个线程生成并起动,所以我们暂且认为第一个线程叫做"子线程",另外一个线程叫做"主线程"。 二、为什么要用join()方法 主线程生成并起动了子线程,而子线程里要进行大量的耗时的运算(这里可以借鉴下线程的作用),当主线程处理完其他的事务后,需要用到子线程的处理结果,这个时候就要用到join();方法了。 三、join方法的作用 在网上看到有人说"将两个线程合并"。这样解释我觉得理解起来还更麻烦。不如就借鉴下API里的说法: “等待该线程终止。” 解释一下,是主线程(我在"一"里已经命名过了)等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。(Waits for this thread to die.) 四、用实例来理解 写一个简单的例子来看一下join()的用法,一共三个类: 1.CustomThread 类 CustomThread1类 JoinTestDemo 类,main方法所在的类。 代码1: package wxhx.csdn2; /** * * @author bzwm * */ class CustomThread1 extends Thread { public CustomThread1() { super("[CustomThread1] Thread"); }; public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); try { for (int i = 0; i < 5; i++) { System.out.println(threadName + " loop at " + i); Thread.sleep(1000); } System.out.println(threadName + " end."); } catch (Exception e) { System.out.println("Exception from " + threadName + ".run"); } } } class CustomThread extends Thread { CustomThread1 t1; public CustomThread(CustomThread1 t1) { super("[CustomThread] Thread"); this.t1 = t1; } public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); try { t1.join(); System.out.println(threadName + " end."); } catch (Exception e) { System.out.println("Exception from " + threadName + ".run"); } } } public class JoinTestDemo { public static void main(String[] args) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); CustomThread1 t1 = new CustomThread1(); CustomThread t = new CustomThread(t1); try { t1.start(); Thread.sleep(2000); t.start(); t.join();//在代碼2里,將此處注釋掉 } catch (Exception e) { System.out.println("Exception from main"); } System.out.println(threadName + " end!"); } } 打印结果: main start.//main方法所在的线程起动,但没有马上结束,因为调用t.join();,所以要等到t结束了,此线程才能向下执行。 [CustomThread1] Thread start.//线程CustomThread1起动 [CustomThread1] Thread loop at 0//线程CustomThread1执行 [CustomThread1] Thread loop at 1//线程CustomThread1执行 [CustomThread] Thread start.//线程CustomThread起动,但没有马上结束,因为调用t1.join();,所以要等到t1结束了,此线程才能向下执行。 [CustomThread1] Thread loop at 2//线程CustomThread1继续执行 [CustomThread1] Thread loop at 3//线程CustomThread1继续执行 [CustomThread1] Thread loop at 4//线程CustomThread1继续执行 [CustomThread1] Thread end. //线程CustomThread1结束了 [CustomThread] Thread end.// 线程CustomThread在t1.join();阻塞处起动,向下继续执行的结果 main end!//线程CustomThread结束,此线程在t.join();阻塞处起动,向下继续执行的结果。 修改一下代码,得到代码2: (这里只写出修改的部分) ```java public class JoinTestDemo { public static void main(String[] args) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); CustomThread1 t1 = new CustomThread1(); CustomThread t = new CustomThread(t1); try { t1.start(); Thread.sleep(2000); t.start(); // t.join();//在代碼2里,將此處注釋掉 } catch (Exception e) { System.out.println("Exception from main"); } System.out.println(threadName + " end!"); } } 打印结果: main start. // main方法所在的线程起动,但没有马上结束,这里并不是因为join方法,而是因为Thread.sleep(2000); [CustomThread1] Thread start. //线程CustomThread1起动 [CustomThread1] Thread loop at 0//线程CustomThread1执行 [CustomThread1] Thread loop at 1//线程CustomThread1执行 main end!// Thread.sleep(2000);结束,虽然在线程CustomThread执行了t1.join();,但这并不会影响到其他线程(这里main方法所在的线程)。 [CustomThread] Thread start. //线程CustomThread起动,但没有马上结束,因为调用t1.join();,所以要等到t1结束了,此线程才能向下执行。 [CustomThread1] Thread loop at 2//线程CustomThread1继续执行 [CustomThread1] Thread loop at 3//线程CustomThread1继续执行 [CustomThread1] Thread loop at 4//线程CustomThread1继续执行 [CustomThread1] Thread end. //线程CustomThread1结束了 [CustomThread] Thread end. // 线程CustomThread在t1.join();阻塞处起动,向下继续执行的结果 五、从源码看join()方法 在CustomThread的run方法里,执行了t1.join();,进入看一下它的JDK源码: ```java public final void join() throws InterruptedException { n(0); } 然后进入join(0)方法: ```java /** * Waits at most `millis` milliseconds for this thread to * die. A timeout of `` means to wait forever. //注意这句 * * @param millis the time to wait in milliseconds. * @exception InterruptedException if another thread has interrupted * the current thread. The _interrupted status_ of the * current thread is cleared when this exception is thrown. */ public final synchronized void join(long millis) //参数millis为0. throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) {//进入这个分支 while (isAlive()) {//判断本线程是否为活动的。这里的本线程就是t1. wait(0);//阻塞 } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } 单纯从代码上看,如果线程被生成了,但还未被起动,调用它的join()方法是没有作用的。将直接继续向下执行,这里就不写代码验证了。 http://blog.csdn.net/bzwm/article/details/3881392

2015-01-13 · 3 min · 503 words · -

苹果 WebApp

苹果 WebApp 苹果真的要在 AppStore 里封杀 WebApp 吗? http://fins.iteye.com/blog/1685886 苹果真的要在 AppStore 里封杀 WebApp 吗 ? 最近几个月, 苹果AppStore似乎加强了对WebApp的管控, 很多过去能上架的 使用WebApp+Native壳的应用陆陆续续的都被拒了. 于是 很多人开始抛出了"苹果要封杀WebApp"/"苹果要像当初对待Flash一样对HTML5说不"一类的观点. 作为一个HTML5开发人员 + 苹果产品用户, 我也想表达一下自己对这个问题的看法. 我的观点不一定对 但是,即使我错了,也不能证明那些认为"苹果要封杀WebApp"的荒谬观点是正确的(好流氓 哈哈). 先来看一看让广大HTML5/WebApp开发者 感动忧虑的那段苹果的原文吧: 引用 If you cannot – or choose not to – revise your app to be in compliance with the App Store Review Guidelines, you may wish to build an HTML5 web app instead. You can distribute web apps directly on your web site; the App Store does not accept or distribute web apps. 简单说就是一句话: 如果你的应用是一个Webapp, 那么请以网页的形式发布你的产品就好了, 不要放到AppStore里, AppStore不接收WebApp. 不管怎么看 我都看不出来"苹果要封杀WebApp"的意思, 更看不出有些人YY的"苹果因为担心HTML5太强大了抢了Native的市场"这种观点. 相反 我觉得苹果是在引导WebApp用正确的方式去发行: 如果你的应用在网页里也能跑, 但你却非要放到AppStore里, 结果就是赚了钱还要分给苹果30%, 而且更新升级什么的还要走漫长的审核过程,何苦呢? 在AppStore方面, 苹果是靠应用(注意,是应用,而不是和某种具体技术绑定的应用.只要是合法的 好的应用,受欢迎卖得多,苹果都能赚钱,苹果才不关心应用用的是什么技术呢)分成赚钱, 如果纯粹从经济目的出发, 苹果完全没必要把WebApp从他能赚钱的领域(AppStore应用)驱赶到他不能赚钱的领域(Web浏览器). 所以 一个合法的应用被拒绝的原因笼统的说只有三点: 1 违规(调用不该调用的方法,做了危险的事情,山寨抄袭等等) 2 苹果觉得应用不够好 3 觉得放到AppStore里不合适. 前两点不用说大家都懂, 而最后一点我想是大量WebApp被拒绝的一个主要原因: 完全没有使用或者没必要使用任何Native的技术,在网页里也能跑. 通常这种应用只是把AppStore当做一个发行渠道. 我特意去AppStore上搜索了下, 其实存在大量的Phonegap封装的应用, 我挑了几个免费的下来,解包看了一下, 它们都使用到了Phonegap提供的一些只有native技术才能实现的功能, 我想这是他们能通过审核的一个很重要的原因之一. ========================= 还有朋友提出了这样一个观点:“app store的意义是维护苹果利益,webapp可以同时存在多个平台,就会降低apple独占的市场份额,直接影响利益。” ...

2015-01-12 · 1 min · 173 words · -

ETL

ETL http://baike.baidu.com/subview/69207/14676359.htm ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过萃取 (extract) 、转置 (transform) 、加载 (load) 至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于数据仓库。 ETL是构建数据仓库的重要一环,用户从数据源抽取出所需的数据,经过数据清洗,最终按照预先定义好的数据仓库模型,将数据加载到数据仓库中去。 信息是现代企业的重要资源,是企业运用科学管理、决策分析的基础。目前,大多数企业花费大量的资金和时间来构建联机事务处理OLTP的业务系统和办公自动化系统,用来记录事务处理的各种相关数据。据统计,数据量每2~3年时间就会成倍增长,这些数据蕴含着巨大的商业价值,而企业所关注的通常只占在总数据量的2%~4%左右。因此,企业仍然没有最大化地利用已存在的数据资源,以致于浪费了更多的时间和资金,也失去制定关键商业决策的最佳契机。于是,企业如何通过各种技术手段,并把数据转换为信息、知识,已经成了提高其核心竞争力的主要瓶颈。而ETL则是主要的一个技术手段。目前,ETL工具的典型代表有:Informatica、Datastage、OWB、微软DTS、Beeload、Kettle、久其ETL…… 开源的工具有eclipse的etl插件。cloveretl. 数据集成: 快速实现ETL ETL的质量问题具体表现为正确性、完整性、一致性、完备性、有效性、时效性和可获取性等几个特性。而影响质量问题的原因有很多,由系统集成和历史数据造成的原因主要包括:业务系统不同时期系统之间数据模型不一致;业务系统不同时期业务过程有变化;旧系统模块在运营、人事、财务、办公系统等相关信息的不一致;遗留系统和新业务、管理系统数据集成不完备带来的不一致性。 实现ETL,首先要实现ETL转换的过程。体现为以下几个方面: 空值处理: 可捕获字段空值,进行加载或替换为其他含义数据,并可根据字段空值实现分流加载到不同目标库。 规范化数据格式: 可实现字段格式约束定义,对于数据源中时间、数值、字符等数据,可自定义加载格式。 拆分数据: 依据业务需求对字段可进行分解。例,主叫号 861082585313-8148,可进行区域码和电话号码分解。 验证数据正确性: 可利用Lookup及拆分功能进行数据验证。例如,主叫号861082585313-8148,进行区域码和电话号码分解后,可利用Lookup返回主叫网关或交换机记载的主叫地区,进行数据验证。 数据替换: 对于因业务因素,可实现无效数据、缺失数据的替换。 Lookup: 查获丢失数据 Lookup实现子查询,并返回用其他手段获取的缺失字段,保证字段完整性。 建立ETL过程的主外键约束: 对无依赖性的非法数据,可替换或导出到错误数据文件中,保证主键唯一记录的加载。为了能更好地实现ETL,笔者建议用户在实施ETL过程中应注意以下几点: 第一,如果条件允许,可利用数据中转区对运营数据进行预处理,保证集成与加载的高效性; 第二,如果ETL的过程是主动"拉取",而不是从内部"推送",其可控性将大为增强; 第三,ETL之前应制定流程化的配置管理和标准协议; 第四,关键数据标准至关重要。ETL面临的最大挑战是当接收数据时其各源数据的异构性和低质量。以电信为例,A系统按照统计代码管理数据,B系统按照账目数字管理,C系统按照语音ID管理。当ETL需要对这三个系统进行集成以获得对客户的全面视角时,这一过程需要复杂的匹配规则、名称/地址正常化与标准化。而ETL在处理过程中会定义一个关键数据标准,并在此基础上,制定相应的数据接口标准。 特色功能 编辑 ETL过程在很大程度上受企业对源数据的理解程度的影响,也就是说从业务的角度看数据集成非常重要。一个优秀的ETL设计应该具有如下功能: 管理简单 采用元数据方法,集中进行管理;接口、数据格式、传输有严格的规范;尽量不在外部数据源安装软件;数据抽取系统流程自动化,并有自动调度功能;抽取的数据及时、准确、完整;可以提供同各种数据系统的接口,系统适应性强;提供软件框架系统,系统功能改变时,应用程序很少改变便可适应变化;可扩展性强。 标准定义数据 合理的业务模型设计对ETL至关重要。数据仓库是企业唯一、真实、可靠的综合数据平台。数据仓库的设计建模一般都依照三范式、星型模型、雪花模型,无论哪种设计思想,都应该最大化地涵盖关键业务数据,把运营环境中杂乱无序的数据结构统一成为合理的、关联的、分析型的新结构,而ETL则会依照模型的定义去提取数据源,进行转换、清洗,并最终加载到目标数据仓库中。 模型的重要之处在于对数据做标准化定义,实现统一的编码、统一的分类和组织。标准化定义的内容包括: 标准代码统一、业务术语统一。ETL依照模型进行初始加载、增量加载、缓慢增长维、慢速变化维、事实表加载等数据集成,并根据业务需求制定相应的加载策略、刷新策略、汇总策略、维护策略。 拓展新型应用 对业务数据本身及其运行环境的描述与定义的数据,称之为元数据 (metadata) 。元数据是描述数据的数据。从某种意义上说,业务数据主要用于支持业务系统应用的数据,而元数据则是企业信息门户、客户关系管理、数据仓库、决策支持和B2B等新型应用所不可或缺的内容。 元数据的典型表现为对象的描述,即对数据库、表、列、列属性 (类型、格式、约束等) 以及主键/外部键关联等等的描述。特别是现行应用的异构性与分布性越来越普遍的情况下,统一的元数据就愈发重要了。“信息孤岛"曾经是很多企业对其应用现状的一种抱怨和概括,而合理的元数据则会有效地描绘出信息的关联性。 而元数据对于ETL的集中表现为: 定义数据源的位置及数据源的属性、确定从源数据到目标数据的对应规则、确定相关的业务逻辑、在数据实际加载前的其他必要的准备工作,等等,它一般贯穿整个数据仓库项目,而ETL的所有过程必须最大化地参照元数据,这样才能快速实现ETL。

2015-01-08 · 1 min · 56 words · -

Pareto principle, 帕累托法则, 二八定律

Pareto principle, 帕累托法则, 二八定律 二八定律又名80/20定律、帕累托法则 (定律) 也叫巴莱特定律、最省力的法则、不平衡原则等,被广泛应用于社会学及企业管理学等。[1] 1897年,意大利经济学者帕累托偶然注意到19世纪英国人的财富和收益模式。 二八定律 在调查取样中,发现大部份的财富流向了少数人手里。同时,他还从早期的资料中发现,在其他的国家,都发现有这种微妙关系一再出现,而且在数学上呈现出一种稳定的关系。于是,帕累托从大量具体的事实中发现: 社会上20%的人占有80%的社会财富,即: 财富在人口中的分配是不平衡的。 同时,人们还发现生活中存在许多不平衡的现象。因此,二八定律成了这种不平等关系的简称,不管结果是不是恰好为80%和20% (从统计学上来说,精确的80%和20%出现的概率很小) 。习惯上,二八定律讨论的是顶端的20%。而非底部的80%。人们所采用的二八定律,是一种量化的实证法,用以计量投入和产出之间可能存在的关系。[2]“长尾理论"被认为是对传统的"二八定律"的彻底叛逆。[2] 如右图所示,横轴是品种,纵轴是销量。典型的情况是只有少数产品销量较高,其余多数产品销量很低。 传统的二八定律 (或称20/80定律) 关注其中红色部分,认为20%的品种带来了80%的销量,所以应该只保留这部分,其余的都应舍弃。长尾理论则关注蓝色的长尾巴,认为这部分积少成多,可以积累成足够大、甚至超过红色部分的市场份额。但也有很多失败者并没有真正理解长尾理论的实现条件。[2] http://baike.baidu.com/view/40591.htm?fromtitle=%E5%B8%95%E7%B4%AF%E6%89%98%E6%B3%95%E5%88%99&fromid=7224763&type=syn

2015-01-08 · 1 min · 20 words · -

Nutch hello world

Nutch hello world download and install ant download and install Cygwin download HBase 0.94.14 http://mirrors.cnnic.cn/apache/hbase/stable/hbase-0.98.9-hadoop2-bin.tar.gz config java_home in .bashrc Download a source package http://mirror.bit.edu.cn/apache/nutch/2.2.1/ cd apache-nutch-2.2.1 Run ant Now there is a directory runtime/local which contains a ready to use Nutch installation. Customize your crawl properties Add your agent name in the value field of the http.agent.name property in conf/nutch-site.xml, for example: ...

2015-01-06 · 1 min · 149 words · -

禁用浏览器的后退按钮

禁用浏览器的后退按钮 浏览器的后退按钮是AJAX开发时候最让人头疼的一块,有的时候遇到这种问题,实在没有结果的情况下我们只能交给用户去学习适应,本文从缓存、JS跳转等方面阐述了如何绕过此问题,还是很值得我们借鉴的,虽然解释语言是ASP,但估计不会造成理解障碍。如果各位有什么其它的方法,不妨拿出来分享一下: ) 浏览器的后退按钮使得我们能够方便地返回以前访问过的页面,它无疑非常有用。但有时候我们不得不关闭这个功能,以防止用户打乱预定的页面访问次序。本文介绍网络上可找到的各种禁用浏览器后退按钮方案,分析它们各自的优缺点和适用场合。 一、概述 曾经有许多人问起,“怎样才能’禁用’浏览器的后退按钮?",或者"怎样才能防止用户点击后退按钮返回以前浏览过的页面?“在ASP论坛上,这个问题也是问得最多的问题之一。遗憾的是,答案非常简单: 我们无法禁用浏览器的后退按钮。 起先我对于居然有人想要禁用浏览器的后退按钮感到不可思议。后来,看到竟然有那么多的人想要禁用这个后退按钮,我也就释然 (想要禁用的只有后退按钮,不包括浏览器的前进按钮) 。因为在默认情况下,用户提交表单之后可以通过后退按钮返回表单页面 (而不是使用"编辑"按钮!) ,然后再次编辑并提交表单向数据库插入新的记录。这是我们不愿看到的。 因此我就决定要找出避免出现这种情况的方法。我访问了许多网站,参考了这些网站所介绍的各种实现方法。如果你经常访问ASP编程网站,本文所介绍的部分内容你可能已经见到过。本文的任务是把各种可能的方法都介绍给大家,然后找出最好的方法! 二、禁止缓存 在我找到的许多方案中,其中有一种建议禁止页面缓存。具体是使用服务器端脚本,如下所示: <% Response.Buffer = True Response.ExpiresAbsolute = Now() - 1 Response.Expires = 0 Response.CacheControl = “no-cache” %> 这种方法非常有效!它强制浏览器重新访问服务器下载页面,而不是从缓存读取页面。使用这种方法时,编程者的主要任务是创建一个会话级的变量,通过这个变量确定用户是否仍旧可以查看那个不适合通过后退按钮访问的页面。由于浏览器不再缓存这个页面,当用户点击后退按钮时浏览器将重新下载该页面,此时程序就可以检查那个会话变量,看看是否应该允许用户打开这个页面。 例如,假设我们有如下表单: <% Response.Buffer = True Response.ExpiresAbsolute = Now() - 1 Response.Expires = 0 Response.CacheControl = “no-cache” If Len(Session(“FirstTimeToPage”)) > 0 then 用户已经访问过当前页面,现在是再次返回访问。 清除会话变量,将用户重定向到登录页面。 Session(“FirstTimeToPage”) = "” Response.Redirect “/Bar.asp” Response.End End If 如果程序运行到这里,说明用户能够查看当前页面 以下开始创建表单 %> 我们借助会话变量FirstTimeToPage检查用户是否是第一次访问当前页面。如果不是第一次 (即Session(“FirstTimeToPage”)包含某个值) ,那么我们就清除会话变量的值,然后把用户重新定向到一个开始页面。这样,当表单提交时 (此时SompePage.asp被打开) ,我们必须赋予FirstTimeToPage一个值。即,在SomePage.asp中我们需要加上下面的代码: ...

2015-01-06 · 1 min · 193 words · -