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 · -

bash

bash # -n 选项代表只检查语法,不执行脚本。 bash -n foo.sh # -n 或 --noexec 选项告诉 Bash:只读取并检查脚本的语法是否正确,但不会实际执行脚本中的任何命令。 bash -c 用法: bash -c "cmd string" 通常使用shell去运行脚本,两种方法 bash xxx.sh,另外一种就是bash -c “cmd string” 对于bash xxx.sh, 首先bash 会在当前目录去寻找xxx.sh,如果找到,就直接运行,找不到则按照环境变量$PATH的指定路径,按顺序去找,如果找到,则执行,找不到则报错。 shell 脚本的参数 $0 就是要执行的 shell 脚本 xxx.sh, $1 就是后面紧跟 xxx.sh 的参数,$2 $3依次类推 而对于bash -c “cmd string” 首先我们看看官方的说明解释 -c If the -c option is present, then commands are read from the first non-option argument command_string. If there are arguments after the command_string, they are assigned to the positional parameters, starting with $0. ...

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

爬虫Labin,Nutch,Neritrix介绍和对比

爬虫Labin,Nutch,Neritrix介绍和对比 http://www.open-open.com/bbs/view/1325332257061 Larbin 开发语言: C++ http://larbin.sourceforge.net/index-eng.html larbin是个基于C++的web爬虫工具,拥有易于操作的界面,不过只能跑在LINUX下,在一台普通PC下larbin每天可以爬5百万个页面(当然啦,需要拥有良好的网络) 简介 Larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人 Sébastien Ailleret独立开发。larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源。 Larbin只是一个爬虫,也就是说larbin只抓取网页,至于如何parse的事情则由用户自己完成。另外,如何存储到数据库以及建立索引的事情 larbin也不提供。 Latbin最初的设计也是依据设计简单但是高度可配置性的原则,因此我们可以看到,一个简单的larbin的爬虫可以每天获取500万的网页,非常高效。 功能 larbin 获取单个、确定网站的所有联结,甚至可以镜像一个网站。 larbin建立 url 列表群,例如针对所有的网页进行 url retrive后,进行xml的联结的获取。或者是 mp3 。 larbin 定制后可以作为搜索引擎的信息的来源 (例如可以将抓取下来的网页每2000一组存放在一系列的目录结构里面) 。 问题 Labin的主要问题是,: 仅提供保存网页保存功能,没有进行进一步的网页解析; 不支持分布式系统; 功能相对简单,提供的配置项也不够多; 不支持网页自动重访,更新功能; 从2003年底以后,Labin已经放弃更新,目前处于荒芜长草的状态 ****** Nutch 开发语言: Java http://lucene.apache.org/nutch/ 简介: Apache的子项目之一,属于Lucene项目下的子项目。 Nutch是一个基于Lucene,类似Google的完整网络搜索引擎解决方案,基于Hadoop的分布式处理模型保证了系统的性能,类似Eclipse的插件机制保证了系统的可客户化,而且很容易集成到自己的应用之中。 总体上Nutch可以分为2个部分: 抓取部分和搜索部分。抓取程序抓取页面并把抓取回来的数据做成反向索引,搜索程序则对反向索引搜索回答用户的请求。抓取程序和搜索程序的接口是索引,两者都使用索引中的字段。抓取程序和搜索程序可以分别位于不同的机器上。下面详细介绍一下抓取部分。 抓取部分: 抓取程序是被Nutch的抓取工具驱动的。这是一组工具,用来建立和维护几个不同的数据结构: web database, a set of segments, and the index。下面逐个解释这三个不同的数据结构: The web database, 或者WebDB。这是一个特殊存储数据结构,用来映像被抓取网站数据的结构和属性的集合。WebDB 用来存储从抓取开始 (包括重新抓取) 的所有网站结构数据和属性。WebDB 只是被 抓取程序使用,搜索程序并不使用它。WebDB 存储2种实体: 页面 和 链接。页面 表示 网络上的一个网页,这个网页的Url作为标示被索引,同时建立一个对网页内容的MD5 哈希签名。跟网页相关的其它内容也被存储,包括: 页面中的链接数量 (外链接) ,页面抓取信息 (在页面被重复抓取的情况下) ,还有表示页面级别的分数 score 。链接 表示从一个网页的链接到其它网页的链接。因此 WebDB 可以说是一个网络图,节点是页面,链接是边。 ...

2015-01-05 · 2 min · 301 words · -

做与作

“作”与“做”的区别 “作”和“做”,都是常用字,音同,有时通用,所以使用时让人犯难,不知该用哪个字。 作,是古老的字,甲骨文里就有,最初的含义是“起”,现代汉语里仍然使用的“振作”、“一鼓作气”、“枪声大作”中的“作”,都是“起”的意思。在这个意义上跟“做”不会打架,因为“做”无此含义。 “作”和“做”,都有“从事”、“制作”、“充当”的含义,所以容易混淆。 做,是后造字,最早出现在宋、元时代,当“即使”、“播弄”、“做作”讲。到明代,“做”成了“作”的俗字,渐渐演变成为“作”的同义词。 那么,在使用时怎样区别“作”和“做”呢?20 世纪 80 年代,著名语言文字学家吕叔湘先生认为:“区别的办法基本上还是用‘文’和‘白’做标准,但不是绝对的。那么怎么办呢?我说,遇到没有把握的词,宁可写‘作’不写‘做’。”到了 20 世纪 90 年代,吕先生在《现代汉语八百词》中,对“作”、“做”二字的用法做了如下补充:“习惯上,具体东西的制造一般写成‘做’,如‘做桌子、做衣服、做文章’,抽象一点的、书面语言色彩重一点的词语,特别是成语里,一般都写成‘作’,如‘作罢、作废、作对、作怪、作乱、作价、作曲、作战、装模作样、认贼作父’。” 从吕叔湘先生的论述中,可以找到区分“作”、“做”用法的一般规律: (1)区别的基本标准是“文”和“白”,内容抽象或书面语言色彩重的词语,一般用“作”,成语都用“作”。 (2)做单音节动词用,多数用“做”,少数用“作”的,其宾语内容也比较抽象。宾语是动名词的(如:报告,调查,榜样,处理,动员,贡献),一般也用“作”。 (3)表身份、成绩、行为等义的“作为”,用“作”。 (4)遇到没有把握的词,宁可写“作”不写“做”,但要做到局部(一篇文章或一本书)统一。 基本词义: 作[zuō zuó zuò] 起,兴起,现在起:振~、枪声大~; 从事,做工:工~、~息、~业、合~; 3.举行,进行:~别(分别)、~乱、~案、~战、~报告; 干出,做出,表现出,制造出:~恶(è)、~弊、~梗、~祟、~态、~色、~为、~难、~奸犯科(为非作歹,触犯法令); 当成,充当:~罢、~保、~伐(做媒人)、~壁上观(人家交战,自己站在营垒上看,喻坐观别人成败)、~法自毙、~茧自缚; 写作、创造:创~、写~、~曲、~者; 文艺方面的成品:~品、不朽之~; 同“做”; 9.旧时手工业制造加工的场所:~坊; 10.从事某种活动:~揖、~弄、~死 做 [zuò]字义 1.进行工作或活动:~活、~事、~工、~手脚(暗中进行安排); 写文:~诗、~文章; 加工、制造:~饭、~模型、~衣服; 当,为:~人、~媒、~伴、~主、~客、看~; 5.装,扮:~作、~功、~派; https://zhuanlan.zhihu.com/p/70084978

2015-01-05 · 1 min · 40 words · -

将HTML5封装成android应用APK文件的几种方法

将HTML5封装成android应用APK文件的几种方法 http://mobile.51cto.com/android-386448.htm 越来越多的开发者热衷于使用html5+JavaScript开发移动Web App。不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数。一方面,用户在使用习惯上,不喜欢在浏览器上输入复杂的网址;另一方面,Html5 Web App 存放在服务器端,在每次使用时需要进行数据传递,会造成流量浪费。有些开发者不想接触复杂的JAVA代码,那么,有什么办法,既可以使用HTMl5开发应 用,又可以将其简单封装成APK文件呢? 一、Android SDK中的WebView 1.在要Activity中实例化WebView组件: WebView webView = new WebView(this); 2.调用WebView的loadUrl()方法,设置WevView要显示的网页: 互联网用: webView.loadUrl(“http://www.31358.com”); 本地文件用: webView.loadUrl(“file:///android_asset/XX.html”); 本地文件存放在: assets 文件中 3.调用Activity的setContentView( )方法来显示网页视图 4.用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面 5.需要在AndroidManifest.xml文件中添加权限,否则会出现Web page not available错误。 缺点: 如果是载入的是普通网页,没有什么问题,但如果是html5,封装后,在android2.3以上才能正常访问,android2.2及以下,SDK中的WebView还没完全支持HTML5 下面是具体例子: MainActivity.java package com.android.webview.activity; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.webkit.WebView; public class MainActivity extends Activity { private WebView webview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //实例化WebView对象 webview = new WebView(this); ...

2014-12-30 · 1 min · 134 words · -

smali

smali http://blog.csdn.net/caszhao/article/details/6030425 je或jz //相等则跳 (机器码是74或84) jne或jnz //不相等则跳 (机器码是75或85) 常见的修改就是把对比部分的机器码中74改成75或者84改成85,在反编译的smali文件中,也是类似的。 相等比较符号在smali中的表示 符号 smali语法 Bao力破解修改 == if-eq if-eq改成if-ne != if-ne if-ne 改成 if-eq equals if-eqz if-eqz改成 if-nez !equals if-nez if-nez 改成if-eqz

2014-12-30 · 1 min · 29 words · -

QNAP

QNAP qnap, plex server, apple tv, av1 https://www.reddit.com/r/PleX/comments/12pe5tx/comment/jgrrjnc/ https://github.com/currifi/plex_av1_tvos?tab=readme-ov-file https://support.plex.tv/articles/202915258-where-is-the-plex-media-server-data-directory-located/ https://www.qnap.com/en/how-to/faq/article/how-do-i-access-my-qnap-nas-using-ssh QNAP 启用 ssh 服务 ssh admin@192.168.50.227 # print The exact data directory location getcfg -f /etc/config/qpkg.conf PlexMediaServer Install_path mkdir /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/Library/Plex Media Server/Profiles # copy file https://github.com/scriptsingh/plex_av1_tvos/blob/main/tvOS.xml to Profiles dir 重启 plex server 威联通 nas web ui> app center> plex server stop start

2014-12-30 · 1 min · 53 words · -

maven-compiler-plugin

maven-compiler-plugin maven-compiler-plugin 用于编译 java 源码, 3.0 以后的版本 默认用 javax.tools.JavaCompiler 编译 maven-compiler-plugin 3.6 和更高版本提供了一种新的配置方法 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <release>9</release> </configuration> </plugin> jdk 9 以上可以只声明 maven.compiler.release <properties> <maven.compiler.release>17</maven.compiler.release> </properties> <!-- ... --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> </plugin> </plugins> maven-compiler-plugin 从 3.6 开始可以只配置 <maven.compiler.release>, 来替代 maven.compiler.source and maven.compiler.target maven-compiler-plugin 会从 <properties> 里读取 maven.compiler.release, 可以不配置到 plugin>configuration 下 “maven.compiler.release” as an replacement for source and target http://blog.csdn.net/zhaoyongnj2012/article/details/23970451 在maven的默认配置中, 对于 jdk 的配置是 1.4 版本,那么创建/导入 maven 工程过程中, 工程中未指定 jdk版本。 ...

2014-12-30 · 1 min · 113 words · -

maven cmd utf8 error

maven cmd utf8 error unmappable character for encoding GBK <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> http://stackoverflow.com/questions/3017695/how-to-configure-encoding-in-maven

2014-12-30 · 1 min · 14 words · -

windows 命令行 杀进程

windows 命令行 杀进程 列出进程: tasklist|findstr task TASKKILL /IM taskmgr.exe TASKKILL.exe TASKKILL命令是Microsoft Windows内置的一款命令,可以用来终止进程,具体的命令规则如下: TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T] 参数列表: /S system 指定要连接到的远程系统。 /U [domain]user 指定应该在哪个用户上下文 执行这个命令。 /P [password] 为提供的用户上下文指定密码。如果忽略,提示输入。 /F 指定要强行终止的进程。 /FI filter 指定筛选进或筛选出查询的的任务。 /PID process id 指定要终止的进程的PID。 /IM image name 指定要终止的进程的图像名。通配符 ‘*‘可用来指定所有图像名。 /T Tree kill: 终止指定的进程和任何由此启动的子进程。 /? 显示帮助/用法。 示例 TASKKILL /S system /F /IM notepad.exe /T TASKKILL /PID 1230 /PID 1241 /PID 1253 /T TASKKILL /F /IM QQ.exe ...

2014-12-30 · 1 min · 95 words · -

Android APK反编译

Android APK反编译 http://blog.csdn.net/ithomer/article/details/6727581 这段时间在学Android应用开发,在想既然是用Java开发的应该很好反编译从而得到源代码吧,google了一下,确实很简单,以下是我的实践过程。 在此郑重声明,贴出来的目的不是为了去破解人家的软件,完全是一种学习的态度,不过好像通过这种方式也可以去汉化一些外国软件。 本文Android反编译教程,测试环境: Win7 Ultimate x64 Ubuntu 12.04 x86_x64 反编译工具包 下载 (2012-10-10更新) 一、Apk反编译得到Java源代码 下载上述反编译工具包,打开apk2java目录下的dex2jar-0.0.9.9文件夹,内含apk反编译成java源码工具,以及源码查看工具。 apk反编译工具dex2jar,是将apk中的classes.dex转化成jar文件 源码查看工具jdgui,是一个反编译工具,可以直接查看反编译后的jar包源代码 dex2jar 和 jdgui 最新版本下载,分别见google code: dex2jar (google code) jdgui (google code) ,最新版本请见 官方 具体步骤: 首先将apk文件后缀改为zip并解压,得到其中的classes.dex,它就是java文件编译再通过dx工具打包而成的,将classes.dex复制到dex2jar.bat所在目录dex2jar-0.0.9.9文件夹。 在命令行下定位到dex2jar.bat所在目录,运行 dex2jar.bat classes.dex 生成 classes_dex2jar.jar 然后,进入jdgui文件夹双击jd-gui.exe,打开上面生成的jar包classes_dex2jar.jar,即可看到源代码了,如下图: HelloAndroid源码在反编译前后的对照如下: 二、apk反编译生成程序的源代码和图片、XML配置、语言资源等文件 如果是汉化软件,这将特别有用 首先还是要下载上述反编译工具包,其中最新的apktool,请到google code下载 apktool (google code) 具体步骤: 下载上述反编译工具包,打开apk2java目录下的apktool1.4.1文件夹,内含三个文件: aapt.exe,apktool.bat,apktool.jar 注: 里面的apktool_bk.jar是备份的老版本,最好用最新的apktool.jar 在命令行下定位到apktool.bat文件夹,输入以下命令: apktool.bat d -f abc123.apk abc123,如下图: 上图中,apktool.bat 命令行解释: apktool.bat d -f [apk文件 ] [输出文件夹] 反编译的文件如下 (AndroidManifest.xml为例) : 将反编译完的文件重新打包成apk,很简单,输入apktool.bat b abc123 (你编译出来文件夹) 即可,命令如下: ...

2014-12-30 · 1 min · 93 words · -

Set JAVA_HOME in windows cmd

Set JAVA_HOME in windows cmd http://kooyee.iteye.com/blog/525068 set JAVA_HOME=jrepath set PATH=%JAVA_HOME%\bin;%PATH% 注意这里没有引号。 这样就不需要在我的电脑属性中修改java_home了,以及重启命令行了。 对于程序会用到多个jre 会比较有用。 linux 修改 JAVA_HOME如下 export JAVA_HOME=jrepath export PATH=$JAVA_HOME\bin;$PATH 如果需要永久修改 则 在.bashrc文件中加入上面的两句话就可以了。

2014-12-29 · 1 min · 24 words · -

windows route, 路由表

windows route, 路由表 打印路由表 route print 显示以10.开始的路由 route print 10.* 1.具体功能 该命令用于在本地IP路由表中显示和修改条目。使用不带参数的ROUTE可以显示帮助。 2.语法详解 route [-f] [-p] [command [destination] [mask netmask] [gateway] [metric metric] [if interface] 3.参数说明 -f 清除所有不是主路由(子网掩码为255.255.255.255的路由)、环回网络路由(目标为127.0.0.0,子网掩码为 255.255.255.0的路由)或多播路由(目标为224.0.0.0,子网掩码为240.0.0.0的路由)的条目的路由表。如果它与命令之一(例如Add、Change或Delete)结合使用,表会在运行命令之前清除。 -p 与Add命令共同使用时,指定路由被添加到注册表并在启动TCP/IP协议的时候初始化IP路由表。默认情况下,启动TCP/IP协议时不会保存添加的路由,与Print命令一起使用时,则显示永久路由列表。所有其他的命令都忽略此参数。永久路由存储在注册表中的位置是 HKEY_LOCAL_MACHSYSTEMCurrentControlSetServicesTcpipParametersPersistentRoutes。 command 指定要运行的命令。下表列出了有效的命令。 destination 指定路由的网络目标地址。目标地址可以是一个IP网络地址(其中网络地址的主机地址位设置为0),对于主机路由是IP地址,对于默认路由是0.0.0.0。mask subnetmask 指定与网络目标地址相关联的网掩码(又称子网掩码)。子网掩码对于IP网络地址可以是一适当的子网掩码,对于主机路由是255.255.255.255 ,对于默认路由是0.0.0.0。如果忽略,则使用子网掩码255.255.255.255。定义路由时由于目标地址和子网掩码之间的关系,目标地址不能比它对应的子网掩码更为详细。换句话说,如果子网掩码的一位是0,则目标地址中的对应位就不能设置为1。 gateway 指定超过由网络目标和子网掩码定义的可达到的地址集的前一个或下一个跃点IP地址。对于本地连接的子网路由,网关地址是分配给连子网接口的IP地址。对于要经过一个或多个路由器才可用到的远程路由,网关地址是一个分配给相邻路由器的、可直接达到的IP地址。 metric metric 为路由指定所需跃点数的整数值(范围是1~9999),它用来在路由表里的多个路由中选择与转发包中的目标地址最为匹配的路由。所选的路由具有最少的跃点数。跃点数能够反映跃点的数量、路径的速度、路径可靠性、路径吞吐量以及管理属性。 if interface 指定目标可以到达的接口的接口索引。使用Route print命令可以显示接口及其对应接口索引的列表。对于接口索引可以使用十进制或十六进制的值。对于十六进制值,要在十六进制数的前面加上0x。忽略if参数时,接口由网关地址确定。 注意: 路由表中跃点数一列的值较大是由于允许TCP/IP根据每个LAN接口的IP地址、子网掩码和默认网关的配置自动确定路由表中路由的跃点数造成的。默认启动的自动确定接口跃点数确定了每个接口的速度,调整了每个接口的路由跃点数,因此最快接口所创建的路由具有最低的跃点数。要删除大跃点数,请在每个 LAN连接的TCP/IP协议的高级属性中禁用自动确定接口跃点数。 如果在systemrootSystem32DriversEtc文件夹的本地网络文件中存在适当的条目,名称可以用于Destination。只要名称可以通过"域名系统"(DNS)查询这样的标准主机名解析技术分解为IP地址,就可以将其用于Gateway,DNS查询使用存储在 systemrootSystem32DriversEtc 文件夹下的本地主机文件和NetBIOS 名称解析。 如果是Print或Delete命令,可以忽略Gateway参数,使用通配符来表示目标和网关。Destination的值可以是由星号()指定的通配符。如果指定目标含有一个星号()或问号(?),它被看作是通配符,只打印或删除匹配的目标路由。星号代表任意一字符序列,问号代表任一字符。例如, 10..1、192.168.、127._和_224_都是星号通配符的有效使用。 使用了无效的目标和子网掩码(网掩码)值的组合,会显示"Route bad gateway address netmask"错误消息。目标中有一位或多位设置为1,而其在子网掩码中的对应位设置为0时会发生这个错误。可以通过二进制表示法表示目标和子网掩码来检查这种情况。以二进制表示的子网掩码包括表示目标网络地址部分的一连串的1和表示目标主机地址部分的一连串的0两个部分。查看目标以确定目标的主机地址部分(由子网掩码所定义) 是否有些位设置成了1。 Windows 98 的Route命令不支持-p参数。 只有当TCP/IP协议在网络连接中安装为网络适配器属性的组件时,该命令才可用。 例子3: 要添加默认网关地址为192.168.12.1的默认路由,执行以下命令: ...

2014-12-25 · 2 min · 313 words · -

Mac OS X 中设置 VPN 静态路由

Mac OS X 中设置 VPN 静态路由, macos route sudo route -n add -net 192.168.5.4 -netmask 255.255.255.0 xxx.xxx.200.1 https://blog.hackroad.com/apple/mac-os/7011.html mac osx Lerpard 中, 使用内置的pptp client端拨号成功后, 所有的网络连接均走vpn路线, 这样校内的网站也走这个了, 导致速度缓慢, 校内连接终端等 解决方法是: 手动设置路由表, 以我的实际情况为例: 在windows下,我需要设置如下3条静态路由(首条0.0.0.0为default) route -p add 0.0.0.0 mask 0.0.0.0 10.13.31.1 (我的校园网网关是这个) route -p add 10.0.0.0 mask 255.0.0.0 10.13.31.1 route -p add 210.32.0.0 mask 255.255.240.0 10.13.31.1 route -p add 222.205.0.0 mask 255.255.128.0 10.13.31.1 在Mac OSX 中, 设置路由的命令稍有不同, 为: route -n add defalut 10.13.31.1 route -n add -net 10.0.0.0/8 10.13.31.1 route -n add -net 210.32.0.0/20 10.13.31.1 route -n add -net 222.205.0.0/17 10.13.31.1 ...

2014-12-25 · 2 min · 244 words · -

BDEV, CDEV

字符设备 提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。相反,此类设备支持按字节/字符来读写数据。举例来说,键盘、串口、调制解调器都是典型的字符设备。 块设备, block device 块设备也就是存储以“块”为单位数据的设备,比较典型的如磁盘设备, 硬盘、软盘,光盘或者优盘/闪存。在 Linux 系统中,一切皆文件,磁盘设备也是文件 应用程序可以随机访问设备数据,程序可自行确定读取数据的位置。数据的读写只能以块(通常是512B)的倍数进行 与字符设备不同,块设备并不支持基于字符的寻址。 用 ls 查看磁盘分区文件 ls -l /dev/sd* # output ➜ ~ ls -l /dev/sd* brw-rw---- 1 root disk 8, 0 Apr 1 07:15 /dev/sda brw-rw---- 1 root disk 8, 1 Apr 1 07:15 /dev/sda1 brw-rw---- 1 root disk 8, 2 Apr 1 07:15 /dev/sda2 brw-rw---- 1 root disk 8, 3 Apr 1 07:15 /dev/sda3 字符设备与块设备的区别 这两种类型的设备的根本区别在于它们是否可以被随机访问——换句话说就是,能否在访问设备时随意地从一个位置跳转到另一个位置。举个例子,键盘这种设备提供的就是一个数据流,当你敲入"fox" 这个字符串时,键盘驱动程序会按照和输入完全相同的顺序返回这个由三个字符组成的数据流。如果让键盘驱动程序打乱顺序来读字符串,或读取其他字符,都是没有意义的。所以键盘就是一种典型的字符设备,它提供的就是用户从键盘输入的字符流。对键盘进行读操作会得到一个字符流,首先是"f",然后是"o",最后是"x",最终是文件的结束(EOF)。当没人敲键盘时,字符流就是空的。硬盘设备的情况就不大一样了。硬盘设备的驱动可能要求读取磁盘上任意块的内容,然后又转去读取别的块的内容,而被读取的块在磁盘上位置不一定要连续,所以说硬盘可以被随机访问,而不是以流的方式被访问,显然它是一个块设备。 内核管理块设备要比管理字符设备细致得多,需要考虑的问题和完成的工作相比字符设备来说要复杂许多。这是因为字符设备仅仅需要控制一个位置—当前位置—而块设备访问的位置必须能够在介质的不同区间前后移动。所以事实上内核不必提供一个专门的子系统来管理字符设备,但是对块设备的管理却必须要有一个专门的提供服务的子系统。不仅仅是因为块设备的复杂性远远高于字符设备,更重要的原因是块设备对执行性能的要求很高;对硬盘每多一分利用都会对整个系统的性能带来提升,其效果要远远比键盘吞吐速度成倍的提高大得多。另外,我们将会看到,块设备的复杂性会为这种优化留下很大的施展空间。 字符设备与块设备的区分 每一个字符设备或者块设备都在/dev目录下对应一个设备文件。读者可以通过查看/dev目录下的文件的属性,来区分设备是字符设备还是块设备。使用cd命令进入/dev目录,并执行ls -l命令就可以看到设备的属性 [root@tom /]# cd /dev /进入/dev目录/ [root@tom dev]# ls -l /列出/dev中文件的信息/、 /*第1字段 2 3 4 5 6 7 8 */ crw-rw—-+ 1 root root 14, 12 12-21 22:56 adsp crw——- 1 root root 10, 175 12-21 22:56 agpgart crw-rw—-+ 1 root root 14, 4 12-21 22:56 audio brw-r—– 1 root disk 253, 0 12-21 22:56 dm-0 brw-r—– 1 root disk 253, 1 12-21 22:56 dm-1 crw-rw—- 1 root root 14, 9 12-21 22:56 dmmidi ...

2014-12-24 · 2 min · 225 words · -