验证用户密码这件事
30 Apr 2015本篇经与 @Gnnng, @pollow 讨论、查资料,在 MSTC 群中请教讨论总结而成。
写出可用的 CSS 并不难,但是写出可维护的 CSS 一直是我在考虑的一个问题。如何让一个团队写出来的 CSS 像是同一个人写出来的,在这点上,Google CSS style guide 规定得太少。而 CSS 模式可以解决这种问题,本文就是我在学习 SMACSS( Scalable and Modular Architecture for CSS ) 时候的笔记。
前段时间看到 Scott H Young 那篇介绍费曼技巧1的文章,一下想到了程序员界流传甚广的小黄鸭调试法(Rubber Duck Debugging)2。几天前晚上散步的时候,聊天儿时提起了罗素悖论,让我联想到图灵对停机问题精妙的解法。想拿这个试试费曼技巧,讲到一半发现卡壳了,自己把自己绕了进去。我想到刘未鹏说过的那种状态,学习一个算法,初看觉得太牛逼了,然后花十分钟理解了人家花了十年才想出的成果,再花十天完全忘记,只能想起那个算法十分精妙,该不会的还是不会。所以应该由本溯源地学习数学和算法,并且写一个博客记录下学习的过程。于是这篇就作为费曼技巧和写作学习实践的第一篇。
在计算机科学领域,最广为人知的问题是关于 P 与 NP 问题的讨论,但不论 P 还是 NP,它们只是对解决问题效率的讨论。其实还有一类问题,它们难到计算机永远无法解出,这类问题被称作不可判定问题(Undecidable Problem)3,其中一个可能是最有名的问题就是停机问题。
停机问题提出了这样的疑问:是否存在一个程序,可以判定任何一个程序是否会停止。
要解决这个问题,我们先假设存在一个程序满足上述条件,比如:
int yourBrilliantProgram(char * program, inputType input){
if (program(input) stops)
return 1;
else //It loops forever
return 0;
}
其中,第一个 if
语句中的判断是人类智慧的结晶,它用了神奇的方法得知了 program(input)
是否停止。
接着我们就要进行破坏了,再来考虑这样一个程序:
int myDisgustingProgram(char * program){
if (yourBrilliantProgram(program, program)){
while(1);
return 0; //Never reaches here
}
else
return 1;
}
我的程序专门跟你作对,如果你说这个程序可以正常退出,那么我就作一个死循环;你说它是死循环的,我就正常退出给你返回一个true
。
So far so good. 最精彩的地方来了,考虑 yourBrilliantProgram(myDisgustingProgram, myDisgustingProgram)
的返回值。这里有点绕,我们一步一步跟踪。
首先,进入 yourBrilliantProgram
的第一个判断语句,这里执行 myDisgustingProgram(myDisgustingProgram)
,进入 if(yourBrilliantProgram(myDisgustingProgram, myDisgustingProgram))
这一句。这里可能出现两个结果:
1
,说明 myDisgustingProgram(myDisgustingProgram)
正常退出,那么当前程序进入死循环,此时上一层的 yourBrilliantProgram()
应该检测到这个死循环,并返回 0
,说明 myDisgustingProgram(myDisgustingProgram)
是个死循环。矛盾。0
,说明 myDisgustingProgram(myDisgustingProgram)
死循环,那么当前程序返回 1
并且正常退出,又证明 myDisgustingProgram(myDisgustingProgram)
不是死循环。矛盾。也就证明,根本不存在这样的程序可以判定任何一个程序是否停止。
##简介
Middleware
)的栈。filter
和provider
:
filter
是对请求的处理,并不对请求作出回应。provider
负责对请求进行回应。##使用方法
在终端中切换至工作目录下,安装 Connect:
npm install connect
调用 Connect:
var connect = require("connect");
此时变量 connect 是一个 function ,返回值是一个新的 Connect 实例。接下来建立一个名为 app
的 Conncect 实例:
var app = connect();
有时候并不需要这样一个 app
变量,可以直接使用 use()
语句将 connect()
链起来,如:
connect()
.use(/* middleware */)
.use(/* middleware */)
.use(/* middleware */)
.listen(3000);
##编写中间件
中间件的基本语法为
.use(function (req, res, next) {
// do something
})
其中 req
和 res
分别是请求和响应对象,而通过调用 next()
可以使请求被下一个中间件捕捉到。
注意:如果没有对请求作出响应,则必须使用 next()
将请求传递至下一个中间件,否则会使页面处于空白无响应状态。
一个例子:
connect()
.use(function (req, res, next) {
if (req.method === 'POST') {
res.end("This is a POST request");
} else {
next();
}
})
.use(function (req, res) {
res.end("This is not a POST request (probably a GET request)");
}).listen(3000);
##Request Object & Response Object
request
对象实际上是一个 http.IncomingMessage
对象,它有如下重要的属性:
req.method
是 HTTP 请求 method。req.url
是请求的 url。req.header
是 hearder 对象。req.query
是查询字符串中的数据组成的对象。需在合适的地方对 query string 使用 connect.query()
进行 parse 操作。req.body
是表单对象。需进行 body parse 操作。req.cookies
是 cookies 对象。需进行 cookies parse 操作。req.session
是session 对象。需要 cookies parse 和 session 中间件。一个完整的例子:
connect()
.use(connect.query()) // gives us req.query
.use(connect.bodyParser()) // gives us req.body
.use(connect.cookieParser()) // for session
.use(connect.session({ secret: "asdf" })) // gives us req.session
.use(function (req, res) {
res.write("req.url: " + req.url + "\n\n");
res.write("req.method: " + req.method + "\n\n");
res.write("req.headers: " + JSON.stringify(req.headers) + "\n\n");
res.write("req.query: " + JSON.stringify(req.query) + "\n\n");
res.write("req.body: " + JSON.stringify(req.body) + "\n\n");
res.write("req.cookies: " + JSON.stringify(req.cookies) + "\n\n");
res.write("req.session: " + JSON.stringify(req.session));
res.end();
}).listen(3000);
没有 Express 这样的框架的支持,不能直接对 respose
进行类似于 render
这样的操作,必须手动写入所有信息。
首先,使用 writeHead()
写入中响应头:
var body = 'hello world';
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
也可以使用 setHeader()
方法进行单项修改:
connect()
.use(function (req, res) {
var accept = req.headers.accept.split(","),
body, type;
console.log(accept);
if (accept.indexOf("application/json") > -1) {
type = "application/json";
body = JSON.stringify({ message: "hello" });
} else if (accept.indexOf("text/html") > -1) {
type = "text/html";
body = "<h1> Hello! </h1>";
} else {
type = "text/plain";
body = "hello!";
}
res.statusCode = 200;
res.setHeader("Content-Type", type);
res.end(body);
}).listen(3000);