反 996 有理:催程序员交代码,写不出好软件( 二 )


错乱的金额客户报告间歇性转账金额非常大 。转账本应是 1~2 美元,但结果却超过了 2 万美元!
迫于时间压力下完成的代码
//Code was ported from single //threaded embedded device to //multi-threaded env //ToBcd is being called from //multiple threads! unsigned int gTemp; int gShift; unsigned int ToBcd( unsigned short amount) { gTemp = 0; gShift = 0; while(amount > 0) { gTemp |= (amount%10) << (gShift++<<2); amount /=10; } return gTemp; } 精心编写的代码
//during Representative Load //testing - no more //unnecessary globals! unsigned int ToBcd(unsigned short amount) {unsigned int gTemp = 0;unsigned int gShift = 0;while(amount > 0) {gTemp |= (amount%10)<< (gShift++<<2);amount /=10;}return gTemp; } 评点 :你有没有听过这样的说法,将现有代码移植到新平台应该很容易,只需简单地重新编译和部署即可?组织向工程师施压,迫使他们走捷径,例如将深度嵌入的代码移植到新的平台和编码范式,而在日程安排中却没有列入用 典型负载来追捕意外混乱的计划?
不稳定的依赖项后端出现间歇性的崩溃,导致事务取消和时间损失 。
迫于时间压力下完成的代码
lib3rdPartyUnstable.doSomethingGood() 精心编写的代码
lib3rdParty.doSomethingGood() 评点 :如果你是在任意的时间压力之下,你觉得有多大可能确保方案在负载下保持稳定?你是否应该牺牲你的周末时间去做公司可能会抱怨的工作,因为他们只是认为你这是在拖延交付日期?在任意时间压力下,工程师更有可能跳过或通过快乐路径进行负载和性能测试,而这些测试正是发现未知混乱根源所需的,比如上面那个第三方依赖项,就需要更换或升级 。
竞争危害最高出价有时会显示出疯狂的巨量金额 。
迫于时间压力下完成的代码
void setHighestBid(long bidCents) { if (bidCents > highestBid) { highestBid = bidCents } } 精心编写的代码
/*Note: This needed to be synchronised to avoid corrupting max bid*/ synchronized void setHighestBid( long bidCents) { if (bidCents > highestBid) { highestBid = bidCents } } 评点 :你是否有过这样的经历:你的软件快速通过了 QA 测试,但在进入生产环境时就崩溃了?捕获竞争危害的一个好方法是在典型负载下运行软件,同时构建并分析指示软件健康状况的指标 。但这听起来像是一个以时间压力为导向的组织想要的东西吗?以我的经验来看,不是这样的!
性能不佳一天结束的工作流程需要几个小时才能完成,而实际上,它们最多只需几分钟即可 。
迫于时间压力下完成的代码
背景: 在整个后端代码中,应用了一种重复的架构模式,在该模式中,对象将持久化,并每次从数据库中获取一个子对象 。这将会导致响应时间非常慢,但如果负载很轻的话,效果尚可 。
/*Person object has several dirty sub-objects that are persisted one-by-one*/ person.persist(); 精心编写的代码
/*Note:Persist framework function refactored to batch SQL updates*/ person.persist(); 评点 :当你对项目的架构提出质疑时,有没有被人“嘘”过?如果你推送复杂测试呢?负载测试是众所周知的软件项目按时交付的祸根,因为它往往会使像上面例子一样的架构问题暴露出来 。如果团队有足够的压力来满足这个截止日期,他们就会很高兴地进行负载测试,并将其交付,而客户将会发现软件的性能问题 。然而,许多组织在进行负载测试时,并没有健康度量的指标,以使客户满意负载测试的执行情况 。而如果没有度量指标显示一定负载下暴露出的不良行为,那么软件通常会顺利地通过,即使软件在经常被忽略的诊断日志中出现了大量有关问题的信息 。
支付处理逻辑人们有时不付款就把产品买到手里,这简直是客服的噩梦!
迫于时间压力下完成的代码
//todo check for errors database.recordPurchase() paymentGateway.startPayment() paymentGateway.completePayment() 精心编写的代码
【反 996 有理:催程序员交代码,写不出好软件】database.startPurchase() try { paymentGateway.startPayment() } catch(Exception e) { log.error(e) database.recordError() return FailedStartPayment(e) } try { paymentGateway.completePayment() } catch(Exception e) { altPayLog.recordError() log.error(e) database.recordPError() return FailedCompletePayment(e) 评点 :你是否曾经在处理复杂的错误情况时被经理打断,问你能否按时交付?这种时间压力是否激励你进行一些出色的错误处理?时间压力往往会让人们不再考虑软件失败时会发生什么情况;只愿意在快乐路径上进行编码 。换句话说,错误处理被抛在一边,只顾满足周五的检查截止日期 。


推荐阅读