后会无期

后会无期

去看了岳父的《后会无期》。关于岳父实在不是脑残粉,很久很久前看过《三重门》而已,甚至连现在它的情节也想不起了。只依稀记得有个小帅哥是男主(哪个故事的男主不是小帅哥),讲高中的故事。后来知道这丫和小四干上了。再后来这丫当了车手。再后来成了岳父。猛然间知道拍了电影。再后来就是排期和《小时代》差不多,俨然干一架的意思。
后来我在公司里投票说,《小苹果》、《后会无期》还有《小时代》大家想看哪部,然后就去看哪部。结果有一同事说我觉得《小时代》也挺不错的啊。结果被其它同事bs个半死。看起来《小时代》是未来,而《后会无期》是现在。因为大多数同事觉得和看《小时代》的有代沟,觉得《后》会更成熟一些。所以侧面印证了《小》这部剧的市场是面向未来的。

啊……我为什么会从这个角度看这么一件事情……

回到这部片子来。

片子充满了欢声笑语,极尽幽默。
“命硬说不好,但命根子,肯!定!硬!”
“无论我在哪里拉屎,总有人给我送纸。”
还有那个“王八蛋”的手语。

我还蛮喜欢这部电影的。
很赤裸裸地告诉大家,现实会如何捉弄人们。印象很深的是,阿吕同学的经历似乎给江河和浩汉以精神导师之感。卧槽我不能缩在那个角落,要像那个旅行者一号一样,用所有的力气,往宇宙深处,只为了看外面的世界一眼。
这时候我想起了年轻或是年少时候的我,想从那个用人际就能搞定一切的小县城挣脱出来,希望在城市能更公平,用能力说明我可以。但显然就像温水煮青蛙,在青蛙尝试跳出来的时候,一个大锅盖下来,“这才是现实”。
在我对阿吕同学开始崇拜的时候,阿吕摆了江汉二人一道。

反正电影就是在不断的内心高呼“卧槽”中度过,很像我们平时的日子有没有。总有一些极品出现在你的生活中。然后你在争吵与将就中度过这些日子。

歌里会唱,Que sera sera, whatever will be will be.
说要顺其自然啊亲。但你不觉得顺其自然,难得糊涂这些,在现实中多让人纠结么。

电影会有一些台词打动你,虽然如果纯电影地看略有生硬之感,仿佛很奇怪地说出来的样子。
比如浩汉说的。每一次告别,最好用力一点。多说一句,可能是最后一句。多看一眼,可能是最后一眼。

网站卡怎么办

网站卡怎么办。。估计这个词搜索量挺高的。
最近刚好碰到一起很二的网站卡的事情,然后花了点时间解决了。然后回头看觉得自己解决的过程还很二。记下来,或许对大家有用。

前奏是这样的
小编:好卡……网站好卡……
工程师:我这儿好好的。
小编:……

又过了一会儿

小编:真的好卡,动都动不了……
工程师:蛤,真的吗?哪里卡?
小编:哪都卡,特别是看贴回贴,然后还有私信。
工程师:那我看看。
小编:……

又过了一会儿
工程师:我看代码逻辑也对啊……是不是你的网络问题?
小编:你看你看又卡了……你看,这个什么502 Bad Gateway是什么意思啊。

啊,终于有一个靠谱的出错信息了。 Continue reading

执行shell远程脚本

出衷:我希望UI组能使用svn来管理css、js、图片。这样PHP组在套用的时候就可以通过对比版本来知道UI组在css里新增了哪些东西。

做法:叫小马把现有ui.rt.cn上的东西转到svn里去。
小马的要求:希望改动代码之后提交到svn之后,能自动发布到ui.rt.cn上去。

问题解析:svn是在192.168.0.27,而ui.rt.cn是在192.168.0.28,两台服务器

思路1:ui.rt.cn上用svn checkout一份,然后定时更新。在0.28上做crontab就好了。
思路2:提交到svn之后,可以利用post-commit这个hook来执行一些命令。应该把“自动发布”这个东西放到这里来。但自动发布怎么做?同样在0.28上checkout一份代码,然后如果能在0.27这台服务器post-commit之后触发0.28的svn up就好了。
so …
[root@test hooks]# cat ui_svn_up.sh
#!/usr/bin/expect
set user root
set host 192.168.0.28
spawn ssh $user@$host
expect -re "]#"
send "cd /home/ui\r"
send "svn up . --username user --password pwd --force -q \r"
expect eof
send "exit\r"

利用expect做跨服务器脚本调用。这里要注意的是我们在0.27到0.28里因为做了ssh key,所以不需要再输用户名和密码。在正常的情况下,是要再改一下代码来实现登录的过程的。

然后在post-commit的hook里加这个脚本就行了。

参考贴:请猛击

就叫我雷锋吧。

fsockopen遇到Temporary failure in name resolution问题的解决

今天迁服务器,然后碰到这么一个问题。
PHP报错:

ERROR: 0 – php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

很明显,name resolution问题,DNS解析问题。
于是修改/etc/resolv.conf,加入114.114.114.114解析服务器。

然后去命令行ping一个163.com,显示错误是network unreachable。
那是网络问题,能登上服务器说明IP肯定没问题了。网关没有配置对。
于是

route add default gw 192.168.0.1

你猜对了,gw的意思是gateway,网关。

然后再ping 163.com,解析对了。

但刷新网页,还是出现这个错误。

于是google/baidu之。发现了这么一篇文章,在三楼里说是用apache+php的,重启apache后解决了问题。

我用的是nginx+php-fpm的方式,于是重启nginx是没用的亲。。要重启php-fpm。。重启php-fpm之后,问题解决了。。
啊,为什么重启nginx没用?因为nginx+php-fpm的时候,nginx只起了把请求从web转移到php-fpm端口的作用,中间没有任何处理的逻辑。所以重启nginx肯定是没用的亲。不信你看nginx里php-fpm配置的那段。。什么叫fastcgi_pass呢?这里的pass意思就是传递,明白了吧。就是把请求丢给fastcgi去处理。

location ~ \.php
    {
#fastcgi_pass  unix:/tmp/php-cgi.sock;
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi.conf;
}

看来php-fpm是把dns的配置信息读到内存里,然后再进行dns操作的。

我们是一堆爱音乐的码农

内个,我们实际是有偷偷在学吉它的。然后教吉它的老湿是一个厦大毕业的学弟(我想应该是学弟吧)。然后Steve老师英文很好,乐理很好,然后能把难懂的乐理用非常容易听得懂的语言说给我们听(虽然我从同学那里学过一点乐理,但是也是很有长进了)。

然后某天我在公司里问了一圈。惊奇地发现部门三分之二以上的同事学过吉它来着,然后就放在某个角落落灰了。于是我把琴从家里搬到了公司。用吃完午饭的20分钟时间练琴。然后怂恿大家把琴带来。于是现在办公室有了四把吉它。

然后我们就一块练啊,53231323,532123,然后C-Am-Dm-G,然后黄金八小节啊……然后我比较用功不是,然后现在会简单的《小薇》、《牵手》、《童年》什么的,虽然还不熟练。然后同事们大呼,有进步啊!
其实只有每天的这20分钟不到的时间,练练手而已。

我在想,如果每天能有两小时来做一件事情,10000小时成为大师一定不是神话对吧。

然后初步的想法是把一些歌弹好,然后会听到什么歌能弹出来。然后哪天去K歌的时候就大喊说,把伴奏关掉~我带了琴~哦哈哈哈哈哈哈哈哈哈。。
生活是丰富的,不要止步于代码、产品、互联网。

MySQL修改表结构的过程

经常用ALTER来修改MySQL的表结构吧?如果这个表很大的话,修改起来很慢是吧?
然后如果用navicat做表结构同步的话,基本每个字段、每个索引的不同都会生成一条ALTER语句,如果你这个时候直接execute all queries,并且刚好你的表里的数据小大,并且你没用上SSD的话,估计你等待ALTER的时间可以吃个饭看场电影了……

这是因为愚蠢的人类没有了解ALTER背后发生了什么事情……

ALTER实际上是这样的。先把a表复制成一个临时表tmp…然后这个时候对a表的select是没问题的,但是update啊或是新的alter啊就会被hold住…然后这个时候服务器会根据ALTER语句去修改临时表的结构……然后现在tmp表是新的结构了……然后服务器再把tmp表更名为a。然后整个ALTER才算结束。然后现在刚刚被hold住的update啊,alter啊就会继续执行。

懂了么,所以如果你有一个300w记录的a表,然后你需要修改a表的10个字段啥的,千万不要写10个alter! 因为在这个过程中,a表要被反复反复地复制成临时表,都是磁盘IO啊……那个慢啊……
聪明一点儿的写法,是把a表的ALTER的10个字段全部写到一个ALTER语句中。比如 ALTER table_a add column xxxxx, add column xxxxxx 。这样就只要复制一次临时表,舒服一些。

史上最简单!用PHP判断一个utf8字符串中是否包含繁体中文

方法很多,比如把所有繁体字收集到一个数组里,然后判断每个字是不是在这个数组里。
比如去找繁体中文的utf8 code的范围。很痛苦有没有!

但是,伟大聪明的罐头有一个史上最简洁的狡诈的方法!!

是的,在gb2312编码中是不包含繁体中文的。所以在转码的时候会把繁体中文丢掉。然后判断两个字符串的长度是否一致,然后就搞定了。。

改造公司的会议

最近公司会议有点儿多,而且觉得又臭又长。根本不想听下去。
在Scrum Master的培训之后,居然学会了用不同的角度来看这些会议。

公司挺多会议就这样的:邮件或是qq上说,一会儿开会啊,谁谁谁到会议室。然后拉人过来,坑哧坑哧把要说的要做的一布置,然后说大家没问题吧,没问题执行吧!
然后大家收拾回座位默默地干活了。

有问题是吧?
1. 会议没目的
开这个会是要沟通啥事,达成什么结果的,没给做预习的功课。会议主持人心里要抱着这个目的来。
2. 会议没过程
把要说的话说了,这不叫会议。大多会议是为了沟通来着。沟通是双向的,有人说话,听众要确认能听得进去。不过大部分会议只做了前半部分,而没保证后半部分。
3. 会议没结果
会议形成的决议是不是能够落地执行?是不是把“会议精神”完整传达到位?

从这礼拜开始,我开始在我参与的会议里有意识地引导会议的流程。
会议开始前,我会找会议发起人说,你这会议是想做什么事情?然后我会问说,这件事情的前提有摸过底吗?大家对这件事情的认识情况如何?然后得到的回答一般是“不知道、不清楚”……
于是我引导了几次会议,看起来效果还不错。

会议中的需要不同,我用的招数也不太一样。

如果需要大家讨论或头脑风暴的场合,一定不要让大家一个个顺序说。而是要让大家先思考,然后把思路记在便笺纸上。然后再阐述各自的观点。这是为了避免有“沉锚效应”,激荡出真正的想法。

另外,为了鼓励大家的信心,我还会把便笺纸贴到白板上,让大家站到前面来讲(不过是我带头贴,然后带头讲,做个示范)。这时候大家其实都非常用心地来阐述自己的想法。这时候的思想沟通是非常有效果的,很大程度上避免了只有一个人在讲话,只有一个人在思考,只出现一个思路。

还有就是要让参会者明白主讲人的意图。
会议

目前我用的办法就是让参会者提问。比如我在介绍产品原型的时候,产品经理把功能点讲了一遍完了之后,我问大家说“大家清楚了吗”,大家默不做声。通常这时候产品经理就觉得大家听明白了,然后继续就下一个话题了。
这时候我又说话了,“那这样,针对现在大家了解的东西,每个人向产品经理提两个问题,只有两个问题。”于是,大家纷纷开口向产品经理提出一些不明白的地方,甚至是一些产品建议。

这是一个很有意思的现象。问“大家清楚了吗”,似乎大家默认清楚了。而要求提两个问题的时候,大家就提出自己不清楚的地方了。

有意安排提问这个环节主要是为了让大家和产品经理充分沟通起来。让产品经理的意图能够被所有人理解,也让产品经理知道哪些地方讲得不够明白。

产品经理讲完了,然后我又问大家“现在大家明白这个原型吗”,大家也都点点头。正常这个会就结束了。但我还加了一个环节就是让大家用一句话概括这个产品是什么。然后大家一个个说。
这也是为了让会议得到一个共同的结果,大家都说出同一句话了,心里想到一块去了,这后面的事情就好办了。

会议的最后,我会给大家发会议邮件,说我们怎么怎么开的,我们得到了什么结论,我们下一步希望得到的东西是这个那个,执行者是这个那个,之类。

其实会议和Scrum的精神挺一致的。Inspection and Adaption,检视与调整。

ps, 会议真心是有技巧的,仿佛是场演出,主持人要把他的想法安排到环节里,让观众有内心的共鸣才是完美演出啊!

怎样的计划靠谱些?

我们都做过个人规划。这时候我们想的是最近几天、最近三个月的、半年的、全年的计划。这个计划里可能有这几天要做的事情,或是年度的大目标(我要和老婆出去玩一趟)。其实做开发的计划,和这个差不多,只是我们可以更有方法地来做这件事情。

目标明确

这个计划是为了什么?它解决的是什么问题?目标不明确,执行一定有问题。这个目标则是从老板到码农都要清楚的。

制定计划项目列表

阻碍目标的实现有哪些问题,换句话说,解决哪些问题就实现了目标?现在要做的就是把这些的所有问题写下来。这些问题可能是一个具体的用户使用场景上的问题,可能是一个BUG,可能是需要做的一些技术或业务实验,也可能是一个具体的功能。
反正先把它们写出来。

现在你可以看到你列出来的问题,有的是很详细的(比如:“常用的功能A居然要两次点击才能进去”),有的则是比较粗旷的(比如:“我只是到这个页面打酱油逛逛的,居然没有对我胃口的内容”)。

现在试着把这个列表按每个条目价值的高低做个排序。
这里的“价值”是很讲究的,也就是说,排序的这个人,要能对这个条目的价值拍板。比如开发经理可能觉得“全站代码重构”是件很重要的事情,但老板完全不care,老板会觉得解决“注册表单太复杂了”是件更重要的事情。
如果一个人不能决定,那就一伙人决定,总得定个价值高低,优先顺序吧。
开发团队会照着这个顺序走,这样保证开发出来的东西始终是最有价值的东西。

排完序了。现在看看这个列表有啥问题没有。
如果要保证开发团队最近的工作能执行得起来,那么就要保证最近的这些计划要够详细是吧。所以如果你价值高的那些任务看上去像是一个假大空的任务,那么就把它细化拆解到一个可具体执行可衡量可验收的程度。或是学术点说,这类的任务必须是SMART的(Specific明确性、Measurable可衡量性、Attainable可达成性、Relevant相关性、Time-bound时限性)。
然后再后续一些的任务可以更粗旷一些。
然后再再后续一些的任务可以更更粗旷一些。

为什么我们不把所有的任务都列得很细,而只把最近要做的价值最高的细化出来呢?

因为计划是会变动的!我们通常做着做着,会有些新的产品方向,那我们在一个月后规划出来很细的东西就没用了。既然它可能完全用不着,就不用一开始就把这部分规划得很细,对吗?特别是目前的互联网节奏,动次打次,节奏很快的!

所以一个好的计划应该是有一个DEEP的特征的:
Detailed Appropriately,最近做的最详细,晚做的不太详细,最后做的最简略。
Estimated,项目是可以估算规模的,这样团队会知道我大概要做多少事情。
Emergent,刚刚说了,这个列表不是一个死列表,它是变化的,是会增减项目的。
Prioritized,每个项目应该判断价值高低,然后从高到低排序。

在Scrum里,这个产品计划叫做Product Backlog。它看起来很可能像是这个样子的。Backlog Prioritization