改变世界的不是技术,而是运用技术的能力

改变世界的不是技术,而是运用技术的能力。作为一个程序员,技术很容易取得,运用的能力却没那么容易。正如少林扫地僧所说,武功越高,越需要相应的佛法化解其戾气,如若不然,就会反噬自身。 我看到太多的程序员,一心钻研新技术,寻求百亿并发的解决之道,一上来就是去中心化,满嘴跑火车,却不关心自己的产品有多少人用,不关心如何将现有的技术发挥到极致。 这段话是我在手机上码的,当时我正处于暴走状态,本来准备写完发个朋友圈的,但怕朋友突然的关心,所以没发。好在我的博客没什么人看,就发这里了。

July 12, 2017

记一次神奇的出差经历

今天找资料无意中看到一些前年的照片,其中有几张是我在一次出差途中拍摄的,现在想来,那次出差非常有意思,值得花两个小时记录下来,等老了好跟孙子吹牛。 先来交代一下事情的背景吧。那时我就职于一家做教育产品的互联网公司,核心产品简单来说就是幼儿园版微信。虽然终端用户主要是幼儿家长,但主要面向幼儿园推广。有些幼儿园比较难搞,于是 CEO 有时候不得不许诺一些额外的东西,比如做个官网之类的。 有家嘉兴的幼儿教育培训机构,提出了要做一个网站,CEO 估计是迫于业绩压力,答应了。后来人家又要求部署到自己的服务器上(估计是因为官方背景),由于我们给人家做的网站是用我们的比较“高大上”的技术栈做的,对方的 IT 人员搞不定,要求我们派人去现场部署,并表示可以报销差旅费。 当时我们服务端有四五个人,不过能搞定这个事情的,估计只有我和 Leader,所以问题就简单了,只能我去了。Leader 舍不得工作日放我去,因为那时开发任务也比较紧张,CEO 一番讨价还价后,我自愿决定放弃双休,前往嘉兴帮 CEO “擦屁股”。CEO 打保票说,不会让你白跑一趟。 那是我职业生涯中第一次出差。周六一大早从南京南站坐高铁前往嘉兴,由于起床太早,在车上睡着了,于是悲剧了,我睡到了上海,出师不利啊!到嘉兴时已经是下午一点,然后把地址搞错,又折返了一程,到目的地的时候,已经快下午三点。 由于是周六,对方办公楼里看不到人。接待我的人带我到机房,机房是这个样子的(当然,这是后面部署中拍的图) 我一看机房没人,惊出一身冷汗。因为接待我的人(看起来像是一个即将退休的老男人)说自己不是搞技术的,有问题打某某某电话,然后给我一个红包转身就走了。 来之前,我意淫过各种美妙的场景,当然最多的还是一群年轻漂亮天真好奇的幼儿园女教师们围着我问这问那亦或是安静地一脸崇拜地看着我忙碌。然而我想多了,我身处几乎空无一人的办公大楼,面对的是几台嗡嗡嗡的服务器——这个就是现实与理想的差距啊。 我镇定下来,仔细观察了一下服务器。虽然我之前只接触过学校里的 Windows Server 和阿里云的 ECS,并且都是远程操作没有接触过真机,但凭着我当年在学校里给学姐学妹们数百台笔记本装系统、解决各种疑难杂症的经验,我自信这点小问题难不到我(还有谷歌百度可以用嘛)。 这是一台装了 Windows Server 2003 的 IBM xSeries 235 塔式服务器,内存 512M,是一台布满灰尘、十几年前就已经停产了的老古董,可以放在博物馆里的那种。情况非常美妙,因为我们的项目只能部署在 *nix 系统上,并且底层框架需要编译,512M 内存不够用,还得搞个交换分区。另外比较幸运的就是这台服务器可以访问外网。 我出发前刻意带了两个优盘,一个刻了 32 位的 lunbuntu,一个刻了 64 位的 Ubuntu Server 版,机智如我。 于是打电话问了接待的人提供的 IT 电话,问能不能重装系统,对方说可以。立马掏出优盘插入,重启,进入启动项菜单,等等,怎么优盘识别不到?立即换接口,换优盘,等所有方案都试了一遍后发现,两个优盘在所有 USB 口上都不能识别。 蛋碎了…… 此时我心中一万匹草泥马奔过…… 千算万算还是失算了…… 这时候我需要的是冷静。 仔细分析了一下,只剩下一条路可以走,就是使用光驱。当时的时间是 2015年12月12日的下午四点,在一个陌生的城市想要买空白光盘。这个时间点有点尴尬,掐指一算,我上次使用光盘应该是5年前了。看来一天搞定再玩一天的计划要落空了。 别无他法,只能拼人品了。 出了办公大楼,打开手机上的地图App,发现离市中心比较远,校区北面是一家沃尔玛,决定去碰碰运气。也许是那天人品大爆发,顺利地在超市里找到了 CD 和 DVD 空白盘,犹豫了一下,决定求稳,买了 CD。花了一个多小时,终于带着光盘回到了机房。 ...

July 12, 2017

论软件工程师的职业素养

在过去,工程师是一个极难获得的称谓,通常需要获取相应的学位,有多年的工作经验,甚至还要通过官方的考评,方能取得。 那时的工程师,往往要承担着社会责任。比如,作为桥梁工程师,你设计了一座大桥,就得为大桥的质量负责, 如果桥垮了,你是要跳河的。 然而,自互联网兴盛以来,出现了一大波“软件工程师”,也就是程序员,他们轻易获取了“工程师”的头衔, 其中有些人毫无职业素养,毫无责任担当。当然,我并非想要贬低程序员,因为本人也是一个程序员, 只是最近掉进坑了,满腹牢骚,愤懑不平,怨气冲天,才不得不作此文,吐槽以泄愤。 在我看来,作为一名软件工程师,最基本职业素养就是专业技能,也就是编码和程序设计,其他的比如团队精神等等等这里就不多谈了, 因为今天只想吐槽这么多。 首先来说说编码。作为一名合格的软件工程师,必须要明白代码的可维护性是多么重要,用来衡量可维护性的,首先是代码的可读性。 有些人把代码写得别人看不懂,就飘飘然以为自己多牛逼多厉害。比如判断一个变量是否为 0,0 偏偏要写成 intval(chr(48)),等等等诸如此类不胜枚举,罄竹难书。 殊不知这种行为愚蠢至极,过两年把他拉回来看自己的这些代码,他一定会抽自己嘴巴子,因为他自己也看不懂自己写了什么。 所以请记住:你的代码别人看不懂,只有外行人才会觉得你牛逼,同行都会说你傻逼。在编码的时候,一定要想一想,这么写别人能理解我的意图吗?代码要写得傻一点,这一点脚本语言工程师尤其要注意,不要滥用魔法特性。 再来扯扯程序设计。其实这一点跟代码的可读性有共通之处,程序设计的目的首先是满足业务需求,其次就是在满足业务需求的前提下保证代码的可维护性,也就是保证代码描述的业务逻辑容易被人理解。 偏偏有些人,自以为自己的设计高端大气上档次,一个缓存 key,存了 9999 条数据,我只想问,有一条数据更新了怎么办? 恭喜你,答错了。人家的做法不是把这 9999 条数据查出来重新 set(虽然这已经足够奇葩),而是把全表的数据查出来每 9999 条分批 set 一遍(奇葩中的奇葩)。除了数据更新,有新数据插入缓存也要全部更新一遍。 哪天内存不够加载全表的数据了怎么办?没事啊,人家已经跑路了!人家跑路了项目怎么办?没事啊,有接盘侠啊! 没错,我就是这个接盘侠。昨天我花了一个晚上,把这波缓存改成了正常人的设计。 2016年的最后两天,我接了一个盘,不过,我会接好这个盘。 我不入地狱,谁入地狱?

December 30, 2016

用 mermaid 画甘特图

今天发现了一个比较好用的画甘特图/流程图的工具:mermaid,官方的介绍是: “Generation of diagram and flowchart from text in a similar manner as markdown”。 我说好是因为对程序员好,支持命令行操作并且是开源的,貌似还可以整合进 Markdown,不过我没找到相关的案例。 使用在线工具绘制 mermaid 提供了一个在线编辑器,可以迅速在线作图,下面是官方的 demo … 生成的效果是这样的: 再来一个甘特图的: … 生成的效果: 画甘特图可以参考官方的 Gantt语法文档。 使用命令行绘制 由于 mermaid 使用 nodejs 写的,所以需要 node 环境,这个不多说,根据自己的平台安装好 node 即可。 安装 mermaid 一行命令搞定: npm install -g phantomjs && npm install -g mermaid 完成之后,就可以使用命令行了。 先新建一个文本文件,我们这里就来展示一个甘特图,所以命名 demo.gantt,当然,文件名随意起就好。demo.gantt 文件内容就用上面的甘特图的例子,然后使用命令: mermaid demo .gantt -w 1920 -s -p -o images 就可以在 images 目录下生成两个文件,一个是 PNG 图片,另一个是 SVG 矢量图。 可以用 mermaid -h 命令查看帮助,这里我贴上刚刚那条命令里用到的参数: ...

September 13, 2016

为什么我要写 ResquePanel

ResquePanel 是用于监控 php-resque 的一款 Web 界面工具。完全使用 PHP 开发。当然,由于 resque 的 “正版” 是 Ruby 写的,所以你也可以用来监控 Ruby 版的 resque。 也许有人会说我造轮子,因为很容易可以在 GitHub 上搜到一个叫 ResqueBoard 的项目,还有个非常漂亮的介绍网页,如图: 可以看出来,作者花费了不少心思,前端做得也漂亮(我觉得这个前端堪称完美!)。所以刚开始我也用了这个,于是,发现了问题。 ResqueBoard 的缺陷 首先是该项目依赖太多,除了 Node.js 的 Cube,另外还要装一个 MongoDB,最关键的还在于如果你需要使用作者改写过的 php-resque,这让人很是担心。虽然我毫不怀疑作者的人品,但要我把正在跑的一个项目依赖的库替换掉(因为与原项目冲突),还是有不少担心的。然后就是 Cube 依赖的一个叫 websocket-server 的项目已经不见了,导致 npm install 安装依赖失败,Google 了半天,最后在该项目的 GitHub Issue List 里找到解决方案,过程参见 npm install cube Error: No dist in websocket-server package。折腾了半天,Cube 的两个进程跑起来了。最后就是替换项目里原来用的 php-resque,小心翼翼。配置了 Nginx 后终于跑起来了。 跑起来后发现,首页是能看了,其他页面都有问题,一检查,发现 web 目录下有个 .htaccess 文件,一看尿了,rewrite 规则这么多!只能用 apache 了,于是又给服务器装了 apache,Nginx 做反代,搞了半天终于基本正常了,右上角显示的三个服务正常连接。再对照官方文档,完全正确了。 但是,跑了几天后,发现数据有问题。首先是很多数据完全获取不到,基本上除了看到队列、处理了多少个 Job,其他一切显示没有数据。这一点让我很是伤心。各种找原因,反复查看官方文档、Issue 列表,还是没找到问题。 我最终决定自己写一个,简单一点的。 ...

June 3, 2016

为什么我不用钢化膜

钢化膜一定要做得易碎,这样手机摔在地上时,膜碎的概率要远远大于屏幕碎的概率: —— 当用户拿起手机返现膜碎了屏没碎,会说,啊,我的钢化膜保护了手机,如果不是它,估计屏幕就要碎了!然后果断再买一块新的钢化膜。结果是用户消费了更多的钢化膜。 —— 反之,如果屏幕碎了膜没碎,用户会说,我擦,贴个膜没卵用!以后再也不贴了!结果是最后没人用钢化膜了。 所以,钢化膜一定要做得易碎,越容易碎越好! PS: 当有人问我为什么不贴膜时,我想到了上面这段话。 : ) 2016年1月29日补记 一朋友看到此文后给我发来下面这张图片,以彰余智。

November 30, 2015

PHPCON 2015(北京站)之旅

2014年 PHPCON 上海站举办前夕,老胡问我去不去,当时对这些会议不是很感冒(其实主要原因是没钱),就没去,不过当时我们约定第二年一起去。到今年北京站举办前一个月,老胡发来链接,问我来否,我自然不想做一个放鸽子的人,领导 Allen 知悉后表示他也要去,于是买门票买车票不提。 6月6日早上到达北京,直奔会场,时间刚刚好。此行主要是为了见一见国内的 PHP 大牛的风采(其实我只熟悉两位嘉宾:惠新宸和韩天峰),顺便看看这些会议到底是一个什么样的情况(因为此前曾参加过南京的一个互联网沙龙,看到最后发现全是广告,所以印象极差——也许是因为免费的)。 先来张会议的日程: 首先开讲的是来自新浪微博的胡波,主要讲 Yaf/Yar 在微博里的使用情况——手机微博服务端这一块从 v4 升级到 v5 的坎坷过程。 由于我们正在使用 Yaf/Yar (后来用 Phalcon 替换了 Yaf),所以胡波的内容让我们极是受用,忍不住多拍了几张现场 PPT (强调一下我一般很少拍照片的): 这两张图说明了 v4 到 v5 升级过程中要解决的问题,跟我们产品 v2 到 v3 的升级非常类似。 我们产品 v2 版本为了求速度,用了我们比较熟悉的 Symfony2,后来使用 ab 压测发现 QPS 极低,才 8 个左右,分析了一下代码执行时间,发现 Symfony2 框架启动时间太高,所以 v2.1 时 App 的接口部分换成了 Yaf,由于 Yaf 过于简洁,没有 ORM 之类的模块,从 v2.3 开始新的业务模块用 Phalcon 写,所以我们的 v2.x 版本用了3个框架。采用了 Yaf/Phalcon 的新的业务模块速度相对老的速度提升明显。 胡波的内容对我们从 v2.x 升级到 v3 有很大启发,不过后来由于我们的业务改变巨大,v3 核心基本上是一个新系统,所以只能部分实践。 ...

June 17, 2015

在 PHPStorm 中使用 region (代码折叠)

使用 VS 写 C# 的人都很喜欢 #region 实现的代码折叠功能。PHP 本身没有类似的功能,但作为一个 PHPer,肯定不甘在这一点上示弱。本文就介绍使用史上最强大 PHP IDE —— PHPStorm 实现代码折叠(注:不一定是一个函数或一个类的)。 其实前面废话说了这么多,正文就只有三行: //region description code.... //endregion 有人要说没图你说个 Smartisan,好,我就贴个图: 展开效果图: 折叠效果图: 注:只在 PHPStorm 下有效。当然,不仅支持 PHP 代码,也支持 js 代码。

January 24, 2014

我的Linux发行版/桌面环境选择之路

PS:这是一个年轻程序员折腾 Linux 桌面的流水账。。。 2013年3月份 Unity 这个时间用的是Ubuntu 12.10,默认的Unity界面,稳定性一般,最不习惯的是,窗口操作按钮(最小化最大化关闭)在左上角,用惯了Windows的我很不习惯。然后就是,Unity的菜单很炫,但不幸的是,09年的ThinkPad R400表示反应有点迟钝,所以我决定换个不那么炫的桌面环境。 2013年4~7月份 KDE 4 这几个月先是在原来Ubuntu 12.10装了KDE 4、BlackBox、Xfce、GNome 3,都折腾了一遍之后,决定使用 KDE 4。KDE 4的优点就是插件多,使用习惯类似Windows,然后就是默认的资源管理器功能强大,远超Unity。 不选GNome3的原因是,感觉跟Unity有点像(个人觉得本质上区别不大,按下WinKey,机械硬盘就会表示压力很大),至于其他的几个,都感觉上个世纪来的。这时候Ubuntu13.04来了,于是直接下了个Kubuntu装了。 2013年8月份 回归Unity 时间一长,就发现Kubuntu的不好了。主要还是Ubuntu的原罪——每次开机都会提示一个错误,永远修复不了。然后就是KDE本身的一些问题,比如对多屏支持不好(我费了好大力气解决的),然后就是发现KDE并不是那么漂亮、精致。 8月份离开前公司,换系统,又换回了Ubuntu,换回了Unity。 2013年9~11月份 Linux Mint(Cinnamon) 月份来到现在的公司,无意中发现Unity的一个重大Bug,就是鼠标按着拖来拖去时可能导致图形界面崩溃——即时升级到13.10,等Bug修复不知何年何月,再加上对Unity的种种不满,于是,决心放弃Ubuntu。 又开始折腾,这时已经相对来讲比较熟悉Linux了,于是尝试使用Debian——终于还是被驱动击败了。。。Debian都搞不定,更别提Gentoo了,于是,还是回到Ubuntu系上。 找来找去,无意中尝试了一下Linux Mint(其实我还在下载的时候,并没有报任何希望,因为感觉Linux Mint的官网略显。。。寒酸),使用的Cinnamon桌面环境,一切都是那么美好….. 适合我多年的Windows下的习惯,又满足了我对Terminal的需求,至于稳定性,还需要时间去验证,至少目前来看,不输于Unity。最终选定Linux Mint(Cinnamon桌面环境)。 2013年12月1日更新 前几日给笔记本换了块硬盘,装了Fedora19。感觉GNOME3还是不错的。不过我主要的目的是尝试一下yum。我觉得貌似 Fedora 比 Ubuntu 要快那么一点点。。。难道是我的错觉? 2014年3月12日更新 折腾了一年的 Linux桌面,最终还是找不到一个稳定又好用且漂亮的,最终还是在新年到来之前回归了 Win7,还特别安装了 Cygwin 以及 Gow,让好用的 grep 等命令保留下来。Win7终归是“温妻”啊! 2014年5月29日更新 3月底入手 ThinkPad X240 后,开始转到 Win8.1,这个过程还好,尤其是 X240 的触控板,在 Windows 下很好用,在 Linux 下很不好用,没办法,没有驱动的支持,再牛叉的硬件也是扯淡啊。 2025年4月1日更新 自2015年5月开始正式切换到 macOS(彼时还叫 Mac OS X),至今已有整整 10 年。 macOS 虽然在很多方面都比不过 Windows,但在 Web 开发方便,便利性远超 Windows。 ...

November 30, 2013

关于使用 Symfony2 开发时遇到的一个诡异的 bug

问题描述 最近在使用symfony 2开发,处于刚入门阶段。昨天完成了注册登录模块,开发阶段一直没有问题,快完成时诡异的错误出现了:注册成功后,查询数据表,记录存在,但登录始终报错。 由于登录是使用symfony2自带的安全框架,又不知道 symfony2有什么debug的好方法,所以只能检查代码,继续读symfony2文档,因为之前做过登录注册模块,所以对配置什么的还是蛮有信心,确信不会错,搞了半天不知道问题在哪。注册成功,登录始终不成功。 衣带渐宽终不悔,为 bug 消的人憔悴 最后还是同事过来,问我用什么加密,然后试图寻找登录加密与注册加密的结果是否一致。不成功,因为login的过程完全由symfony来完成的,查文档一时又找不到login具体的代码,最后,我们找了一个在线加密网站,比对加密结果和注册加密结果是否一致,最后结果是一致。。。 蛋疼!泥马这错太诡异了!难道真要我这个刚入门的去看框架源码??? 众里寻bug千百度,蓦然回首,bug 却在灯火阑珊处 正当我垂头丧气心如死灰批头散发郁闷的要死的时候,突然!眼前一亮!为什么网站上加密结果的最后是两个等号而数据库里面的没有等号???!!! 我擦,终于找到了!经过测试,发现快完成的时候改用了架构师设计的数据库,password字段长度只有50,而我之前设计的是255,且密码在采用sha512算法加密后长度大于50,导致写入数据库的只有前面的50个字符,所以我开始比对的时候竟然没有发现这个问题。。。 我看开头几位都一样就没有关注后面的。。。!!! 而我的印象里,如果字符串大于数据库设计的长度应该是要报错的,所以要么是mysql截取了,要么是symfony截取了,具体原因等下次再研究吧。。。

October 18, 2013