<<精通javascript开发>> 简单笔记

性能

  • 事件冒泡 -> 父级元素处理子元素的事件

  • cpu密集 -> web worker OR 事件委托 事件委托 -> 定时执行处理函数

  • DOM变动 -> 使用父级元素替代多个子元素的操作

  • GZIP -> 传输时压缩,抵达浏览器解压缩

  • 避免js 对样式的直接改动 -> 使用css

  • 减少js 对DOM的append -> 最后才append

  • js代码需要时才加载- > requirejs...

  • 代码的混淆编译… -> webpack...

代码规范

  • 私有变量 -> 私有的,外部不可访问的变量和函数用 "_"

  • Getter 和 Setter -> 提供对变量的操作的接口

  • 继承 -> 提供create接口 和 options 参数对class 的初始化

  • es5的新特性 -> forEach Object.defineProperty ...

<<基于Python的Web应用开发实战>> 简单笔记

1. Restfull

  • 资源: 资源是 REST 架构方式的核心概念。 每个资源都要使用唯一的 URL 表示。 某一类资源的集合也要有一个 URL。 API 还可以为某一类资源的逻辑子集定义集合 URL。 表示资源集合的 URL 习惯 在末端加上一个斜线,代表一种“文件夹”结构。

  • 资源转换Json

client -> server: from_json server-> client: to_json

  • 认证 REST Web 服务的特征之一是无状态,即服务器在两次请求之间不能“记 住”客户端的任何信息。客户端必须在发出的请求中包含所有必要信息,因此所有请求都 必须包含用户密令。

POST - PUT - DELETE —request with Token

2. 测试

  • Httpie 测试
  • client 测试
  • 端到端测试

3. 性能

  • 慢查询
  • 高CPU运算

4. 蓝本:blueprint

蓝本和程序类似,也可以定义路由。 不同的 是,在蓝本中定义的路由处于休眠状态,直到蓝本注册到程序上后,路由才真正成为程序 的一部分。

JavaScript内存优化

寒假系统学习javascript的时候,写了一些简单的练习代码,先来看下面一段:

//闭包
var global_ten=10;
var sum;

function papa() {
var hundred_more=100;
sum=function(a,b){
return a+b+global_ten+hundred_more;
};
hundred_more=10000;
}

papa();//changed the hundred_more
console.log(sum(9,11));//hundred_more has changed

//访问保留环境中存在的i
var fns=[];
function definer(){
for(var i=0;i<5;i++){
fns.push(function(){
return i;
});
}
}
definer();
for (var i = 0; i < fns.length; i++) {
console.log(fns[i]());
};
//引入另一个作用域对象local_i
//() 立即函数 立即执行
var fns_ano=[]
function definer_ano(){
for(var i=0;i<5;i++){
fns_ano.push(function(local_i){
return function(){
return local_i;
}
}(i));
}
}
definer_ano();
for (var i = 0; i < fns_ano.length; i++) {
console.log(fns_ano[i]());
};

闭包是JavaScript 的高级特性,我们可以借助它来实现更多更复杂的效果来满足不同的需求。但是要注意的是因为把带有​​内部变量引用的函数带出了函数外部,所以该作用域内的变量在函数执行完毕后的并不一定会被销毁,直到内部变量的引用被全部解除。所以闭包的应用很容易造成内存无法释放的情况。

还有以下几个概念:

作用域

域(scope)是JavaScript 编程中一个非常重要的运行机制,在同步JavaScript 编程中它并不能充分引起初学者的注意,但在异步编程中,良好的作用域控制技能成为了JavaScript 开发者的必备技能。另外,作用域在JavaScript 内存管理中起着至关重要的作用。

作用域链

由于JavaScript 中,变量标识符的查找是从当前作用域开始向外查找,直到全局作用域为止。所以JavaScript 代码中对变量的访问只能向外进行,而不能逆而行之。

以上应有图,但是搜了一下网上资源也很多,在此不赘述 推荐:JavaScript内存优化

ps:关于系统学习javascript语言之建议--《javascript for php developers》。注: 以上内容《深入浅出node.js》也有详解。

《深入浅出node.js》一:异步I/O

近期从图书馆借来《深入浅出node.js》一书,拜读ing,今天晚上阅读了“异步I/O”一章。简要梳理一下:

I/O的阻塞与非阻塞

阻塞I/O完成整个获取数据的过程,而非阻塞I/O则不带数据直接返回,要获取数据,还需要通过文件描述符再次读取。

I/O的同步与异步

I/O的同步与异步出现在应用程序中。如果做阻塞I/O调用,应用程序等待调用的完成的过程就是一种同步状况。相反,I/O为非阻塞模式时,应用程序则是异步的。

异步I/O与轮询技术

当进行非阻塞I/O调用时,要读到完整的数据,应用程序需要进行多次轮询,才能确保读取数据完成,以进行下一步的操作。 轮询技术的缺点在于应用程序要主动调用,会造成占用较多CPU时间片,性能较为低下。现存的轮询技术有以下这些:

  • read:通过重复调用来检查I/O状态,是最原始性能最低的一种方式
  • select:对read的改进,通过对文件描述符上的事件状态来进行判断。缺点是文件描述符最大的数量有限制
  • poll:对select的改进,采用链表的方式避免最大数量限制,但描述符较多时,性能还是十分低下
  • epoll:进入轮询时若没有检查到I/O事件,将会进行休眠,直到事件发生将其唤醒。这是当前Linux下效率最高的I/O事件通知机制

注:select 和epoll机制,在《tcp/ip网络编程》相关文章中已经介绍。

轮询满足了非阻塞I/O确保获取完整数据的需求,但对于应用程序而言,它仍然只能算作一种同步,因为依然需要等待I/O完全返回。等待期间,CPU要么用于遍历文件描述符的状态,要么用于休眠等待事件发生。

理想的异步I/O模型

理想的异步I/O应该是应用程序发起异步调用,而不需要进行轮询,进而处理下一个任务,只需在I/O完成后通过信号或是回调将数据传递给应用程序即可。

Node的异步I/O

事件循环

Node的执行模型实际上是事件循环。在进程启动时,Node会创建一个无限循环,每一次执行循环体的过程成为一次Tick。每个Tick过程就是查看是否有事件等待处理,如果有则取出事件及其相关的回调函数,若存在关联的回调函数则执行它们,然后进入下一个循环。如果不再有事件处理,就退出进程。

事件循环是一个典型的生产者/消费者模型。异步I/O、网络请求等则是事件的生产者,源源不断为Node提供不同类型的事件,这些事件被传递到对应的观察者那里,事件循环则从观察者那里取出事件并处理。

观察者

每个事件循环中有若干个观察者,通过向这些观察者询问来判断是否有事件要处理。事件循环是一个典型的生产者/消费者模型。在Node中,事件主要来源于网络请求、文件I/O等,这些事件有对应的网络I/O观察者、文件I/O观察者等,事件循环则从观察者那里取出事件并处理。

请求对象

从Javascript发起调用到内核执行完I/O操作的过渡过程中,存在一种中间产物,叫做请求对象。以最简单的Windows下fs.open()方法(根据指定路径和参数去打开一个文件并得到一个文件描述符)为例,从JS调用到内建模块通过libuv进行系统调用,实际上是调用了uv_fs_open()方法。在调用过程中,创建了一个FSReqWrap请求对象,从JS层传入的参数和方法都封装在这个请求对象中,其中我们最为关注的回调函数被设置在这个对象的oncompete_sym属性上。对象包装完毕后,将FSReqWrap对象推入线程池中等待执行。 至此,JS调用立即返回,JS线程可以继续执行后续操作。当前的I/O操作在线程池中等待执行,这就完成了异步调用的第一阶段。

执行回调

回调通知是异步I/O的第二阶段。线程池中的I/O操作调用完毕后,会将获取的结果储存起来,然后通知IOCP当前对象操作已完成,并将线程归还线程池。在每次Tick的执行中,事件循环的I/O观察者会调用相关的方法检查线程池中是否有执行完的请求,如果存在,会将请求对象加入到I/O观察者的队列中,然后将其当做事件处理。

在最后需要指出: Node通过事件驱动方式处理请求,可以省掉创建和销毁线程的开销,同时操作系统在调度任务时因为线程较少,上下文切换的代价也很低。即使在大量连接的情况下,Node也能有条不紊地处理请求。