Nodejs (5) 异步编程

Submitted by Lizhe on Fri, 01/05/2018 - 14:53

服务端异步编程的核心思想在于: 事件发生会触发响应逻辑. 在Node的世界里流行两种响应逻辑管理方式: 

回调和事件监听

回调通常用来定义一次性响应的逻辑

事件监听器 本质上也是一个回调, 不同的是它跟一个事件相关联. 

var http = require('http');
http.createServer(
    function(req,res){
        res.writeHead(200,{'Content-type':'text/plain'});
        res.end('helloworld\n');
    }
).listen(3000);

回调是一个函数, 它被当做参数传给异步函数, 它描述了异步操作完成之后要做什么.

上面例子中的创建了一个HTTP服务器,并用回调定义响应逻辑

Nodejs (4) 异步I/O

Submitted by Lizhe on Thu, 01/04/2018 - 12:32

单线程同步编程模型会因阻塞I/O导致硬件资源得不到更优的使用

多线程编程模型也因为编程中的死锁, 状态同步等问题让开发人员头疼.

Node在两者之间给出了它的方案, 利用单线程, 远离多线程死锁, 状态同步等问题, 利用异步I/O, 让单线程远离阻塞, 以更好的使用CPU

异步I/O可以算做Node的特色 , 因为它是首个大规模将异步I/O应用在应用层上的平台, 它力求在单线程上将资源分配得更高效

 

为了弥补单线程无法利用多核CPU的缺点, Node提供了类似前端浏览器中Web Workers的子进程, 该子进程可以通过工作进程高效地利用CPU和I/O

 

Node 自身的执行模型为 事件循环, 正是它使得回调函数十分普遍

在进程启动时, Node便会创建一个类似于while(true)的循环, 每执行一次循环体的过程我们称为Tick. 每个Tick的过程就是查看是否有事件需要处理, 如果有, 就取出事件及其及相关的回调函数. 如果存在相关的回调函数, 就执行它们, 然后进入下一次循环, 如果不再有事件处理, 就退出进程.

 

观察者

Nodejs (3) NPM与包

Submitted by Lizhe on Wed, 01/03/2018 - 15:39

包和NPM是将模块联系起来的一种机制

包 由 包结构 和 包描述文件 组成

package.json 包描述文件
bin 用于存放可执行二进制文件的目录
lib 用于存放JavaScript代码的目录
doc 用于存放文档的目录
test 用于存放单元测试文档

 

包描述文件是一个JSON格式的文件 package.json , 位于包的根目录下, 是包的重要组成部分

包规范定义可以帮助Node解决依赖包安装的问题, NPM 正是基于该规范进行了实现

centos yum npm 安装

Submitted by Lizhe on Fri, 12/29/2017 - 16:57

[root@vm2 ~]# sudo curl -sL -o /etc/yum.repos.d/khara-nodejs.repo https://copr.fedoraproject.org/coprs/khara/nodejs/repo/epel-7/khara-nodejs-epel-7.repo
[root@vm2 ~]# sudo yum install -y nodejs nodejs-npm

Lucene (6) Query子类

Submitted by Lizhe on Thu, 12/28/2017 - 15:56

1. TermQuery

对索引中特定项进行搜索, Term是最小的索引片段, 每个Term包含了一个域名和一个文本值.

Term t = new Term("title", "java");

Query q = new TermQuery(t);

使用这个TermQuery对象进行搜索, 可以返回在title域包含单词java的所有文档

注意域值是区分大小写的

2. TermRangeQuery

索引中的各个Term对象会按照字典编排顺序(通过String.compareTo方法)

搜索时包含或不包含起始项和终止项, 如果这个项为空, 那么它对应的端就是无边界的

Query q = new TermRangeQuery("title", new BytesRef("a"), new BytesRef("z"), true, true);

末尾的两个布尔型参数表示 

Lucene (4) 搜索

Submitted by Lizhe on Tue, 12/26/2017 - 11:22

当你查询Lucene索引时, 它将会返回一个包含有序的ScoreDoc对象数组的TopDocs对象.

在输入查询后, Lucene会为每个文档计算评分(用以表示相关性的数值)

IndexSearcher 所有搜索都通过IndexSearcher进行, 它们会调用该类中重载的search方法
Query 封装某种查询类型的具体子类. Query实例将被传递给IndexSearcher的search方法
QueryParser 将用户输入的查询表达式处理成具体的Query对象
TopDocs 保持由IndexSearcher.search()方法返回的具有较高评分的顶部文档
ScoreDoc 提供对TopDocs中没跳搜索结果的访问接口

 

Lucene (3) 并发,线程安全和锁

Submitted by Lizhe on Fri, 12/22/2017 - 15:10

 

任意数量的只读属性的IndexReader类都可以同时打开同一个索引.

无论这些Reader是否属于同一个JVM, 以及是否属于同一台计算机都无关紧要.

但需要记住, 在单个JVM内, 利用资源和发挥效率的最好办法是用线程共享单个的IndexReader实例

 

对于一个索引来说, 一次只能打开一个Writer. Lucene采用文件锁来提供保障. 一旦建立起IndexWriter对象, 系统会立刻分配一个锁给它.

该锁只有当IndexWriter对象被关闭时才会释放.

注意如果你使用IndexReader对象来改变索引的话, 比如修改norms或者删除文档, 这时IndexReader对象会作为Writer使用, 它必须在修改上述内容之前成功地获取Write锁, 并在被关闭时释放该锁  

 

当IndexWriter对象已经打开一个索引时, 你可以同时直接使用IndexReader打开同一个索引.

每个IndexReader对象会得到一个对应时间点的索引"快照", IndexReader只有在IndexWriter提交修改 或者 IndexReader自己被重新打开后才能获知索引的修改情况