Skip to content

四火的唠叨

一个纯正程序员的啰嗦

Menu
  • 所有文章
  • About Me
  • 关于四火
  • 旅行映像
  • 独立游戏
  • 资源链接
Menu

扒一扒知乎上的帖子——“为什么有些大公司技术弱爆了?”

Posted on 12/11/201510/02/2024 by 四火

helpless

知乎上看到一个热帖,我觉得很有意思,叫做 “为什么有些大公司技术弱爆了?”。我刚看到标题的时候,先入为主和刻板偏见了一下,正如同第一个回答一样,我皱了皱眉头,产生了对题主的鄙视之情;但是很快,读完帖子以后,我却立场明确地站到题主一边了。正如同里面有位回答:

看题目以为是题主傻逼,看了正文发现真的是公司傻逼。

上面这种情况其实发生的概率挺低的,但是我觉得这回是真的发生了。

但是令我感到遗憾的是,各式各样的回答里面,大部分居然都跳出来 “教育” 题主,表态这个世界就不是完美的,表态要妥协要接受这样的事实,要无奈地咽下这个现实的苦果。这个大面积出现的观点,太不正常了吧?

比如这样的话:

写好代码是程序员的节操。抱歉,节操多少钱一斤,北京三环商品房多少钱一平?

有的问题实在不是能够三言两语回答的,尤其是当面对整个行业的现实的时候,但是,可以很明确的是,当一个项目代码写烂掉的时候,这个项目也活不久了。

好吧,还是就事论事,下面就贴过来,然后逐一分析其中的内容。说说为什么大致上题主没问题,有问题的是这家公司,这个项目组。

=================================

今年年初,到一家互联网公司实习,该公司是国内行业龙头。

不过技术和管理方面,却弱爆了。

那里的程序员,每天都在看邮件,查问题工单。
这些问题,多半是他们设计不当,造成的。

>> 这就是所谓的 operation 的工作,大多情况下很无趣。这通常也意味着系统复杂,负载高,问题不容易轻易定位和解决,往往是历史遗留下来的大型系统。这并不奇怪,就像外人见到风光的 AWS 一样,之后内部的工程师才知道其中有多少维护性的工作,压力有多巨大。我记得不久前,看过一个 principal talk,讲 oncall 的折磨使他成长,我想说法不假,只是很遗憾我还到不了这个层次。题主能看到问题多半出自设计不当,不错。而问题居然多半是因为设计不当,这个工程的初始架构人员 ,以及后来架构看护的骨干工程师,是要挨批评的。对于一个 “国内行业龙头”,这样的事情是不该发生的。

代码写的一团糟,全是复制粘贴,连作者都没改,大家普遍不写注释,也不格式化,代码歪歪扭扭。

>> 这又是一件不该发生的事情。对于代码质量的追求各有说法,但是 “复制粘贴”、“作者都没改”、“不写注释”、“不格式化” 等等这样的字眼,我不相信一般的 “龙头” 公司能够接受。这些东西就像饭要一口一口吃一样,纵然有再大的野心,这些最最基本的细节,始终是不能忽略的。我觉得公司在招人的时候,既然是双向选择,就可以互亮代码,这样的代码摆出来看到以后,大家就不用浪费时间了。

一个项目里,httpclient 竟然出现了四种。
一种是该公司研发部写的,
一种是老版本的开源项目,
一种是新版本的开源项目,
还有一种是开发人员造的轮子。

>> 最理想的情况当然是统一成一种。遇到这样多种实现,并且有自造轮子的情况,很多都是源于 “历史原因”。当然,都能看到代码简单地 “复制粘贴” 了,不看以往代码实现,按照自己的理解来写也就并不奇怪了。当然,我可以接受因为某某特殊原因而导致一个 httpclient 有多于一种的实现方式(我在这里还写过造轮子的好处),但是居然有四种之多,我觉得凶多吉少了。

打接口请求响应日志,竟然不知道用拦截器。
打错误日志竟然不打上下文信息,每个人一种日志风格,千奇百怪。
许多重要的中间流程,居然不打日志。

>> 拦截器是个好东西,简化代码,避免啰嗦的日志影响业务逻辑的阅读。当然也有不好的地方,比如不直观、不好调试,以及有时候可能发生的性能问题等等。因此这个也不强求,根据项目实际情况而定。日志风格千奇百怪的问题,多是由于缺乏项目内部的管理造成的,各就各业,缺少沟通。开发人员不怎么样不说,这个项目经理更是弱爆了。重要流程不打日志,这一条只能帮助证明这群开发人员的工程意识还欠缺。

idea、eclipse、myeclipse 的配置文件竟然全部传到项目里去了。

>> IDE 用的不一样没事儿,但是这些 IDE 的配置文件也传上去了?这样的低级问题都出现……难道代码不用 review 么?

该公司混了两年的程序员,跟快递公司做查询接口,竟然不知道加密运单号。

>> 这样的信息是否要加密通常取决于调用两边的协议是怎么规定的,但是凡是涉及到隐私等等重要信息,都需要加密以减少信息泄露的风险。

所有服务间通讯,都没有设 requestId,导致跟踪会话很困难。

>> 如果只是牵涉到服务之间的通讯,而通讯又只是简单的查询的话,没有 requestId 我觉得是可以接受的。至于会话的跟踪,如果这里指的是整个系统在一个 request 到达和处理的过程中,能够跟踪全部的或者重要的行为,比如调用了哪些接口,得到了哪些结果,做了哪些操作等等,这个功能确实是很有必要的,但是这个跟踪是可以在服务间通讯没有 requestId 做到的。比如在主系统中使用一个线程变量,在每次打印这些信息的时候把线程变量放置在前面,后续的日志分析工具就可以捕捉到这次会话交互的所有日志。

一个没什么 qps 的边缘接口,居然做消费者生产者+阻塞队列的异步模式。
显得你技术少是不是。
不知道异步会增加维护成本,提高测试难度吗?
而且,任务队里没有考虑持久化,赶上发布,丢了好多任务。

>> 没什么 qps 的边缘接口,做成这样的异步模式,看起来是有点杀鸡用牛刀了。但是这个事情要结合背景去分析,比如有可能是为了未来的扩展需要,有的接口可以预见到请求量会大幅增加。当然,结合整个上下文来看,我更倾向于是这个项目组疏于管理,然后来了一个自恃牛逼的 “大拿”,整了一套高大上唬住大伙儿;或者是一个很想在项目中尝试新东西的小哥,就拿这东西练手了。至于任务队里没有持久化这个一条,依然要看具体的问题,不过通常情况下,如果要设计一个通用的任务队列,持久化是一个必选项。当然话也不能说死,你是要搞完全不在乎任务丢失的,或者任务调度者可以不断地重试那些挂掉的任务,于是你不在乎他们丢失的问题——不过想想好像这样的 case 挺少的。

读取一个小小的 xml 和 exc 配置文件,居然用流式解析,没见过这么二逼的,真是醉了。

>> 这和上面那个杀鸡用牛刀是同一个问题,已经阐述过了。

做优化全靠拍脑门拍大腿,难道不会用 excel 分析日志,用 jprofile 扫项目?
一个 100 以内的常数集合遍历,他也要写个优化算法进去,算法跟业务还搅在一起,一团乱麻。
每个人都在嚷嚷性能、算法、分布式计算……

>> 看起来这里指的是性能方面的优化,那么做优化至少包括两部分,一部分是在设计阶段就要分析需求层面的数据推出要 “优化” 到什么程度,另一部分才是题主说的根据日志和已有项目运行的数据 “反推 ”(几年前写过一点这方面的东西)。当然,无论哪个,都比拍脑门和拍大腿靠谱得多。至于 100 以内常数集合遍历,也要写优化算法,这有时未必是件坏事,比如大家都在遵循最佳实践,不过结合上下文看(包括 “算法和业务搅在一起”),我更倾向于是属于前面已经阐述过的问题。就这种状况下,每个人都还嚷嚷 “性能、算法、分布式计算” 就显得有点没抓到主要矛盾了,主要矛盾应该是把这些代码最基本的问题给解决了。我记得小时候练习书法的时候,老师批评过我:先不要尝试那些技巧,先把最基本的横平竖直给练好了。

几乎没有文档,全靠从代码反推逻辑。

>> 代码和文档经常是对立面,这样的状况并不稀奇。我觉得比较可行的做法是,有概要的文档,但是详细文档往往不现实,即使写了也难免过时。公司内部的文档太多太多是一坨浆糊。

有枚举他不用,非要在每个页面上,把枚举值挨个儿写死,知道后面改代码多么费劲吗?

>> 欠缺基本的程序员素质。

欺骗性的变量名,里面存储的是 AES 加密的,变量名后缀却写成了 DES;里面存的是小写字母,却写成 upperStr。
一个方法十几个参数,有三分之一是极其简略的缩写,注释肯定也没有的。
一个类写到三四千行是常事。

>> 看到这里我已经产生无力吐槽的感觉了。

开发自测,居然要把代码全丢到公共机器上,而且都是走 svn,他们把 svn 当 ftp 用。
svn 里面大量的无意义提交,一多半的提交连都编译不过去。
我看到有个应届生,改了两句话,马上提交,说是怕代码丢失。

>> 自测走 svn 其实不稀奇。就像自己开发一个新功能在 git 下可以 cut 一个新的 branch,然后开发了,提交了,部署到各种机器上去。不过当 ftp 用显然是不对的。“一半多编译不过去的提交”,这个项目没有项目管理吗?开发机上不单元测试吗?至于 “改了两句话,马上提交”,没看出有什么不妥,只要提交前的测试、review 等等通过。

一个运行了两年的项目,spring 的包扫描明显配错了,有些 bean 根本扫不进来,居然没有人发现。
一半的 bean 在 spring 管理下,另一半的 bean 他们自己写单例模式来实例化。

>> 第一条依然是项目组疏于管理的佐证。即便是主力程序员,也缺少对项目整体的责任感,或者是代码烂得让人难以提起兴致。第二条则是一个典型的不好的实践。有时候可能会需要这样的妥协,但是居然有一半的 bean 脱离 Spring 的管理,那最初引入 Spring 干嘛?

他们用 mysql 来做审计系统,出报表,有个报表要跑 8 分钟。
原来是有人用字符串来存多值(逗号分隔),sql 里写了 like,导致没有利用到索引。
为什么不用 pg,pg 在 sql 编程方面,功能更丰富,更适合做统计,它本身就支持数组。

>> 报表跑 8 分钟很正常。Sql 用字符串存多值这个,没有利用索引,还是要分析具体问题,原则上我不觉得有什么问题。要想完美解决这个问题,还是在 mysql 里面,就得把多值拆解成多行,放到一张新表里面去。另外,也有一些 NoSQL 系统天然支持 value 多值,比如 DynamoDB,不过这是题外话。至于为什么不用 pg,这涉及到最初的技术选型,后人看的时候只是说说 “如果用 xxx 就 yyy 了” 当然容易,但是不清楚最初是否有技术层面的考量。当然,这个项目那么烂,也许是一开始图方便搞了 mysql 的 prototype 就上了。无论如何,有质疑的想法总是值得鼓励的。

程序员们都是得过且过的态度,怎么把代码灌进去,跑的通测试,就算交差了。

为什么大型互联网公司,技术和管理这么差劲,是怎么形成的?

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

你可能也喜欢看:

  1. 软件工程师成长的一个误区
  2. 不要让业务牵着鼻子走
  3. 有趣还是无趣?
  4. 直面歧视
  5. SSH 学习杂记

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

订阅·联系

四火,啰嗦的程序员一枚,现居西雅图

Amazon Google Groovy Hadoop Haskell Java JavaScript LeetCode Oracle Python Spark 互联网 前端 华为 历史 同步 团队 图解笔记 基础设施 工作 工作流 工具 工程师 应用系统 异步 微博 思考 技术 数据库 曼联 测试 生活 程序员 管理 系统设计 缓存 编码 编程范型 英语 西雅图 设计 评审 问题 面试 项目

分类

  • Algorithm and Data Structure (30)
  • Concurrency and Asynchronization (6)
  • System Architecture and Design (43)
  • Distributed System (18)
  • Tools Frameworks and Libs (13)
  • Storage and Data Access (8)
  • Front-end Development (33)
  • Programming Languages and Paradigms (55)
  • Testing and Quality Assurance (4)
  • Network and Communication (6)
  • Authentication and Authorization (6)
  • Automation and Operation Excellence (13)
  • Big Data and Machine Learning (5)
  • Product Design (7)
  • Hiring and Interviews (14)
  • Project and Team Management (14)
  • Engineering Culture (17)
  • Critical Thinking (25)
  • Career Growth (57)
  • Life Experience and Thoughts (45)

推荐文章

  • 谈谈分布式锁
  • 常见分布式系统设计图解(汇总)
  • 系统设计中的快速估算技巧
  • 从链表存在环的问题说起
  • 技术面试中,什么样的问题才是好问题?
  • 从物理时钟到逻辑时钟
  • 近期面试观摩的一些思考
  • RSA 背后的算法
  • 谈谈 Ops(汇总 + 最终篇):工具和实践
  • 不要让业务牵着鼻子走
  • 倔强的程序员
  • 谈谈微信的信息流
  • 评审的艺术——谈谈现实中的代码评审
  • Blog 安全问题小记
  • 求第 K 个数的问题
  • 一些前端框架的比较(下)——Ember.js 和 React
  • 一些前端框架的比较(上)——GWT、AngularJS 和 Backbone.js
  • 工作流系统的设计
  • Spark 的性能调优
  • “残酷” 的事实
  • 七年工作,几个故事
  • 从 Java 和 JavaScript 来学习 Haskell 和 Groovy(汇总)
  • 一道随机数题目的求解
  • 层次
  • Dynamo 的实现技术和去中心化
  • 也谈谈全栈工程师
  • 多重继承的演变
  • 编程范型:工具的选择
  • GWT 初体验
  • java.util.concurrent 并发包诸类概览
  • 从 DCL 的对象安全发布谈起
  • 不同团队的困惑
  • 不适合 Hadoop 解决的问题
  • 留心那些潜在的系统设计问题
  • 再谈大楼扔鸡蛋的问题
  • 几种华丽无比的开发方式
  • 我眼中的工程师文化
  • 观点的碰撞
  • 谈谈盗版软件问题
  • 对几个软件开发传统观点的质疑和反驳
  • MVC 框架的映射和解耦
  • 编程的未来
  • DAO 的演进
  • 致那些自嘲码农的苦逼程序员
  • Java 多线程发展简史
  • 珍爱生命,远离微博
  • 网站性能优化的三重境界
  • OSCache 框架源码解析
  • “ 你不适合做程序员”
  • 画圆画方的故事

近期评论

  • + 1.943624 BTC.NEXT - https://graph.org/Ticket--58146-05-02?hs=9a9c6f8dfe3cdbe0074006e3e640b19b& on 所有文章
  • Anonymous on 闲聊投资:亲自体验和护城河
  • 四火 on 关于近期求职的近况和思考
  • YC on 关于近期求职的近况和思考
  • mafulong on 常见分布式基础设施系统设计图解(四):分布式工作流系统
  • 四火 on 常见分布式基础设施系统设计图解(八):分布式键值存储系统
  • Anonymous on 我裸辞了
  • https://umlcn.com on 资源链接
  • Anonymous on 我裸辞了
  • Dylan on 我裸辞了
© 2025 四火的唠叨 | Powered by Minimalist Blog WordPress Theme
Menu
  • 所有文章
  • About Me
  • 关于四火
  • 旅行映像
  • 独立游戏
  • 资源链接