我是怎么堕落的

人在一个群体 容易被同化
我小学初中 一直是个high爆全场的人,周围的人也high爆全场,所以成绩包括我们班的成绩特别好
到了高中,逐渐所有人变得不再开放 你再high爆全场就会被当成脑残,所以我就也变得不再那么开放,所以成绩就垃圾了

这篇博客用来喷GFW

这个世界没有什么对与错 但是有最佳实践 —男哥
用类比的方法 我们可以更清晰地看清这个世界 甚至这个宇宙 —男哥

2015-01-24更新:
年会的时候跟网络组的同事周天一聊了下,他说GFW是一个在特定时期的特定产物,当我们这样的人成为社会的中坚力量的时候,就没有GFW了。方滨兴其实是一个很不错的教授。
觉得很有道理。

之前跟朋友聊,朋友说GFW不会真正影响我们,说因为翻墙太容易了,只要你想根本不是问题。
他说的的确也是。但是如果翻墙说到底还是会花时间的,如果你一时想要搜一个东西比较急(其实大多数你要搜东西的时候都应该是比较心切想要知道答案的),你一般就会选择百度了,百度没有错,但是如果你因为这个而丧失了接触更好东西的机会,那就得不偿失了。

因为互联网有棒棒的东西叫做超链接,当你得到了优质的搜索结果后,想象力是不可低估的,搜索结果不同造成的影响可以到次方级别。

为什么中国有GFW(我的观点

其实一个国家很多程度上跟一个人类似的,中国之所以对网络那么敏感,就是想限制人们知道有些黑历史。我觉得中国人还是很爱面子的,所以类比的来说,我们中国公民就类似与一个家庭的孩子,因为身家不太清白,家里的大人就限制你去了解世界,因为他怕你知道了黑历史后就觉得自己家原来并不是那么神圣了。
所以我们每个中国公民就像是一个,被内闭的家庭教育所坑害了的孩子

不过既然有害处就一定有好处
GFW的好处:

  • 在墙外我认识了不少墙内优秀的人
  • 有妹子找我学翻墙
  • 麦迪在twitter上回复了我
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
附上跟Yugo的讨论
Your雪人 21:59:01
我同事认识方滨兴
张绍宇 21:59:12
and
Your雪人 21:59:19
中国人素质低 容易被煽动
张绍宇 21:59:25
。。。
张绍宇 22:01:01
这种论调是阴谋
张绍宇 22:01:23
初听之下可能有道理,但经不住推敲
Your雪人 22:01:31
你不觉得他促进了就业么
张绍宇 22:01:40
没有
Your雪人 22:01:49
人们都用洋人的产品 结果是怎样呢
张绍宇 22:02:03
不要有狭隘的民族主义
张绍宇 22:02:21
什么洋人的产品,国人的产品
Your雪人 22:03:54
这只是我现阶段的想法 没有什么对错
我当年也是恨GFW入骨
张绍宇 22:03:59
以前闭关锁国是不是也拉动了就业?
张绍宇 22:04:25
阻止了西方国家倾销大规模工业生产出来的廉价商品?
Your雪人 22:04:40
good call, 历史的结果是怎样的呢
张绍宇 22:04:53
闭关锁国终究会被人暴力打开
张绍宇 22:05:59
你想想程序员都去用百度了,几十年以后国内外技术差异会有多大?
张绍宇 22:07:23
你不知道这些什么意识形态其实都是幌子,只是利益集团为了维护自己利益
Your雪人 22:07:51
http://about.me/zzz6519003
我同事的观点是:这是一个必然产物,等我们这代人成为社会的中坚力量 自然就没有GFW了 我觉得很有道理
你的观点也很有道理
Your雪人 22:08:02
不知道 历史的答案是怎样的
张绍宇 22:08:48
想太多,社会阶层固化,能够成为中间力量的大部分都是利益集团的人
张绍宇 22:09:50
推荐两部小说,动物农场和1984,很有意思的
张绍宇 22:11:40
当然,世界上所有国家其实都是掌握在利益集团手里,只是他们吃相各不一样
Your雪人 22:13:09
你觉得没有GFW我们能听这么多盗版音乐么 pdf
张绍宇 22:13:34
这些是违法行为
张绍宇 22:14:00
而且这和 GFW 没哟一毛钱关系
Your雪人 22:14:03
如果没有GFW 还是可以的吧
张绍宇 22:14:11
只是我国在这方面法制还不健全
张绍宇 22:14:39
现在不是已经有好转迹象了么?
张绍宇 22:15:12
盗版软件害人啊,中国的桌面软件产业就是毁在盗版上了
张绍宇 22:15:42
Office 盗版相当于低价倾销
张绍宇 22:16:28
表面上用盗版 Office 好像赚到了,实际上坑大了
张绍宇 22:16:37
盗版音乐也是一样
Your雪人 22:17:16
乌鲁木齐貌似出现过 政治动乱 结果断网一年 不知道跟网络有关系么
张绍宇 22:18:05
通过网络来联络的
张绍宇 22:19:08
这种特殊情况断网和 GFW 性质完全不同
张绍宇 22:19:42
就像打仗的时候军事管制一样,是在保护大家
Your雪人 22:19:46
good call
Your雪人 22:21:22
我比较好奇中国当年闭关锁国怎么解决的
张绍宇 22:21:41
各种不平等条约,强制通商
Your雪人 22:22:10
Fuck。。。。 china is fucked up
Your雪人 22:22:13
will be
张绍宇 22:22:44
这道不至于被侵略啥的。。。
张绍宇 22:25:04
日本以前不也是闭关锁国么,美国海军跑到江户,开了几炮,把他们都吓尿了
Your雪人 22:27:36
美国能救中国么
张绍宇 22:27:43
才不会
Your雪人 22:28:03
2. 以前 闭关锁国 促进国内就业?
张绍宇 22:28:19
那时候我想是的
Your雪人 22:28:23
3. 强者愈强 弱者愈弱 怎么打破
张绍宇 22:29:43
因为以前中国是农业和手工业,生产力底下,成本高,国外是机械化生产,成本低效率高,很多产品比如纺织品,国外的价格很便宜,如果大量涌入肯定会导致很多人失业
张绍宇 22:30:28
短期来说是可以维持就业的,长期呵呵
Your雪人 22:31:06
下次继续
张绍宇 22:31:35
http://www.zhihu.com/question/19805892
张绍宇 22:32:26
事实是所谓的“闭关锁国”是中国几千年来的基本国策。其目的是维护官方贸易的垄断性,国家权力强占民间权益,国进民退而已。
张绍宇 22:32:42
其中一个回答的主旨
Your雪人 22:33:36
if it were u what would u do
张绍宇 22:33:50
it 是?
Your雪人 22:34:02
国家政府
张绍宇 22:34:39
对什么事情?
Your雪人 22:34:52
维护官方贸易的垄断性
张绍宇 22:35:19
可以看我玩 文明 的时候所选的政策
张绍宇 22:35:34
为啥要维护官方垄断?

The Art of Unix Programming-Book Note

题记 似乎所有的领域 发展到最后 都会变成哲学 —男哥

Rule 1. You can’t tell where a program is going to spend its time. Bottlenecks
occur in surprising places, so don’t try to second guess and put in a speed hack
until you’ve proven that’s where the bottleneck is.
Rule 2. Measure. Don’t tune for speed until you’ve measured, and even then
don’t unless one part of the code overwhelms the rest.
Rule 3. Fancy algorithms are slow when n is small, and n is usually small.
Fancy algorithms have big constants. Until you know that n is frequently going
to be big, don’t get fancy. (Even if n does get big, use Rule 2 first.)
Rule 4. Fancy algorithms are buggier than simple ones, and they’re much
harder to implement. Use simple algorithms as well as simple data structures.
Rule 5. Data dominates. If you’ve chosen the right data structures and
organized things well, the algorithms will almost always be self-evident. Data
structures, not algorithms, are central to programming. [3]
Rule 6. There is no Rule 6

design-defect

I’m gonna use this post to continuesly show all those design defection that I’ve been through.
The God Design is like this:
I think maybe I do this, it can have some effect in my mind, and i tried it, and yay! it works!

Switching input method in OSX
in

Sougou iOS custom input method

In iOS, u can register some quick input combo.
like me, if i type “zzzg”, it should have “zhengzhongzhao###gmail”

in the Sougou custom input method, we don’t have it.

iOS, Wechat, Renren sharing

It’s been a long time since iOS8 releases, but wechat(the most likely one to be the FB in CHINA) haven’t come with the extension of sharing.

不写代码的产品经理/QA很难察觉到的东西

关于微信

  • 微信朋友圈内的分享
    打开朋友圈,点击一个Link,那个favicon图片的获取是通过图片的URL,在分享的时候,通过这个URL来获取图片,这就造成有的时候这个URL并不能即时显示。
    这一点我想可能不写代码的产品经理很难察觉到。
  • 微信的播放媒体后出现的BUG
    场景: 我在听音乐,微信里播放一小段朋友分享的歌曲。我再按线控上的播放按钮,就没有声音了。

node-testing

更新中...

Mocha

Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the documentation.

Intro

搭建一个测试原型

1
2
//f2e 是原型生成的目录
mocha init f2e

浏览器测试 饭桶js

npm i -g mocha-phantomjs

npm i 为npm install的缩写

1
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }

出于应用健壮性的考量,针对前端 js 脚本的单元测试也非常重要。而前后端通吃,也是 mocha 的一大特点。

场景 Situation

  • 在我们现在的subcase项目中,统一了ret_code作为成功与否的标志,方便测试。
  • HTTP Status testing Send HTTP requests, receive responses and check HTTP statuses

Example

Simple example

1
2
3
4
5
6
7
8
9
var should = require('chai').should(),
scapegoat = require('../index'),
escape = scapegoat.escape,
unescape = scapegoat.unescape;
describe('#escape', function() {
it('converts & into &', function() {
escape('&').should.equal('&');
});

API Testing Example

from https://gist.github.com/vgheri/5430387#file-test-js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
describe('Account', function() {
it('should return error trying to save duplicate username', function(done) {
var profile = {
username: 'vgheri',
password: 'test',
firstName: 'Valerio',
lastName: 'Gheri'
};
// once we have specified the info we want to send to the server via POST verb,
// we need to actually perform the action on the resource, in this case we want to
// POST on /api/profiles and we want to send some info
// We do this using the request object, requiring supertest!
request(url)
.post('/api/profiles')
.send(profile)
// end handles the response
.end(function(err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
res.should.have.status(400);
done();
});
});
it('should correctly update an existing account', function(done){
var body = {
firstName: 'JP',
lastName: 'Berd'
};
request(url)
.put('/api/profiles/vgheri')
.send(body)
.expect('Content-Type', /json/)
.expect(200) //Status code
.end(function(err,res) {
if (err) {
throw err;
}
// Should.js fluent syntax applied
res.body.should.have.property('_id');
res.body.firstName.should.equal('JP');
res.body.lastName.should.equal('Berd');
res.body.creationDate.should.not.equal(null);
done();
});
});
});
});
1
2
3
4
5
6
7
8
9
describe('#index', function () {
it('should get /topic/:tid 200', function (done) {
request.get('/topic/' + support.testTopic._id)
.expect(200, function (err, res) {
res.text.should.containEql('test topic content');
res.text.should.containEql('alsotang');
done(err);
});
});

涉及到插入的时候,之前写rspec也遇到类似的
的情况,可以通过测试count是否增加1。

Fun

mocha -R nyan and whole lots of other stuff.

1
2
3
4
5
6
1 -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__,------,
0 -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__| /\_/\
0 -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_~|_( ^ .^)
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ "" ""
1 passing (141ms)

Chai

Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Should
chai.should();
foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.length(3);
tea.should.have.property('flavors')
.with.length(3);
Expect
var expect = chai.expect;
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.length(3);
expect(tea).to.have.property('flavors')
.with.length(3);
Assert
var assert = chai.assert;
assert.typeOf(foo, 'string');
assert.equal(foo, 'bar');
assert.lengthOf(foo, 3)
assert.property(tea, 'flavors');
assert.lengthOf(tea.flavors, 3);

SuperTest

Miscs

Be kind and don’t make developers hunt around in your docs to figure out how to run the tests, add a make test target to your Makefile - TJ

Nock

Nock is an HTTP mocking library that can record HTTP calls and play them back, so that you can either mock an API by hand, or just record actual HTTP calls and use their responses in future test runs. Our orchestrate.js library does the former, but I’ll show you how to do the latter.

转自链接

《九浅一深node.js》Book Note

更新中。。。

模块机制

  • CommonJS希望JS可以在任何地方运行。
  • exports是唯一导出的接口,在模块中有一个module对象,代表自己,而exports就是module的属性。
  • require允许不包含扩展名,会按照.js, .node, .json尝试。
  • 同步配合缓存,可以大幅度缓解Node单线程阻塞调用的缺陷。
  • 18 ~

异步I/O

  • I/O disctributed I/O is pretty expensive
  • The cost of multi-thread when you create thread, and switch between them is expensive.
  • Asynchronous I/O
1
2
3
4
5
6
7
8
9
App OS
I/O call------> process request
/||
other call ||
||
||
||/
callback process done
  • repeatly to call I/O is 轮询
  • 55 ~

Asynchronous Programming

Continuation Passing Style

1
2
3
function foo(x, bar) {
return bar(x);
}

业务重点由返回值转移到了毁掉函数中。

  • 偏函数
1
2
3
4
5
6
7
8
9
10
var toString = Object.prototype.toString;
var isString = function(obj) {
return toString.call(obj) == '[object string]';
};
var isType = function(type) {
return function(obj) {
return toString.call(obj) == '[object' + type + ']';
};
};
  • 雪崩就是高访问并发的时候大量请求同时涌入数据库。
    用事件队列解决
1
2
3
4
5
6
7
8
9
10
11
12
13
var proxy = new events.EventEmitter();
var status = "ready";
var select = function(callback) {
proxy.once("selected", callback);
if (status == "ready") {
status = "pending";
db.select("SQL", function(results) {
proxy.emits("selected", results);
status = "ready";
});
}
};
// 保证相同的SQL语句从开始到结束永远只有一次,Node单线程执行所以无需担心状态同步问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var count = 0;
var results = {};
var done = unction(key, value) {
results[key] = value;
count++;
if (count === 3) {
render(results);
}
};
fs.readFile(template_path, "utf8", function(err, template) {
done("template", template);
});
db.query(sql, function(err, data) {
done("data", data);
});
/* L10n.get
Synchronous method for retrieving localization strings from app's resources. This function should
be used only when direct manipulation on the strings is needed (etc. date/time formatting) and in
all other UI related cases should be replaced with DOM attributes setting or L10n.setAttributes().
This method has also potential to generate race conditions so a developer has to make sure that any
code that uses this method is not fired before l10n resources are loaded using L10n.once() or L10n.
ready().*/
l10.get(function(err, resources) {
done("resources", resources);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
// 烧饼(哨兵)变量和偏函数结合
var after = function(times, callback) {
var count = 0, resutls = {};
return function(key, value) {
results[key] = value;
counts++;
if (count === times) {
callback(results);
}
};
};
var done = after(times, render);
1
2
3
4
5
6
7
8
9
10
// 多对一的收敛和事件订阅/发布
var emitter = new events.Emitter();
var done = after(times, render);
emitter.on("done", done);
emitter.on("done", other);
fs.readFile(template_path, "utf8", function(err, template) {
emitter.emit("done", "template", template);
})
  • 74 ~

构建Web应用

《Node.js开发指南》 Book Note

更新 2014-11-29

Node.js 中,并不是所有的 API 都提供了同步和异步版本。Node.js 不鼓励使用同步 I/O。

模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的。

在 Node.js 中,创建一个模块非常简单,因为一个文件就是一个模块,我们要关注的问
题仅仅在于如何在其他文件中获取这个模块。Node.js 提供了 exports 和 require 两个对
象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获
取模块的 exports 对象。

覆盖 exports

1
2
3
exports.Hello = Hello;
->
module.exports = Hello;

在使用 npm 安装包的时候,有两种模式:本地模式和全局模式。

Node.js核心模块

常用工具 util

提供常用函数的集合,用于弥补核心 JavaScript 的功能过于精简的不足。

  • util.inherits
  • util.inspect

event

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。
为什么要这样做呢?原因有两点。首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发射应该是一个对象的方法。其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。

Node.js进阶话题

核心模块拥有最高的加载优先级,换言之如果有模块与其命名冲突,
Node.js 总是会加载核心模块。

BAD:

1
2
3
4
5
6
7
8
9
var fs = require('fs');
var files = ['a.txt', 'b.txt', 'c.txt'];
for (var i = 0; i < files.length; i++) {
fs.readFile(files[i], 'utf-8', function(err, contents) {
console.log(files);
console.log(i);
console.log(files[i]);
});
}

可以利用
JavaScript 函数式编程的特性,手动建立一个闭包:

1
2
3
4
5
6
7
for (var i = 0; i < files.length; i++) {
(function(i) {
fs.readFile(files[i], 'utf-8', function(err, contents) {
console.log(files[i] + ': ' + contents);
});
})(i);
}

我之前在这个地方,不是特别懂,其实因为他这个例子,用了(i)让我有一些误解,我们可以用以下

1
2
3
4
5
6
7
for (var i = 0; i < 5; i++) {
(function (idx) {
setTimeout(function () {
console.log(idx);
}, 5);
})(i);
}

cluster的功能是生成与当
前进程相同的子进程,并且允许父进程和子进程之间共享端口。Node.js 的另一个核心模块
child_process 也提供了相似的进程生成功能,但最大的区别在于cluster 允许跨进程端
口复用,给我们的网络服务器开发带来了很大的方便。

JS

闭包(closure)是函数式编程中的概念,出现于 20 世纪 60 年代,最早实现闭包的语言
是 Scheme,它是 LISP 的一种方言。之后闭包特性被其他语言广泛吸纳。

  1. 嵌套的回调函数
  2. 实现私有成员
    JavaScript通过约定在所有私有属性前加上下划线(例如_myPrivateProp), 表示这个属性是私有的
1
2
3
4
5
6
7
var generateClosure = function() { var count = 0;
var get = function() {
count ++;
return count; };
return get;
};
var counter = generateClosure(); console.log(counter()); // 输出 1 console.log(counter()); // 输出 2 console.log(counter()); // 输出 3

闭包的严格定义是“由函数(环境)及其封闭的自由变量组成的集合体。”

对象

JavaScript 中的对象实际上就是一个由属性组成的关联数组,属性由名称和值组成,值 的类型可以是任何数据类型,或者函数和其他对象。注意JavaScript具有函数式编程的特性, 所以函数也是一种变量,大多数时候不用与一般的数据类型区分。

call 和 apply 的功能是 以不同的对象作为上下文来调用某个函数。简而言之,就是允许一个对象去调用另一个对象 的成员函数。

1
2
3
4
5
6
7
8
var someuser = {
name: 'byvoid',
display: function(words) {
console.log(this.name + ' says ' + words); }
};
var foo = { name: 'foobar'
};
someuser.display.call(foo, 'hello'); // 输出 foobar says hello
1
2
3
4
5
6
7
8
9
10
11
12
var someuser = {
name: 'byvoid', func: function() {
console.log(this.name);
} };
var foo = { name: 'foobar'
};
foo.func = someuser.func;
foo.func(); // 输出 foobar
foo.func1 = someuser.func.bind(someuser);
foo.func1(); // 输出 byvoid func = someuser.func.bind(foo);
func(); // 输出 foobar func2 = func;
func2(); // 输出 foobar
1
2
3
4
5
6
var person = {
name: 'byvoid', 7 says: function(act, obj) {
console.log(this.name + ' ' + act + ' ' + obj); }
};
person.says('loves', 'diovyb'); // 输出 byvoid loves diovyb
byvoidLoves = person.says.bind(person, 'loves'); byvoidLoves('you'); // 输出 byvoid loves you

TODO

  • 构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构
    造函数内定义的属性。
  • 构造函数内定义的任何属性,包括函数在内都会被重复创
  • 同一个构造函数产生的
    两个对象不共享实例。
  • 构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。

Learning Notes Angular

1
2
3
4
5
6
7
8
9
<body class="container" ng-controller="StoreController as store">
<div class="product row">
<h3>
<em class="pull-right">$</em>
</h3>
<button>Add to Cart</button>
</div>
</body>
1
<button ng-show="store.product.canPurchase">Add to Cart</button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
(function() {
var app = angular.module('gemStore', []);
app.controller('StoreController', function(){
this.product = gem;
});
var gem = {
name: 'Azurite',
price: 110.50,
canPurchase: false,
soldOut: true
};
})();
  • ng-hide
1
2
3
4
5
6
7
8
<body class="container" ng-controller="StoreController as store">
<div class="product row" ng-repeat="product in store.products">
<h3>
<em class="pull-right">$</em>
</h3>
</div>
</body>
1
<em class="pull-right">{{product.price | currency </em>
  • Pipe - “send the output into”