Node.JS 究竟是什么?

Node旨在解决服务器能够处理的并发连接的最大数量的问题。

Node官网首页有一句话就是对Node是什么以及node解决什么问题做出了介绍,原文如下

Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, 
scalable network applications. Node.js uses an event-driven, 
non-blocking I/O model that makes it lightweight and efficient,
perfect for data-intensive real-time applications that run across distributed devices.

大概意思是说Node是基于Chrome的javascript的引擎,旨在提供一种简单的构建可伸缩网络程序的方法,node特点是基于事件驱动,非阻塞I/O,同时还有一个特点没有直接提到就是单线程。

在 Java™ 和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 的配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户群的增长,如果希望您的 Web 应用程序支持更多用户,那么,您必须添加更多服务器。当然,这会增加服务器成本、流量成本和人工成本等成本。除这些成本上升外,还有一个潜在技术问题,即用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。鉴于上述所有原因,整个 Web 应用
Node 解决这个问题的方法是:更改连接到服务器的方式。每个连接发射一个在 Node 引擎的进程中运行的事件,而不是为每个连接生成一个新的 OS 线程(并为其分配一些配套内存)。Node 声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞 I/O 调用。Node 还宣称,运行它的服务器能支持数万个并发连接。

为什么选择是Javascript 语言

  • V8 JavaScript 引擎是 Google 用于其 Chrome 浏览器的底层 JavaScript 引擎。很少有人考虑 JavaScript 在客户机上实际做了些什么?实际上,JavaScript 引擎负责解释并执行代码。Google 使用 V8 创建了一个用 C++ 编写的超快解释器,该解释器拥有另一个独特特征;可以下载该引擎并将其嵌入任何 应用程序。
  • JavaScript 是一种很棒的事件驱动编程语言,因为它允许使用匿名函数和闭包,更重要的是,任何写过代码的人都熟悉它的语法。事件发生时调用的回调函数可以在捕获事件处进行编写。这样可以使代码容易编写和维护,没有复杂的面向对象框架,没有接口,没有过度设计的可能性。只需监听事件,编写一个回调函数,其他事情都可以交给系统处理!
    由于V8正好可以满足上述提到Node几个特点,以及Javascript独特优势,以及Javascript的大量用户,所以NodeJS就这样地产生了。

Node适合做什么工作。实时 高并发I/O,弱密集逻辑计算

  • RESTful API
  • 新浪微博、twiter这样高并发的应用
  • 编写网络小工具。
  • 聊天程序
  • 游戏后台
  • 股票等实时信息展示网站。

同时Node有数万的计的第三方模块,Node 的一个特性是 Node Package Module,这是一个内置功能,用于安装和管理 Node 模块。它自动处理依赖项,因此您可以确定:您想要安装的任何模块都将正确安装并包含必要的依赖项。它还支持将您自己的模块发布到 Node 社区,假如您选择加入社区并编写自己的模块的话。您可以将 NPM 视为一种允许轻松扩展 Node 功能的方法,不必担心这会破坏您的 Node 安装。同样,如果您选择深入学习 Node,那么 NPM 将是您的 Node 解决方案的一个重要组成部分。

优秀的设计+众多开发者的支持,应该是Node平台火起来的原因吧。

如何设计优秀的API

谷歌架构师Joshua Bloch最近分享了一份幻灯片,系统的讨论了优秀API的设计原则。他指出:每个API接口应该只专注一件事,并做好:如果它很难命名,那么这或许是个不好的征兆,好的名称可以驱动开发、并且只需拆分与合并模块即可。设计原则包括:

  • API应尽可能地简洁:满足需求、对有疑问的地方可以暂时不使用(函数、类、方法、参数等,你可以不添加,但千万不要删除)、概念性的东西比体积重要);
  • 实现不要影响API:关注实现细节(不要迷惑用户、不要随便改变实现方式)、意识到具体的实现细节(不要有越权的方法行为,例如不所有的调优参数都是可疑的);
  • 不要让实现细节“泄露”到API(例如on-disk和on-the-wire格式等异常情况);
  • 最小化可访问:设计人员应尽量把类及成员设为私有,公共类不应该有公共字段(包括异常实例),最大限度地提高信息隐藏,允许模块可以被使用、理解、构建、测试和独立调试;
  • 命名问题:应该见名知意,避免含糊的缩写、对同一样东西的命名应该有个一致性的前缀(遍及整个平台API)、讲究对称、代码应该易读。

CSS 定位之BFC

在 CSS 面试中问 BFC 等概念,就如在 JS 面试中问闭包等概念一样,经常会刷掉一些真正优秀的人。 ——玉伯

第一次接触BFC是在清除浮动的时候,清除浮动主要有两种法

它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。

  • 利用 clear属性,清除浮动
  • 使父容器形成BFC
    于是当时查询了好多资料总结如下:
    但在进一步说明 BFC 特性之前,首先要介绍另一个在 CSS 的可视化格式模型 (Visual Formatting Model) 中具有非常重要地位的概念——定位方案。定位方案是控制元素的布局,在 CSS 2.1 中,有三种定位方案——普通流 (Normal Flow) 、浮动 (Floats) 和绝对定位 (Absolute Positioning) ,下面分别对这三种布局简略说明一下。

####普通流(Normal Flow)

在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行, 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

浮动 (Floats)

在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

####绝对定位 (Absolute Positioning)

在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响(如果看了上文的童鞋,会发现这点与浮动元素会影响兄弟元素是不同的),而元素具体的位置由绝对定位的坐标决定。

BFC 正是属于普通流的,因此它对兄弟元素也不会造成什么影响。

####BFC的定义
在进行盒子元素布局的时候, BFC 提供了一个环境, 在这个环境中按照一定规则进
行布局不会影响到其它环境中的布局。比如浮动元素会形成 BFC,浮动元素内部子元素
的主要受该浮动元素影响,两个浮动元素之间是互不影响的。
也就是说,如果一个元素符合了成为 BFC 的条件,该元素内部元素的布局和定位
就和外部元素互不影响(除非内部的盒子建立了新的 BFC), 是一个隔离了的独立容器。
在 CSS3 中,BFC 叫做 Flow Root。

####BFC到底是什么?
当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思。

####怎样才能形成BFC

  • float的值不为none。
  • overflow的值不为visible。
  • display的值为table-cell, table-caption, inline-block中的任何一个。
  • position的值不为relative和static。
  • css3中flex boxes

####BFC的作用

  1. 包含浮动元素(清除浮动)
    BFC 会 根据子元素的情况自 适应 高度 ,这个 特性 是 对父元素 使 用
    overflow:hidden/auto/scroll、 float:left/right 样式可以闭合浮动的
  2. 不被浮动元素覆盖
    浮动元素会无视兄弟元素的存在, 覆盖在兄弟元素的上面, 为该兄弟元素创建
    BFC 后可以阻止这种情况的出现

BFC 主要有三个特性:

(1) BFC 会阻止外边距折叠
两个相连的 div 在垂直上的外边距会发生叠加,在实际开发中,或许我们有时会不需要这种折叠,这时可以利用 BFC 的其中一个特性——阻止外边距叠加。阻止父子元素的 margin 折叠,仅当两个块级元素毗邻并且在同一个块级格式化上下文时,它们垂直方向之间的外边距才会叠加。也就
是说,即便两个块级元素相邻,但当它们不在同一个块级格式化上下文时它们的边
距也不会折叠。同时BFC 的元素,不和它的子元素发生外边距折叠。

(2) BFC 可以包含浮动的元素
这也正是上面使用 overflow: hidden 与 overflow: auto 方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动元素父元素的 BFC 特性,从而可以包含浮动元素,闭合浮动。

W3C 的原文是“’Auto’ heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素。

但是 IE6-7 并不支持 W3C 的 BFC ,而是使用自产的 hasLayout 。从表现上来说,它跟 BFC 很相似,只是 hasLayout 自身存在很多问题,导致了 IE6-7 中一系列的 bug 。触发 hasLayout 的条件与触发 BFC 有些相似,具体情况 Kayo 会另写文章介绍。这里 Kayo 推荐为元素设置 IE 特有的 CSS 属性 zoom: 1 触发 hasLayout ,zoom 用于设置或检索元素的缩放比例,值为“1”即使用元素的实际尺寸,使用 zoom: 1 既可以触发 hasLayout 又不会对元素造成其他影响,相对来说会更为方便。

(3) BFC 可以阻止元素被浮动元素覆盖
如上面所说,浮动元素的块状兄弟元素会无视浮动元素的位置,尽量占满一整行,这样就会被浮动元素覆盖,为该兄弟元素触发 BFC 后可以阻止这种情况的发生。

一个成功的 Git 分支模型

一个成功的git分支模型

javascript replace

简单介绍

StringObject.replace(searchValue,replaceValue)
StringObject:字符串
searchValue:字符串或正则表达式
replaceValue:字符串或者函数

###字符串替换字符串
'I am loser!'.replace('loser','hero')//I am hero!

直接使用字符串能让自己从loser变成hero,但是如果有2个loser就不能一起变成hero了。

'I am loser,You are loser'.replace('loser','hero');//I am hero,You are loser

正则表达式替换为字符串、并将正则的global属性改为true则可以让所有loser都变为hero

'I am loser,You are loser'.replace(/loser/g,'hero')//I am hero,You are hero

###有趣的替换字符

####使用$&字符给匹配字符加大括号
var sStr=’讨论一下正则表达式中的replace的用法’;
sStr.replace(/正则表达式/,’{$&}’);//讨论一下{正则表达式}中的replace的用法

####使用$和$'字符替换内容,$位于匹配子串左侧的所有文本。$’位于匹配子串右侧的所有文本。
‘abc’.replace(/b/,”$`”);//aac
‘abc’.replace(/b/,”$’”);//acc

####使用分组匹配组合新的字符串
‘nimojs@126.com’.replace(/(.+)(@)(.*)/,”$2$1”)//@nimojs

####replaceValue参数可以是一个函数
StringObject.replace(searchValue,replaceValue)中的replaceValue可以是一个函数.如果replaceValue是一个函数的话那么,这个函数的arguments会有n+3个参数(n为正则匹配到的次数)

function logArguments(){    
console.log(arguments);//["nimojs@126.com", "nimojs", "@", "126.com", 0, "nimojs@126.com"] 
    return '返回值会替换掉匹配到的目标'
}
console.log(
'nimojs@126.com'.replace(/(.+)(@)(.*)/,logArguments)
)

参数分别为

  1. 匹配到的字符串(此例为nimojs@126.com,推荐修改上面代码的正则来查看匹配到的字符帮助理解)
  2. 如果正则使用了分组匹配就为多个否则无此参数。(此例的参数就分别为”nimojs”, “@”, “126.com”。推荐修改正则为/nimo/查看控制台中返回的arguments值)
  3. 匹配字符串的对应索引位置(此例为0)
  4. 原始字符串

Python 学习笔记(1)

去年买了本Python基础教程,看了一个月,感觉Python 入门也挺easy的,也写了一些简单的代码,最近又买了本《Python入门教程》,感觉这个书不应该买的,就是太基础,书看完了,,将Python一些最基本的东西总结一下吧。将重点内容概括一下 作为读书笔记,好记性不如烂笔头啊。

字符串

字符串有三种方式

1. 单引号
2. 双引号
3. 三引号

通过+ 完成字符串拼接
len (s) 求字符串的长度
3*”hello”复制三次字符串。

列出模块中的所有函数 dir(math)
打印文档字符串 print(math.cos.doc)

类型转换

int("3")
str(3)
float('3.0')
float(3)

变量的引用赋值:让变量指向表达式的值 比如 x=2;x指向2,y=x;y也指向,改变y的值对x无影响,只是改变了y的指向而已

多种赋值

x,y,z=1,2,3  相当于x=1,y=2,z=3;

从 键盘读取字符串 name=input();只能获取到字符串 ,如果要读取整数的话,需要类型转换,int(a)

将字符串 首字母大写
‘du bao kun’.capitalize(); //Du bao kun
去除收尾的空格
‘ du bao kun ‘.strip();// du bao kun

print 在字符串 可以传入多个参数,以分隔符来输出,可以设置sep来自定义分割符号,比如 print(‘du’,’bao’,’kun’,sep=’.’)#du.bao.kun

ord 获取字符编码 比如 ord(‘a’)#65
chr获取对应的字符 chr(97)#’a’

转义字符 \单斜杠,\’单引号 、\”双引号、\n 回车,\r,换行\t 制表符

获取字符串的字符 通过 [index]
字符串切片 比如
food=’apple pie’;food[0:5] #apple

不包括索引5的字符,相当于food[:5],如果起始索引忽略的话则相当于0,如果最后一个索引忽略,相当于 为字符串长度。

负数索引, 比如 ‘food[-9,-4]’ #apple

字符串测试函数:’s.endwith’ ,’s.startwith’,’s.isalnum’只包含字字母或者数字isalpha
只包含字母,’isdecimal’只包含十进制的数字的字符
‘isdigital’只包含数字,’isidentifier’只包含合法字符,’islower’只包含小写字母,’isnumric’只包含数字,’istitle’大小写符合头衔要求
‘isupper’只包含大写字母、’t in s s’包含字符串t
cout(t) 字符串中t出现的次数

搜索函数:find(t) 如果没有找到子串t则返回-1、 rfind(t)、index(t)、rindex(t)没有找到会爆出异常

要范文索引为i的字符 ,通过 ‘s[i]’或者 ‘s[i:i+1]’

同时还有改变大小写、剥除函数、拆分函数,替换函数

format 函数 一下输出结果均为Jack like rose

print('{0} like {1} '.format('jack','rose'))
print('{first} like {second} '.format(second='rose',first='jack'))

eval可以解析 表达式的值 比如 ‘eval(‘5+3’)’结果为8
布尔逻辑 :’not and or ==、’
短路求值 如果 true or x ,则表达式x值不再计算。同理如果 false and x,x表达是也不进行计算。
流程控制 if /else,if/elif/else

if x:
    print('x')
else
    print('y')

条件表达式

reply=‘yuck’if food =='lamb' else 'yum'

相当于

if food =='lamb'
    reply='yuck'
else
    replay='yum'

循环
for i in range(10):
print (i)
while

i=0
while i<10:
    print(i)
    i=i+1

python 使用缩进来表示代码块,要在Python中 表示代码块,必须以同样程度缩进代码块的每一行,但Python 允许你编写包含任意数量语句的代码块,但注意冒号

函数定义

def say_hello():
    print ('hello')

默认值

def greet(name,greeting ='hello'):
    print(name+greeting)
greet('kunkun')
greet('kunkun','你好')

输出结果

kunkunhello
kunkun你好

关键字参数

greet(greeting='nihao',name='kunkun')

测试驱动开发:QUnit 介绍

在Javascript项目的开发流程中,测试驱动开发广为流传,测试驱动能够让我们节省编码的时间,本篇文章主要介绍Qunit,一个测试驱动的开发框架,来帮助我们发现程序的错误以及bug

为什么要使用测试驱动开发

首先在最初使用单元测试的时候,这可能是一个繁杂和琐碎的过程,包括单元测试环境的搭建,以及为每一个要测试的函数编写测试代码,都会花费很多的时间,但是要相信单元测试最终会帮主我们来减少在一个项目周期中用来调试代码的时间。同时也会减少半夜接到电话被拉过去修改bug的麻烦,长远来说,这个过程会让你受益更多比如 跨浏览器的测试,使用这种方式能够让你在不同的浏览器中进行测试。总之编码之前,测试先行一个比较好的习惯。

随着Github等类似的代码分享平台的出现,现在开源的东西也越来越多了,怎么才能证明这些东西的可用性呢,因为开源模块的作者会编写单元测试的代码。当我们clone完这个模块之后 然后跑一边单元测试代码,会让自己开源的模块增强可用性。同时我们在为开源项目贡献代码的时候也建议附上单元测试的程序,以增强自己的代码被接受的可能性。

用Unit test 来代替调试,同时也能有利于团队合作,当他人看你写的模块的时候,看一下写的单元测试代码就明白该模块的功能了。单元测试能让我们更快地了解每个关键函数的功能。

话说回来,当项目完成之后 又发现了bug,当我们在修改完一个bug之后,怎样才能说明bug修改好了呢,单元测试这个时候也可以为我们提供帮助,几行单元测试就能证明这个bug被修复了,无需多言。

为什么选择Qunit?

原因是这个框架很简单上手,也是单元测试新手的最佳选择,就像Jquery那么easy,对于初学者来说,Qunit跟jQuery是也是出自同一人之手。Qunit也是用来测试jQuery 本身的单元测试框架, Qunit对于jQuery开发者也是单元测试框架的最佳选择。当然还有更多javascript单元测试框架比如 mocha,jasmine,断言库chai,should.jsExpectbetter-assert

开始搭建环境

第一步就是先下载Qunit的Javascript 和CSS文件。地址如下

<link rel=“stylesheet" href="//code.jquery.com/qunit/qunit-1.14.0.css" type="text/css" media="screen">
<script src=“//code.jquery.com/qunit/qunit-1.14.0.js”></script>

新建三个文件test.html、Calculator.js,test.js 我们用来展示单元测试的结果。Calculator.js编写我们要实现功能的程序,出于演示目的这里编写一个计算器的程序.test.js编写单元测试的代码。test.html代码如下

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Unit Test</title>
    <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.14.0.css" type="text/css" media="screen">
    <script src="http://code.jquery.com/qunit/qunit-1.14.0.js"></script>
</head>
<body>
             <h1 id="qunit-header">QUnit Test Suite</h1>
                <h2 id="qunit-banner"></h2>
                <div id="qunit-testrunner-toolbar"></div>
                <h2 id="qunit-userAgent"></h2>
               <ol id="qunit-tests"></ol>


               <script type="text/javascript" src='./Calculator.js'></script>
               <script type="text/javascript" src='./test.js'></script>
</body>
</html>    

其中body里面几个html元素是为了展示测试结果使用的,测试代码执行的时候,Qunit会把测试结果放到这些元素中,结合内置一些CSS 让我们方便地了解哪些测试通过了,哪些没有通过。
Calculator.js主要包含两个简单的函数 multiply返回两个数的乘积,isOdd判断一个数是不是奇数。

function multiply(a,b) {
  return a*b;
}
function isOdd(n) {
   return Math.abs(n) % 2 == 1;
}

test.js就是我们要写的测试了。代码如下

test('isOdd()', function() {
    ok(isOdd(3), 'Three is an odd number');
    ok(isOdd(2), 'Two is not an odd number');
});

test('multiply()', function() {
    strictEqual(multiply(2,2), '4', '2 multiplied by 2 is 4');
    equal(multiply(2,3), 6, '3 multiplied by 2 is 6');
});

到此为止就可以运行了,结果是 2个通过,两个失败。

我们很容易的看出,测试就是调用了一个名字为test的函数,包含两个参数,第一个参数是对测试函数的描述,第二个参数是一个回调函数,里面的ok,strictEqual,equal 分别是对测试例子结果的断言,对于strictEqual,equal来说比如我要测试一个函数,第一个是被测试函数的调用的返回结果,第二个是期待的结果,第三个是对本次测试示例的描述,如果测试结果与自己想要的结果一致,则本次单元测试通过,否则 。。。。。对于ok断言主要是判断被测试的函数返回值是否为真。如果为真则通过。否则。。。。
值得要说一下的是,strictEqual 是判断严格相等相当于===比如4===4返回true,4==’4’则返回false,equal是只要可以转为相等的结果则通过相当于==,会对操作数进行类型转换 比如4==’4’ 返回true

除此之外还有其他的断言函数可用,这里就不介绍了。官网写的灰常清楚了

  • deepEqual() :深度相等判断,适用于原生类型,数组,对象 正则表达式,以及日期 函数类型
  • equal() :非严格相等,
  • notDeepEqual :与deepEqual功能相反
  • notPropEqual() 严格的比较对象属性,不相等则通过。
  • notStrictEqual() 严格的比较,不严格相等则返回通过
  • ok() 第一个参数为true 则通过测试。
  • propEqual() 使用=== 来比较对象内部的属性,与deepEqual() 不同的是propEqual()可以用来比较两个具有不同原型以及构造函数的对象。
  • strictEqual() 同时比较值和类型
  • throws() 要求抛出异常。

下载本篇博客的源码

sublime 输出对中文的支持

今天用sublime 写Python的Demo,当编辑代码完成之后按Ctrl +B,能完成Python的解释,并在控制台输出结果,但是如果输出内容中包含中文的话则会有错误发生,错误如下

[Decode error - output not utf-8]

大概猜出是编码的问题,于是百度了解决方案为,在Sublime插件包里修改 Python.sublime-build 这个文件在C:\Users\kunkun\AppData\Roaming\Sublime Text 2\Packages\Python下面.在最后一行里面添加·"encoding": "cp936",原来的文件为:

{
    "cmd": ["python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

修改后的文件

{
  "cmd": ["python", "-u", "$file"],
  "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
   "selector": "source.python",
   "encoding": "cp936"
}

改完之后则可以正常输出中文了。

如果nodejs在控制台输出中文乱码的问题

修改Nodejs.sublime-build文件中的encoding为utf-8