5月
25
2014

「我只是认真」——聊聊工匠情怀

老罗的Smartisan T1手机发布会很多人应该都看了,发布会的最后老罗凝视着自己的工匠自画像,半晌没说话,随后转过身,慢慢离开舞台,屏幕下方只留下一句话:

我不是为了输赢,我就是认真。

这一瞬间让我想起93年「狮城舌战」的主角蒋昌建,在「人性本善还是人性本恶」的总结陈词最后,以顾城的名句,「黑夜给了我黑色的眼睛,我却用它寻找光明」,把整个辩论赛的氛围推向高潮。

而老罗的这句话,和这句话背后的工匠背景,却以另外一种无声的却震人心魄的力量,敲打着每一个在场的,或是观看着整个发布会的观众的心绪。

「工匠情怀」,我深有体会,就像我在 面向GC的Java编程 一文中所提到的:

优秀程序员的价值,不在于其所掌握的几招屠龙之术,而是在细节中见真著。

如果我们可以一次把事情做对,并且做好,在允许的范围内尽可能追求卓越,为什么不去做呢?

追求卓越,追求完美,追求细节的极致。小时候看到那些修表匠,握着一个小螺丝刀,或是看着电工,用烙铁沾着锡和松香,在那一小寸的世界里,把坏了的地方修好,那种专注的眼神,觉得很厉害。

现在再去回想那些工匠工作的场景,越发觉得钦佩。在我老家有一家刻章的店,在我上幼儿园的时候就已经在那开了很多年了。前段时间需要刻一个章,发现那家店还在,于是走进去,门口坐着一个老人,我确实记不得当年是不是他,不过看这岁数八九不离十。我以前在别的地方刻的章,都是在电脑里设计完图案后,激光刻蚀。但那次老人却是用的手刻,我着实惊呆了。只看他拿出一块红色的印底,右手持着刻刀,开始一下一下地刻着。虽然老人连话都不怎么说得清了,但是工作时那专注的神情,和精湛的手艺,以及最后成品那比机器更完美的效果,着实让我心里非常动容。

一、技术人的执着

我见过很多人,也见过很多程序员,都有如此的「工匠情怀」。

做产品需求评审,有的人善于快速提供技术解决方案,在最短的时间内解决问题。

但我见过的很多牛人,他们除了能在脑海里最快地形成方案原型,并且更深入地考虑各种细节点,最终能给出一个更趋于完善的技术方案。

在他们身上,我看到了对这项职业的自我尊重,对自我价值的追求,也有对「卓越」的理解和渴求

《精通正则表达式》的译者余晟老师写过他和正则表达式的 缘起 。只是因为项目经理让他「多用Google,查查正则表达式的资料」,余老师打开了正则的大门,读完了英文原版的《Mastering Regular Expression》,如今成为了国内最了解正则表达式的人之一。

看完那篇文章其实我想起了我的实习经历。那时候我刚去公司两三天,有一天我老板找我让我研究一下如何用Java里的MappedByteBuffer做文件内存映射来读取大文件。尽管我们当时要处理的文件很大,以我在学校编码的经验看,用普通的Reader也是可以很好地解决的。

于是我说,「这个其实用Reader也能做,更简单一些,没那么麻烦。」

老板反问我,「什么叫没那么麻烦,这是一个做技术的人的态度吗?」

那几天我花了很多时间,去从Linux一直到JVM,去了解什么是内存映射,底层原理是什么,和其它技术的比较、优缺点,并和其它几种读文件的技术做了性能对比。

虽然最后项目没有采用这个方案,但是那句反问直到现在一直在我脑海里,时时地提醒我:「做技术的人,对待技术,应该拥有什么样的态度?

所以其实我很感谢我的老板,以前他教我们这些新人优秀的职场习惯,有一条是每天的邮件必须没有未读数,即便是不需要阅读的邮件,也要一键置为已读,不要留一个未读的数字在那。现在想起来,有点像iOS App右上角那个提醒数的角标,有些强迫症的人怎么也忍受不了有个红圈圈在那。开个玩笑,虽然有些习惯看起来可有可无,无关紧要,但这确实映射了一种态度和思维习惯。

完美有多远?我不知道,但我愿意多往前走一步。

二、拾起初衷

我们的生活,每天很忙碌。有时候忙得自己都忘记了为什么在此处,有时候忙得只能不断地用直觉、用以往的经验去设计一个解决方案,而没有时间去思考需求是不是合理,方案是不是最佳,我们以为自己设计的是最佳实践,谁知道呢?

这个社会,这个世界,处在一个以不可思议的速度向前直奔的时间线上,我们处在这个时代的浪潮之上,每个人都感到了那种令人窒息的紧迫感。

父母都是不希望孩子太累的,我们见过很多这样的话:

差不多就行了。

糊弄糊弄就完事了。

不要与众不同。

顺其自然。

但是你应该问问自己,是不是真的要 顺其自然

我记得在上大二的时候,听一个叫端木恒的人说过一句话,大意是,这个世界上,政治可以改变很多事情,而科技,可以通过促进信息的流通,最终去推动政治的变革,去改变整个世界。

当时觉得这事儿太酷了,是的,所以我当时的想法是,要去一个技术足够强大,并且对人们的生活有实质影响的公司。希望用技术的力量去让更多人生活地更好。

这当然是一种不自量力,但又如何呢?只是一个普通人小小的想法,不断追求卓越,愿意比别人多往前走一步而已。

就像冯大辉说的:

所有人都说你做不成,都告诉你不要去做,不靠谱,嘲讽你,而你最后真的把事情做起来了,这就是牛逼。

做成了,其实牛不牛逼对你自己而言已经不重要了。

没做成,所有人都笑你是傻逼,但起码也对得起自己的内心。

再说,如果 青年人 想的都是养老和退休,那做事的人在哪?

三、发现更好的自己

老罗最后的一个问题是:

在一个完美主义者的眼里,这是一个怎样的世界?

这个社会上很多人在生活上追求更高的品质,但愿意对自己手头所做的事情坚持高标准坚持卓越理念的人已经不多见了,以至于我们发现花再多的钱也买不到安全的食品了,花了一辈子的积蓄买的房子却有各种质量问题。扪心自问自己在工作中是否能坚持某些东西,大部分人的态度都差不多,只是你糊弄一下不会怎样,而他马虎一点就会死人,区别仅仅在于这里

M·斯科特·派克说过一句话:

规避问题和逃避问题的趋向,是人类心理疾病的根源。

很多人把随大流把妥协作为一种「成熟」的标志,小时候敢想敢说可能也敢做,长大以后懂得了人情世故,懂得向现实妥协,45度角仰望天空说自己终于长大了。再看身边那些「冥顽不灵」、「认死理」的所谓完美主义者,认为这些人才是不正常的群体,把这些人要么当做傻逼要么当做装逼。

天哪,我都想问,「这是一个怎样的世界?」

肯定有人会说,站着说话不腰疼。诚然,在生活中,有的人是为了活下去,有的人是为了活得更好,有的人是为了帮助别人活得更好。这是不同的人生阶段,每个人的情况不一样,但这并不影响每个人内心的精神寄托和对信念的追求。

我从不指望去改变别人,但我相信我可以改变自己,虽然也很难。

学生都喜欢问,如何最快地提高自己的能力。说实话,我真的不知道什么是捷径,我的经验就是和比你优秀的人一起工作,经常请教比你资深的人,不断挑战过去的自己(每天审视自己太紧张了,只要比前段时间的自己更好就可以了)。

四、细节是魔鬼

Devils are in the details,细节是魔鬼,这句话很多人都听过,但要在工作中时时刻刻注意?难。

前几天给同事做Code Review,就几行代码,发现了一个问题。

场景是我们发现某个系统中存在占用内存超大的HTML字符串,需要统计HTML字符串的长度,于是为了获得准确的字节长度,这段代码调用的是String.getBytes().length,一眼看起来并没有什么大问题。

但是考虑到本身这个字符串就比较大,联想到Java内部是用UTF-16存储字符串的,而getBytes()会转换为系统默认编码(GBK或是UTF-8等等),这里必然存在底层字符数组的拷贝(可以去参考String.getBytes()的源代码证实),一个本身就很大的字符串,经过拷贝,将会占用更多的内存,加剧这个问题,而在HTML中,中文其实只占了非常小的一部分,所以直接用String.length(),虽然会少数几个字符,但对统计结果影响其实并不大,并且这里不存在任何数组分配的开销。

另外建议所有调用String.getBytes()的地方通通显式传入编码,这是个大坑。

另外一个案例,也是在Code Review的时候发现的。

某个调用场景下,每次都会新建一个解析器对象去解析结果,尽管解析器没有任何实例变量不会产生线程安全问题,创建的开销也并不大,但我还是坚持要改成单例,使用同一个实例去处理,这也符合面向GC编程的思想。

这些场景,每天我们都在遇到,也许我们会说这些都是很小的问题,无伤大雅,差不多就行了。但就像前面说的,这是一种态度,一种思维习惯,当你坚持用最高的标准去要求自己,去要求自己的工作时,你才有可能渐渐接近卓越。细节是魔鬼,它会在完全察觉不到的时刻,把人拉回平庸。

「我不是为了输赢,我就是认真。」这不代表我们不在乎输赢,从头至尾我都坚信,只有坚持完美,坚持品质,坚持那些我们曾经了解现在可能已经放弃了的美好的东西,像一个老工匠,把一种专注、追求极致的情怀融入我们的作品里,也许有一天,就有人,追寻着 梦想 ,发现了 生活更多的可能性 ,像乔布斯、像贝索斯,改变整个行业,改变全世界。

我们是被这个时代推上浪潮之巅的人,是去做一个见证者,或是一个冲在最前面也不怕被拍死的傻瓜,是我们每个人选择的权利。

只是不要忘记,那些傻瓜,不是真的不怕死,他们只是认真

Written by Hesey Wang in: 思考 |

29 Comments »

  • Honwhy

    我想变得简单,更加专注地去追求一门技艺,却往往输给了现实输给了安全感。

    [回复]

    Yurii 回复:

    你说的“安全感”是因为没彻底弄清楚所以不安的感觉吗?

    [回复]

    Honwhy 回复:

    我已经将迷茫不清楚的的安全感问题具体到我的技术选择问题了。
    我懂或者略懂几门编程语言,从C语言还不停留在基础水平,害怕找不到工作,java编程经验特别少,而且还从来没有学习过基础,都是边查边码的,j2ee框架很多,我会的很少,是不是没有优势啊?我个人又想学习Node.js和python,对android又感兴趣,这些可以统称技术上的不安全感吧。

    [回复]

    Yurii 回复:

    要在干中学,不经过实践的检验,怎么知道自己的水平到底如何?呆在家里想对这个那个感兴趣是没用的,到外面去练练,就有方向了。

    Hesey Wang 回复:

    可能是你还没有一项深入的技能能给你足够的自信感,不妨选择一个领域深挖下去,做到比身边的人都要优秀的时候,未知的东西就没那么恐惧了。

    Comment | 2014 年 05 月 25 日
  • […] (感谢网友 @Hesey小纯纯 投稿  博客 | 原文链接) […]

    Pingback | 2014 年 05 月 26 日
  • “追求卓越,成功自己就会找上门” 。。 《三个白痴》

    [回复]

    Comment | 2014 年 05 月 26 日
  • malasang

    93年「狮城舌战」的主角蒋昌建

    [回复]

    malasang 回复:

    你暴露了你的年龄

    [回复]

    Comment | 2014 年 05 月 26 日
  • IdleMind

    关注细节,以老工匠的态度做自己的工作。

    [回复]

    Comment | 2014 年 05 月 26 日
  • 晴天雨植

    不错,学习了

    [回复]

    Comment | 2014 年 05 月 26 日
  • 赞认真精神。
    做到普通人眼中“不必要”的程度,才能达到超出普通人的水平——也就是能在一个微小领域,推动世界进步一点点。

    [回复]

    Comment | 2014 年 05 月 26 日
  • 恩,很有想法!!!

    [回复]

    Comment | 2014 年 05 月 26 日
  • AGCT

    学生都喜欢问,如何最快地告诉自己的能力。
    “告诉”打错了?

    [回复]

    Hesey Wang 回复:

    已修正,谢谢

    [回复]

    Comment | 2014 年 05 月 26 日
  • 匿名

    您好。您的博客能用rss定阅吗?我怎么找不到rss的链接。

    [回复]

    Hesey Wang 回复:

    可以,右上角的Feed图标即是。URL: http://blog.hesey.net/feed

    [回复]

    Comment | 2014 年 05 月 26 日
  • 匿名

    如警钟响于耳。最近有些迷茫,怀疑自己,但总是告诉自己,坚持下去就有好的结果。坚持自己,坚持自己的选择,坚持进步。

    [回复]

    Comment | 2014 年 05 月 26 日
  • hzren

    关于String,length(),这是一个坑,在不同的字符集下,每个字符的长度是不一样的,就算是一个字符集下,每个字符的字节长度也可能是不一样的,所以length()方法返回的长度肯定是小于等于真实的字节数组的长度,前一段时间再找如何避免创建对象就能计算出一个String 字节数组长度的方法,可惜没找到,找到了希望能告诉下

    [回复]

    Hesey Wang 回复:

    很多人关心这个问题,觉得是个「坑」。不过是不是坑,是要看场景的。如果我要拿精确的长度,当然不能这么搞,不过首先,文本本身是HTML,中文只占一小部分,ASCII字符又通常都只占1个字节,所以受Charset影响不大。

    这个地方其实是判断字符长度超过阈值后就打一行日志统计用,阈值是MB级别,差几个字节,对我来说没有什么影响。

    但使用getBytes()的问题在于,如果这个String占了1GB,我再引发额外的拷贝,那么FullGC就很难避免了,事实也是如此。

    [回复]

    Comment | 2014 年 05 月 27 日
  • 有个问题没有看明白, 你提到
    “某个调用场景下,每次都会新建一个解析器对象去解析结果,尽管解析器没有任何实例变量不会产生线程安全问题,创建的开销也并不大,但我还是坚持要改成单例,使用同一个实例去处理,这也符合面向GC编程的思想。”

    从你提到的 “面向GC编程的思想” 里, 建议的是:
    1. 分配小对象的开销非常小,不要吝啬去创建。
    2. GC最喜欢这种小而短命的对象。
    3. 让对象的生命周期尽可能短,例如在方法体内创建,使其能尽快地在YoungGC中被回收,不会晋升(romote)到年老代(Old Generation)。

    我的问题是, 因为”创建的开销也并不大”, 所以应该使用局部变量, 这样可以在YoungGC中被回收.
    但如果使用单例, 那么对象就会被放到Old Generation, 那为什么你觉得使用单例是符合”面向GC编程”呢?

    [回复]

    Hesey Wang 回复:

    Old Generation并不是魔鬼,如果确实是需要long-live的对象没什么问题,GC那篇文里不建议的是为了对所谓的「内存优化」把小对象做无谓的Cache。

    这个场景下其实本来很简单,把这个对象配成一个Spring Bean注入另一个Bean即可,这样单例似乎就没那么刻意?主要是这个地方的代码因为历史原因没法这么搞,所以只能自己做一个单例了,因为没「必要」每次都创建。这事儿有点微妙,因为每个developer对是否有必要的看法都不同……

    [回复]

    Comment | 2014 年 06 月 06 日
  • […] (转载自 舒の随想日记 ,未用于任何商业用途) […]

    Pingback | 2014 年 06 月 16 日
  • […] (感谢网友 @Hesey小纯纯 投稿  博客 | 原文链接) […]

    Pingback | 2014 年 06 月 21 日
  • Yocus

    些的真好。

    [回复]

    Comment | 2014 年 07 月 10 日
  • 心远

    说的太好了。感觉我们已经难以望其项背了,呵呵。

    [回复]

    Comment | 2014 年 07 月 19 日
  • xxx

    就目前的情况来说做到认真无须多大功夫,就像老罗数落各大手机厂商一样,其实稍微下点功夫事情的结果已经不一样了。
    ^_^ 不过我发现这样说的基础还是在考虑别人是怎么看的

    [回复]

    Comment | 2014 年 07 月 21 日
  • […] 原文: http://blog.hesey.net […]

    Pingback | 2014 年 08 月 06 日
  • […] (感谢网友 @Hesey小纯纯 投稿  博客 | 原文链接) […]

    Pingback | 2016 年 05 月 03 日

RSS feed for comments on this post. TrackBack URL

Leave a comment

©2006 - 2016 Hesey (舒)