美文网首页程序猿Android开发感悟大牛聚集之地
不要相信程序员在加班时间写的代码

不要相信程序员在加班时间写的代码

作者: 匿蟒 | 来源:发表于2016-05-14 13:56 被阅读17097次

    作为一个最底层的程序员,我先记录一些只有底层程序员才会知道的事情。如果多年后,我违背自己进入这个行业的初心,走上管理岗位,也能回想起一些禁忌,避免一些错误。

    其中最重要的就是这条:不要相信一个程序员在加班时间写出来的代码

    (软件工程的学说表明,连正常时间好好写的代码,也不要太相信。不过这不是本文的重点,略过不提。)

    (不懂代码的人,看到本文中的Java代码可以略过,不影响理解。)

    创造力的时限

    写代码,与写文章、绘画、思考复杂问题,并没有本质上的区别,都是创造性的活动。

    每个人的创造力,都会随着身体状态而波动。广为人知的是,一个人年老体衰后,相比年富力强时,创造力会急剧下降。其实,人每天的状态起伏,也同样会剧烈影响这一点。

    如果是拧螺丝,那么在精疲力尽、拧不动以前,身体状态对结果不会产生太大影响。因为拧螺丝的指标非常简单——拧紧,要做的事也非常机械化——拧,直到它紧,换下一个。

    但如果是写代码,有些事,是不能在状态不好的时候完成的。

    比如,在Java里,遍历一个外部的List,做一些处理。如果状态不佳、做事前想的东西少了点,那么很可能直接这么做:

        public void handleAList(List<Integer> aList) {
            for (int i = 0; i < aList.size(); ++i) {
                // Do sth with List#get(int)
            }
        }
    

    这样做是从C/C++带来的一种很直观的做法。有什么问题吗?

    假如外面传入的aList是一个ArrayList,那么List.get(int)的时间复杂度是O(1),算上外面那重循环则是O(n);而假如aList是一个LinkedList,那么List.get(int)的时间复杂度是O(n),算上外面那重循环则是O(n2)!

    (为不懂算法时间复杂度评估的人解释下:在这个场景下,O(n)代表最优、最快,而O(n2)代表不可接受地慢。)

    如果时间充分,那么可以去查看handleAList()的调用位置,看看它传递的是哪种List;而如果思考得够充分,考虑到这两种情况都有可能,那么代码就会做兼容处理,改成这样:

        public void handleAList(List<Integer> aList) {
            for (int i : aList) {
                // Do sth with i
            }
        }
    

    这使用了for-each语法,实际上是用Iterator来做遍历,无论对哪种List都是总共是O(n)的开销。

    注意,这通常不被看做一个bug,普通的黑盒与白盒测试都是无法发现的。只是你的App会比较卡,或者后台会比较慢。当需要解决这种性能问题时,可能需要非常经验丰富的程序员,在海量代码里找数周时间——而这一切,在开发之初,只要那个程序员状态好一点,就可以避免。

    一个人,每天的创造力是有时限的。在时限外,他不再是一个优秀的创造者,而是一个笨蛋。

    (为了便于理解,这个例子非常简单,以至于不够贴切。对Java来说,优先使用for-each或Iterator来遍历,已经是一个共识,是技术素养的一部分。)

    失误率的飙升

    程序员在写代码的过程中,每天做得最多的应该就是等价变换。

        if (isSthTrue()) {
            // Take some actions.
        }
    

    变换成

        if (!isSthTrue()) return;
    
        // Take some actions.
    

    这只是最简单的一种逻辑反转,实际上还有更多、更复杂的形式。通过这类变化,对代码做出调整后,程序员可以把代码变得更好,或者做到以前不能做的事。

    而在加班时间、大脑不那么清醒的情况下,很可能会写成这样:

        if (isSthTrue()) return;
    
        // Take some actions.
    

    区别仅仅只是少了一个符号,而意义则完全走样。

    这个例子比较简单,出错后也很容易在调试过程中发现、纠正。但是,请不要怀疑,的确会有程序员为了这么个简单的问题,调试整整一个晚上!

    (!i,(字体未配置好时)本就难以区分,眼睛疲劳昏花时,在数百个字符里扫来扫去,难以分辨(!i中是否少了个符号,也并不奇怪。而如果换成第二天早晨,很可能只需要瞥一眼。

    大多数管理者,往往会对熬夜的程序员给出一些肯定,并且允许第二天可以休息一天(有些甚至只给一早上)。但如果他们知道内情,会发现自己其实亏了一天。如果程序员正常下班,第二天花一小时解决这个问题,剩下的七个小时可以继续开发。

    还有很多比这复杂得多的变换,或其它类型的代码改动,即使在大脑清醒的情况下也需要花费一些时间,认真思考、小心调试。而如果来了一个问题,你说“必须要今天下班前搞定”,那么程序员会很烦躁,并且越来越烦躁。

    烦躁的后果

    一件需要冷静思考、谋定后动的事,如果逼迫人们在烦躁的情况下去做,那么往往会得到意想不到的糟糕结果。

    我有一位前同事,技术实力且不论,心性也不太稳(实际上,像我这种少年老成、未老先衰、找不到妹子都不急的青年,还真不多)。他是一个可以解决问题的人,但是在烦躁的情况下,也经常做出令我瞠目结舌的事。

    比如,有一天,项目组要求某个bug必须解决。他搞到晚上9点还没搞定,找我帮忙。我当时水平也很差,不然也不会那时还在加班,没能帮他解决,只是因此而知道这件事。他后来在10点半时采用了一个规避方案,然后下班了事。

    具体一点是这样的:在一个class中,有多个地方调用同一个Method。其它地方没有问题,唯独某个位置的结果不正确。他改成这样:

        private boolean isSthTrue(int sth) {
            // Implementation A
        }
    
        private boolean isSth1True() {
            // Implementation B
        }
    
        private boolean isSth2True() {
            // Implementation C
        }
    

    本来isSthTrue()是可以做通用判断的,他没有在规定时间内找到根本原因(Root Cause),实际上当时他也根本没有往发现根本原因的方向去查找代码,而是一晚上都在做一些无效的调试。最后没办法调试出好的结果,于是给出问题的地方一个特殊处理——新增了isSth1True()isSth2True()去那个出错的地方顶替。结果,那个bug的确是解决了,但是后来带出来了另外一个bug。

    不过他也达到了目的,当天下班了。

    而后来,我在代码里发现了另外一组更早就有的接口。

        private boolean isTrueSth1() {
            // Implemented like B
        }
    
        private boolean isTrueSth2() {
            // Implemented like C
        }
    

    我问了一下这两个Method的作者(另一位同事),他根本没有看到有isSthTrue()

    这件事的最终结果是,解决了一个bug,后来又引起了多个bug,连我也跟着一起焦头烂额。

    不解决问题地debug

    借着这个例子,回头再说一下创造力的时限

    这位同事,之所以不去找Root Cause,是因为项目组的催逼和自身的烦躁,他平时是可以解决问题的。但是为什么一个简单问题会这么难解决,为什么代码里之前就有一套他要的Method,他却新写一个?

    外部代码环境就不说了,这个class共有2000行。2000行可能并不是特别直观的数目,既不能说多,也不能说少,取决于这个class干什么事。

    后来,另一个比较老道的同事,重构(refactor)了这个class,只用了不到500行——这就说明了一个问题,这个class之前就太过冗余。

    约半年后,我水平也提高了些,总体的项目时间也松散了些,我花了六周重写(rewrite)了这个不大的代码库。这个class最终只用了100行,部分功能都独立封装到了其它class中。

    如果之前,在这个代码库写就之初,就能有一个充分的时间做一个好的架构设计,不需要rewrite就可以只有100行;而如果时间不太充分,却能给应有的时间好好写,也起码能有refactor后的水平,也就是500行。无论是100行,还是500行,后面出的一大堆问题,都不会出现,或者更容易解决。

    这个代码库是怎么来的?

    当初某领导,交给了一个比较厉害的同事,只给一周时间。这位同事加班加点,一周当成两周用,从别的代码里剥离、拼凑出来了一个编译能通过的东西——这就是交给我们维护的代码库。

    来自项目最底层的复仇

    前面说的,无论是写出隐蔽的bug,还是解决一个带出俩,其实都是这类事情的阳光面。你没看错,这是阳光的一面。

    还有我不想多说的阴暗面。

    前面说的事情,没有一类是故意的。无论出事的原因是程序员的技术素养不足、加班情况下大失水准、还是原先的代码就非常容易诱导失误,都是程序员在认真努力的情况下,不可自控地犯错。

    还有一类是故意的。

    比如,去年(2015)携程那小哥儿,就是怒删数据库。当然,他不是为了加班严重而如何如何,而是心爱的运营妹子被公司某高层给……(另有一说,虽然有什么内部的QQ、微信截图,但这仍然是谣言,实际上是黑客攻击。)

    什么程度的压迫,就会得到什么程度的反抗。

    要知道,即使是很努力地去做,也仍然可以出各种问题。而如果要故意捣乱,很多手段,虽然不会引起老板的注意,甚至可以不被认真的代码审查者(reviewer)警觉,但是会客观地影响产品的品质,让用户讨厌一个产品,或者让一个爆款产品最终失败。

    反正埋了雷,领了工资,跳下一家便是——要么给股票、期权,要么充分洗脑,或至少给出足够的加班费(几年后的医疗费),否则就是这个后果。

    我只能说,就我个人而言,最多辞职,不会故意乱搞。这关乎职业道德,关乎我是否意念通达、心境澄明。(坐等穿越去修真:P)

    但是,我不能用自己的道德准绳去要求别人,对吧?

    而且,永远不要指望一个人在承受不道德的对待时,仍然能谨守原来的道德。

    结语

    作为一个软件项目的领导者,你在要求某个程序员加班时,其实就已经在冒险;而如果你经常这么干,不要奇怪为什么项目总是延期,或者一到关键时候,总有突发事件。

    只要试验次数够多,可能性再小的事也会发生;而只要试验次数更多,小概率事件也会连续发生。

    所以,最理智、客观的观念就是:欲速则不达,不要相信一个程序员在加班时间写的代码

    相关文章

      网友评论

      • decab38dd89e:很多时候我只相信他们在加班时间怼出来的代码。上班时间?不知道他们在神游什么?很多程序员也表示不到加班根本无法有效生产代码,太多的干扰和打断,不如给我安安静静的三小时
      • 鱼笨自由:赞一个:+1:
        真正厉害的程序员,从不屑于加班。
        例如我,我就相信,每天遇到的问题,第二天早上通常能直接搞定。
        或者,直接在更加清醒的时候去研究问题。
        往往,不够清醒时,两天也抵不过,清醒时的一个小时。
      • H_Cynic:嗯 看完很有觉悟 赶紧埋两颗手雷去 以后再叫我加班 引爆手雷:joy:
      • 終點起點:越加班效率 越低,我这样说,不知道你们能懂不能
      • 张砷镓:单元测试和code review做好的话,就没有问题。关键还是要看程序猿本身有没有对代码质量的信仰,是不是仅仅以完成任务为目标。

        最后,除了修复线上bug和争分夺秒的需求,需要加班说明工期估算有问题,leader难辞其咎。
      • ff3bf66b7e0b:其实主要是加班与收益不对等,才会使人产生文中的思想。为什么很多管理层白天忙,晚上还猛的干活(不见得干别的活比写代码简单;或者干活也包含代码维护审查;反正我宁可写代码,不愿意去应酬),因为看得到收益。我建议想往上走的程序员,千万不要怀着这种程序员的小农思想被做一辈子的底层程序员。
        匿蟒:@ff3bf66b7e0b 加班与收益,的确是大多数人的考虑,不过不是本文强调的重点。本文强调的是工作产物的质量不足,会反过来影响效率。

        从收益上讲,现在的程序员加班大体有两种:
        1. 无偿加班。
        2. 加班费或股票、期权。
        对很多创业公司来说,活下来就是人生赢家,死了就连工资也没了。如果员工愿意拼死干活,这也是你情我愿的。而对于第1种又如何呢?

        我见过加了七八年班,仍然与应届毕业生干类似工作的底层程序员;也见过和他同期的老同事,职位是他leader的leader。说到底,晋升与努力有关、与天赋有关、与学历有关、与工作效率有关、与不可替代性有关,唯独与加班无关。公司只会因为某个人能带领好一个团队而晋升他为leader,而不会考虑他的加班情况如何。只论功劳,不看苦劳。

        955的时间,干完别人996的活,这样的程序员才是更优秀的;带着不加班的程序员,按时完成项目,这样的领导者才是更适合晋升的。
      • a19467d0b1b8:刚刚开始工作,不喜欢加班,因为加班会让我感到内心的焦躁不安,没有心情Code。 :unamused:
      • ys尘笑:只想找个靠谱的老板
      • lohol:看了两眼就知道你不是C++程序员...
      • 炎藤:我发现腾讯官网有这篇文章转发了,不知道各大公司加班情况又是怎么样呢?听说其实大公司也都在加班的...
      • GodOfBug:for each 对LinkedList 访问的确加快了 :smile: Iterator缓存了next不用每次循环而get需要
      • 天堂鸟clz:加班没效率是肯定的,但有些公司是习惯了加班,不加班不行,除非离职换工。经常加班,也会导致原先2个小时的工作量,可能得花1天甚至更长时间去做。
      • 0f3ff55db503:千里马常有,而伯乐不常在。
      • 未有期希:赞同,我想该休息了 :smile:
        tomorrow ,hello
      • 苏易川:以我看,程序员不应该有上班时间,因为上班时间这个概念本身就意味着没有效率!有的人就是喜欢在大半夜写代码,而且效率极高,但是在上班时间却很没有效率!
      • 苏易川:以我看,程序员不应该有上班时间,因为上班时间这个概念本身就意味着没有效率!有的人就是喜欢在大半夜写代码,而且效率极高,但是在上班时间却很没有效率!
      • 工程师milter:所有互联网公司的头头都应当认真读三遍!
      • zhanghengiOS:可是开发写出东西来了,qa也不是马上能测出来的,测出来的时候就是要发版或者要下班的时候蛋疼
      • 3040c2ad6f16:申请转载~
        3040c2ad6f16:@匿蟒 您是否方便添加我的微信swkafh,完善一下作者简介的内容?
        3040c2ad6f16:@匿蟒 感谢
        匿蟒: @傲风寒swk 可以
      • 龙翔云际:其实个人觉得对于层次比较高的工程师不但不应该加班,最好连上班的时间都不要控制,一个水平高的程序员只要约定好工期他一定能完活,加班有时候只会降低效率
        匿蟒:@龙翔云际 据我所知,Google这类公司就是这样的。
        不过可惜的是:1、大多数公司达不到这样的水平;2、大多数程序员也达不到这样的水平。
        ╮(╯_╰)╭
      • 柴泽建_Jack:理是这个理,但是领导总是会把一个人待在公司的时间,等价为他工作的时间。
      • 雪吖头:说的非常有道理
      • 1f7bd0bfb56e:欲速则不达
      • ab66fc044653:跟接地气
      • 帅气小伙:卧槽,居然有这么明智的领导者
      • WolfXu:加班纯粹浪费时间,不给钱的加班尤其是!
      • bigCatloveFish:其实 合理的工期 合理的review 是非常重要的
      • 67139ffd76d7:对啊,熬夜写的代码白天就删掉了
      • gogo_coder:深有体会
      • 231586b20784:领导才不管呢
      • 12130f301648:前者,每天工作8小时,上班时间本分工作,朝九晚五;
        后者,早上10点前没见人,上班时间吊儿郎当,晚上加班不知道在干嘛到9点;
        绩效评定,后者工作努力,任劳任怨,表现突出。
        升职加薪。
        唉。。
      • Twenty_:加班确实是一件比较蛋疼的事情。。
      • be8218fb001c:骗自己吧 项目周期短 不加班怎么搞
        WolfXu:@匿蟒 太对了,赶时间的结果就是花几倍的时间改bug
        匿蟒:@陈家崽里 周期短的项目,要么实际开发内容不多,要么一定做不好。大项目给短周期,才是自己骗自己。

        如我文中提过的例子,一个总共5000到10000行的Project,那位领导只给一周,结果就是bug解了半年还没完。
      • 搭车游戏:虽然不是你们这一行的,但也是技术工程师。我想说作者说的太对了,加班写出来的东西,有时候心烦意乱时间又紧张就会在别人不留意但是又得费一番功夫的地方偷偷放水。
      • 齐刘海姑娘:哈喽~您的文章已收录专题“ 我不是程序猿,请叫我攻城狮”http://www.jianshu.com/collection/db91065b98c6,欢迎关注投稿哦~ :kissing_heart: :heart: :heart:
      • 爱喝营养快线:感觉早上思路清晰,晚上写了一天头昏脑胀,不过有的正好相反
      • 印佐:个人怎么觉得,晚上写代码更顺畅,白天屁事太多,都不能静心写。
        印佐:@匿蟒 不合适,早晚颠倒,长期下去,身体会受不了。
        匿蟒:@小盼子 很多人在长期的奇怪作息下,已经把兴奋点调整到了晚上。
        可是,整个白天都困顿、疲累,一到晚上就精神抖擞地开始工作,真的合适的吗?
      • ea0edfd8a561:这事还得看人
      • 6583f8b9eaf8: :flushed: 不是因为需求变更么?
      • b08dfdea3033:话说我怎么觉得下班了才真正进入状态,乱起八糟的人跑光了才能专心写代码。
        b08dfdea3033:@匿蟒 事实上除了研发类职位和实习生,程序员的工作是不可能不被打断的,如果说通过文档、调整开发顺序来降低沟通时间,必然会增加迭代周期
        匿蟒:@HalfmanG2 一个好的团队,不应该给程序员一些乱七八糟的事,打断写代码的过程。
        现在通常把一线程序员,当成代码生成器、技术方案提供者、技术顾问、沟通环节之一、相邻耦合模块的技术支持、技术文档作者、电脑维修员……要在白天写代码,就要拒绝被打断。
      • 4a4d96373b3b:加班写的代码确实会容易出大问题。深有体会。公司上层白天尽不干正事,就是开会。刚要静心写了,就过来要改个东西,或者去开会,或者尼玛市场的过来问问题。。一天根本没多少连贯时间做事。。一快下班那边就开完会了,就开始分配紧急任务了。。只能加班
        終點起點:越加班效率 越低,一身的怨气。 没事 也得坐下 装一会儿,也是老板想看到的。要不然开会旁敲侧击 说某某某怎么怎么。这是一种病态
        匿蟒:@jasonone 这样的工作流显然有问题,但很遗憾,这是现在的主流。

        总不能让领导们加班开会,第二天早上告诉你结果吧?
        至于项目问题多、代码质量差——代码又不是领导写的,当然是码农的锅。

        大环境如此,我的建议是尽量尝试改变环境,否则就只出应有的力,保持身体健康、心情愉快。
      • 妮可米唯:写得很风趣,然而也贴切
      • 陆大胖:笔者可有破解之道~
      • 痕迹Dev:加班写出来的不是代码,是Bug。
      • 王仁兴:写的不错,明天继续加班
      • 鹅鹅鹅鹅鹅鹅:加班这个事情,老板至少要占百分之八十的责任,至于剩下的百分之二十,属于各种不可抗因素,例如各类突发事件。但是人的精力确实有限,疲劳战早就被确认是无效的,但还是有很多老板热衷于加班这个事,好像把人留下来加班,看见办公室里人头攒动能代表多么美好的前景似得“看,大家多么热火朝天!”无非是被这种假象给感动了而已╮(╯_╰)╭
        匿蟒:@rancec 我乐观些。
        大环境难改,但小环境却容易创造。只要有个挡需求、扛责任、懂规划、教手下的好leader,再跟上合格的招聘,很快就能建立一个不加班的高效团队。
        现在的很多leader其实只是年龄够大,技术水平却很低。他们还不明白,或早已忘了:贪婪(Greedy)算法虽然通常能有个不错的结果,却往往不是最好的结果。
        02ac1053db6f:这就好比中国式的GDP增长:挖路修路,永不停歇。不同的是,有的有意预留操作空间,有的是无知的不作死就不会死。
        要是想创造程序员梦想的“Google”(也有无厘头的项目和内部争斗)那一类纯粹技术领先型的公司或者机构,我们这一辈的努力可能还不够的,要多加油了;

        希望国内大环境会越来越好
        匿蟒:@鹅鹅鹅鹅鹅鹅 我之前待过一个团队,加班为整层楼之最。然而,出bug最多,block项目最多,得表扬最多……
      • 东风壹号:加班只能说明第一老板没有分配好工作任务,第二程序员能力不足!
      • 56362a9605fa:coder在公司里很多时候处于食物链的底部, 上面是QA, architet, PM。。。blahblah, that's why everyone fucks coder
      • b9a860a4d173:不是每个经理都是这么想的!
        凌冬不凋:@匿蟒 从很多程序猿的角度看,很多经理都是傻叉,而事实上,确实是。
        炎藤:我不想点击喜欢,只想说赞
        匿蟒:@oviovi 其实,现在每个经理都不是这么想的。
        他们通常喜欢说:团队执行力……
      • voidsky_很有趣儿:所以。别让程序猿加班了!所有管理者都看看
      • 专坑心手:跟我的看法一样,八小时内能高效工作就不错了,加班真没多少用。
      • 我在睡觉:写的很好。过去我也经常被加班,还好没有干过什么蠢事
      • FQ炒蛋:创造力有时限!
      • c401111ff892:删除rm全部/
        a19467d0b1b8:从删库到跑路
        xiasuhuei321:@rancec ……够狠
        02ac1053db6f:@c401111ff892 rm还不够,重要的是狠心写段脚本,不断rm+cp覆盖,这样不久服务器硬盘必挂无疑,而且就算你想找实验室restore数据也不可能了。如此一来,才喜感十足……
      • 5a3c5b6ebe74:写的很赞,希望这一阶段学习过后,找工作能遇到有这种理念的boss

      本文标题:不要相信程序员在加班时间写的代码

      本文链接:https://www.haomeiwen.com/subject/pgtskttx.html