百科问答小站 logo
百科问答小站 font logo



一个程序员的水平能差到什么程度? 第1页

     

user avatar   liang-zi-wei-48 网友的相关建议: 
      

大概就是,一个if循环19.8亿次,而且7年没人敢动....

真事,就出现在知名游戏大厂R星的知名大作 GTA 5 中。

而且,19.8亿次的if循环,今天仍然在世界各地的玩家cpu上跑着。

————————————————————————————————————————————
3月16日更新:

GTA 5“屎山”代码后续来了。

R星终于官宣准备修复了!

主动改善玩家游戏体验?不存在的。

要主动,哪里还要等七年?

这篇揭R星老底的帖子在全网大火后,R星不得不出面应对。

在和黑客大哥联系后,R星认可了他的改进方法,宣布在后续更新中修复相关问题,并且还慷慨的给他付了一笔1万美元的奖金。

鉴于R星失误实在太低级太离谱,而这位老哥的方法又太有效,以致无数玩家称他“功德无量”。

如果平均给每个玩家节省10秒,全球500万玩家一天就能节约5000万秒,一年中,节约的总时间大概能有数十年。相当于挽救了十多个人的生命!

“事了拂衣去,不留功与名”,这位黑客大哥被无数玩家膜拜。当然大家也不忘再把R星拖出来“鞭尸”。

有人吐槽,GTA 5仅2020年就买了2000万份,累计销量更是达到1.4亿份,R星每年都能从这个项目上赚数亿美元,但是却不肯花几分钟去解决这么一个低级错误,实在可耻。

还有人抨击R星几乎从不与玩家社区互动,玩家提的意见也从来充耳不闻,直到这次被被黑客嘲讽打脸,才不得不出来表态。

事后,黑客大哥还透露了一丝身份信息,原来他人在拉脱维亚。

拉脱维亚是波罗的海国家,原来是前苏联加盟国之一。在网上搜索相关信息,可以发现“拉脱维亚黑客”,几乎是和俄罗斯黑客一样传奇神秘的存在。

有网友爆料,在拉脱维亚,普通程序员工资平均3-4k欧元(23000-31000人民币)。

而他领到的这1万美元奖金,相当于三四个月工资了。

提前领了一笔“年终奖”,黑客大哥表示很开心。同时他也说,将密切关注GTA 5未来更新,一丝不苟的检查修复情况。

不知道他还能不能从R星领走更多奖金

(注:所谓“屎山”,是程序员间流传的一个梗,指陈年累月且复杂低效的代码,因为改动成本巨大,所有人避之不及。)

——————————————————————————————————————————

GTA 5“屎山代码”前情回顾:

一支烟的功夫,GTA 5联机版终于打开了。


「7年了!GTA 5联机版加载还是这么慢??」


Please wait forever to play
Reddit、Steam、HackerNews上,无数玩家吐槽抱怨……
进游戏少则等5、6分钟,多则20分钟。
终于,一个黑客大哥实在忍不了,用逆编译器逐条查看运行情况,终于找到原因。
原来,R星(游戏开发商RockStar)写的代码太低效,加载时,一个if语句竟然循环了19.8亿次….
幕后黑手:谁占用大量时间?
加载GTA 5 Online到底有多慢?


硬件拉满的土豪玩家请无视
Reddit相关板块发起的调查中,超过80%的玩家,都要等3分钟以上,有的甚至超过15分钟。
而且,从7年前Online上线到今天,这个情况丝毫没有改善。
暴躁的,已经骂起了脏话……


但奇怪的是,如果你选择是故事模式(单机版),加载就会快很多,感觉甚至像两个不同的工作室开发的游戏。
具体到这位黑客大哥的例子,他自己的硬件配置如下:


CPU,是老而弥坚的AMD FX-8350,2012年上市,采用“推土机”架构,超频潜力惊人。
显卡还是GTX 1070。
这样今天看起来老旧的配置,打开单机版GTA 5需要1分10秒,而加载联机版则6分钟起。
黑客大哥用了最简单的Windows任务管理器,来判断联机版GTA 5在启动时,都调用了哪些计算机资源。


在1分钟的时间分界线上,之前是加载的是单机和联机版通用的基础内容,之后是联机版独有的内容。
可以看到,联机版GTA 5,加载时调用大量CPU资源至少长达4分钟之久。
而同时,内存、GPU、硬盘的使用情况几乎没有明显变化。
所以,问题大概率出在代码上。
“R星代码写太烂!”
黑客大哥在开扒R星代码之前,就说:
我闻到一股烂代码的味道…..
为了找出到底那一部分程序卡住了CPU,他使用了工具Luke Stackwalker,对CPU任务堆栈进行采样分析。
Luke Stackwalker对于闭源应用程序,可以转存正在运行的进程堆栈,和当前指令指针的位置,以一定时间间隔建立一个调用树。
最后将数据整合,就可以得到程序运行统计数据。
从结果上看,一共有两个函数“卡住”了CPU:


于是他使用专业的代码拆解工具,给GTA 5来了一个“开膛破肚”。
沿着调用栈往下走,发现问题出在一个sscanf函数上。


sscanf的功能是读取格式化的字符串中的数据,而在GTA 5中,它正在读取的是一个10M左右,有63000多个条目的JSON文件。
这个文件到底是干什么用的?黑客大哥推测,这可能是游戏内购商店的相关内容。


在具体运行时,sscanf对于每个有效值,逐个读取每一个字符,然后返回结果,之后指针移向下一个值,循环往复……直到把10M文件全部扫一遍。
再看第二个问题,这是一个存储命令,对象是item,具体是什么不得而知。
但是保存前,有一个if语句,逐一比较item内项目的哈希值,检查它们是否出现在某一列表中。
按照他的计算,这一步if,要执行(63000^2+63000)/2 = 1984531500次!
没错,等待加载前的十多分钟里,GTA 5用你的CPU,执行了19.8亿次if命令。


如此简单粗暴的编程思路,让这位老哥哭笑不得:
既然对象有唯一哈希值,那为什么不用hash map???



(hashmap根据hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序不确定。)

至于为什么这样,有网友推测最开始,if的循环次数并没有这么多,而是随着开发,条目不断增多,最后到了积重难返的地步。

而之前的代码结构,谁也不愿意去动。

就这样,19.8亿次if,一遍遍在世界各地玩家cpu上上演。。。

这是不是堪称游戏开发史上最意外的“屎山”代码?


问题解决,加载时间节省70%
至于第一个问题,黑客大哥采用hook大法,不一一读取字符串,而是:
hook strlen
“缓存 “字符串起始和当前长度。
如果在字符串范围内函数在此被调用,返回缓存的值
至于if语句问题,就更直接了——完全跳过重复检查,利用hash map插入项目,因为这些值是唯一的。
最后的结果如下:


现在,GTA 5联机版加载,从原来的6分钟,下降到现在的1分50秒!而且,用的还是七八年前的硬件配置。
在此,应该手动@R星:你学废了吗?


这位黑客大哥在博文中没有留下任何身份信息,也没有透露用的反编译工具,但是做好事不留名的他,把打好包的工具上传到了Github,玩家通过一行代码就能下载:


git clone —recurse-submodules github.com/tostercx/GTA


之后,把dll文件粘贴到游戏根目录下就OK!
博客原文

nee.lv/2021/02/28/How-I
Github地址:

github.com/tostercx/GTA


user avatar    网友的相关建议: 
      

前老板,印度人,把我气疯了

公司做信号AI的。招我的时候说这个function已经写好了,那个project已经搞好了,我一听这么牛逼,这些功能很不好写啊,就接offer了。我进去前两个月的时候开会提到这个function,他还斩钉截铁地说"we already have that you don't need to worry about that",还做ppt说performance现在sensitivity, specificity都在90%以上,我也没多想。

后来有一天他提到网上有个这个功能的evaluation toolkit, 他不会用,所以自己手动算了一下performance, 我一看,这东西不就是个C程序么,在command terminal里带几个arg跑一下就好了。他很高兴,你跑吧。我跑完之后算出来performance大约是Se=20%, Sp=6%,就看了眼他的performance怎么算的。发现差不多就是clip(sum(pred_duration) / sum(true_duration), 0, 1), 根本没对比检测到的区间和ground truth的区间是不是同一个。我简直吐血,跟他说不能这么算。他盯着屏幕好久开始问我are you sure you can't calculate it this way? Are you sure this is how you run this toolkit? 我那时候已经怀疑人生了:Yes. What do you think overlap means?

然后他说那你看看怎么改代码吧,我才终于开始读他那个代码。他的style简直让人崩溃,indentation全是乱的,variable命名很多读了半天发现根本不是他describe的那个东西,还动不动会有一行代码写着signal=sig; 然后从这行开始某个variable就改名了。而且比如一段300Hz*30s的信号,他记录符合某特定pattern的区间,先弄个9000x1的array, binary的,记录每一个时间点是不是这个特征,然后再弄个8999x1的array,y=x(1:end)-x(0:end-1),然后再找出y里non-zero的点。我说大哥你这跟内存和CPU都有仇么?我们程序对输入信号长度是不限的,你30s的这么算也就算了,以后24h的也这么搞么?

Anyway, 后来这段40多行的代码我总算读懂了,读完发现基本可以概括为sum(find(40<time_diff<160))。一段这么简单的...如果这也可以称之为算法的话... 写了这么一大坨垃圾,time complexity space complexity都完全没考虑。而且关键是这个function是要识别一个很复杂的pattern,而他用了个自以为是的rule based algo,然后再用他那个错误的eval metric跑出来个90%+的performance,就宣布大功告成了。

我冷静下来之后跟他汇报了一下问题,然后他说哦,那你调整一下threshold,现在不是find(40<time_diff<160)吗?你把上下threshold调成45, 155什么的试一试。

我打个比方吧,他这个相当于写个识别照片男女的程序,没有任何神经网络机器学习etc,只提了身高一个feature,这个feature还不甚准,然后if height > 170: male; else: female. 现在performance不好,告诉我那你把170改成172试试。

我说这个得重写。他说不行啊来不及,现在必须提交,换个小点的database再跑一下把,然后拿出来个n=14的database,跟我说这个是training set。他说出training set那两个字的时候我就要崩溃了:你这是rule based algorithm啊,你train了啥???而且人家regulation department点名要用他们自己的database,不能换别的啊。Anyway, 我在他那个n=14的database上跑了一下,还是只有70%左右的成功率。再汇报给他,他说删掉几组算错的data,重新再算一遍吧。

我惊恐万分,辞职了。

后来又遇见了几个印度码农,都是说得漂亮做得一坨屎的主。

我真不想racist,但是从此以后我见到印度码农就害怕。我在学校里头见到的印度同学都挺聪明的啊,这TM怎么回事?

前段时间有个猎头找我,介绍了一家公司,最后提到说他们希望找一些tell it as it is的人,不要说的跟做的不是一回事儿。我不解,问她这是什么意思啊,然后猎头一副“很难解释”的表情和语气说,“比如他们以前招了一个印度人...”,然后我瞬间“哦,懂了”


user avatar   su-yuan-meow 网友的相关建议: 
      

之前面过一个女生,偏data science岗位。

先问了个热身题,有一个文件,每一行是一条记录,里面有ID,类别,数量等等。

写一个Python程序,输出有多少个unique ID,和出现次数最多的ID。

她答得很快,说把文件load进pandas,用unique函数输出,然后用count unique新建一个表,按照count排序,取最上面的。

我表示了肯定,然后问她有没有什么可以不用pandas的方法。

她愣住了,似乎没有听懂我的问题。

我耐心的解释,就是用python有没有什么办法,比如一些内置的数据结构之类。

她还是一脸迷茫。

我继续解释,比如我们可以用一个字典记录每个ID的出现次数,或者对于每个ID,都找一遍文件看出现了几次。

她似乎听懂了,开始写的第一行仍然是,import pandas。

后面明白了,她打心眼里认为python就是pandas。

于是后半场面试,就变成了我在和她科普,python和pandas之间的关系。


user avatar   yinfupai 网友的相关建议: 
      

有个功能仅仅只是需要在网页上显示一下树形数据,叫一个月薪一万多的php程序员去做,结果他回答说,用的框架不支持,做不了。


user avatar   kaveil 网友的相关建议: 
      

前端dog一枚,年前废了个项目。原因是后端数据出错而且没法解决,最后公司终止了这个项目。还好知道不是前端的锅,没扣我们钱。

这个后端的水平厉害到什么程度呢?之前出现过一个问题,用户数据不对,说是前端显示错误,他下发的是正确的。最后我们一条条数据排查,发现前端发送了一些并不存在的请求。很诡异,然后继续排查,发现是自动游戏发送的数据(就是页游的自动砍怪自动寻路),但是我们测试的时候是手动操作。再继续排查,居然在地图上发现了两个自己,也就是说这个帐号登录了两次!因为后端没有做重复登录验证,导致直接关闭页面的话这个用户就一直在线不会下线。

你们以为这就完了吗?

没有,我们把问题提交给后端之后,他让前端每次在提交登录请求之前,先发送一个该账户的退出登录请求,然后再发送登录请求……我们本着不跟傻比计较的心态还是按他说的做了。

如果这就完了那倒好了,过了两天测试又出问题了,说是没打怪钱和经验会自动涨,后端继续说是前端的问题,他打印的日志是对的。有了之前的经验,我们排查的就很快了。这次发现他把另一个用户的数据推送给当前用户,再一看两个用户的UID居然是相同的,直接杀过去找后端,发现他UID居然没设唯一字段,而是从0开始递增,导致了第三方(QQ微信)登录用户和帐号注册用户共用了同一个UID,这次我们被他气得连骂人的话都说不出来了……

总之类似的问题还有很多,公司眼看不对及时终止了项目,本来想开了他的,但是因为另一个后端离职暂时留着他祸害同事,我们前端一致决定拒绝跟他合作项目,现在让他跟实习的前端玩儿去了。


user avatar   da-niu-16-68-45 网友的相关建议: 
      

老板觉得公司里都是男的,缺少一点阴柔之气,想平衡一下,正巧当时互金公司倒了一大批,大批简历投到公司,老板以为自己也是技术出身,就招了一个三年工作经验的女程序员,互金出来的,要价倒是不低。我休假去了,没面她,等我回来要安排工作了,这才发现问题了。
给她安排了一个新项目,是会展方面的,跟她简单说了一下工作安排:先搭个spring maven项目,然后跟产品谈下需求,考虑一下数据模型,过两天跟我碰再确定具体模型。她没说什么,等到第二天快下班了,产品来问我了,她怎么还没动工?我说我安排了啊,这就找过去问她,她说框架还等着技术总监(也就是我)搭了,她不是架构师,不会。
当时我就懵了,还有这种操作,你就是上spring网站都能搭一个啊。又问她需求谈了没有?数据模型有没有想出个大概?她又说,需求是BA谈的,她不会。我这就急了,那你会什么呀?她说她原来公司都是框架环境都是配好的,她只管写代码。我当时心里就凉了半截,这项目估计最后要我来收拾残局了。这就去找老板换人,老板说你就带带她吧,反正这项目也不急,就当给公司添一点亮色吧!

没办法,只能硬着头皮带她了,期间各种eclipse环境之类的就不谈了,比如svn配置忽略文件类型,lombok插件等等,总之环境不会配。
终于帮她全部配完环境,详设也写好跟她讲解了一遍,总算开工了,若干天后提交代码了,我做了一下code review,这心里又凉了半截:方法,类名,变量等等一概中文拼音;业务逻辑明明可以复用的不写公用方法,跟别提用自定义注解了;驼峰命名法是什么不知道;Mysql有的表字段名全大写,有的全小写,有的又跟我来个驼峰。我又跑去找老板要换人,老板打个哈哈,哎呀,又不是人人都有这个你这个水平,再带带说不定就出来了。

没辙,给我戴顶高帽子,只好回去跟她苦口婆心地说了半天代码规范,其实就是阿里那一套,装个插件就能检查,又跟她着重讲了一下命名规范,要用英文命名,否则注释少的话很难看懂程序,她直点头,说这就改,我也就信了。

等到代码再次提交,我一看,一口鲜血差点没吐在屏幕上,展品的长宽高单位是米,结果好家伙一看,长度long_rice,高度high_rice,当时看的时候实在没明白这脑回路到底是个什么套路,强压怒火跑去问她这是什么意思,她振振有词地说:你讲的呀,命名的时候最好要体现度量单位。
我实在忍不住了,吼起来了:那rice是什么单位,是什么单位?她也不示弱,把词霸的屏幕取词一开,移到米字那里,说:你自己看,米不就是rice吗!我顿时无语,只能又跑去找老板,老板也无语,只能自我解嘲地说:她不是过了四级了吗,我还查来着了。
这件事情最后的结局就是我在面人的时候,都要当面问几个英语单词,实在是怕了。
~~~~~~~~~~~~~~~
rice这个我是实在没看明白,记得还有一处我是看明白了,她把发消息的发命名为hair,我愣了一下也就知道。

作者:靓仔山河
链接:jianshu.com/p/e6fca3be4
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


user avatar   exco 网友的相关建议: 
      

说个十几年前的事情吧。

真的都是泪。

当时公司找了一个外包公司,号称掌握核心科技(不是做空调那家)。

对方号称技术很牛X,只派了一个程序员过来。

这大哥看起来头发不多,低声细语,很是靠谱。

一开始交代了需求,他就自己去做了。

后来发现赶不上进度,要求来我们公司驻场。

然后发现大哥半天貌似一直在修改同一屏代码。

实在好奇,就问了一句:咋了?

大哥谦逊地一笑:奇怪这功能为啥出不来。

我看了看代码,惊了。

基本上是能写IF ELSE 不写 CASE的主。

然后为啥这些代码不起作用呢?

往上拽了拽,函数最上面发现了一句:IF (FALSE) THEN


user avatar   Ivony 网友的相关建议: 
      

大概是通过复制粘贴来让同一段代码反复执行多次吧……


user avatar   JX-Consp 网友的相关建议: 
      

使用函数名的字符串长度作为 hash function;并且将函数名设计地错落有致来避免 hash 冲突


user avatar    网友的相关建议: 
      

从道理来说,早减晚增本身是没啥毛病的,毕竟只是个选项,丰俭由人。

大家怕的是某些人通过这些选项,再加点私货。而且这个说法和推迟退休一起出来,由不得大家多想。

按照目前的舆论情况,如果你敢允许早退减拿,估计只要不在体制内的人就统统早退了,反正也没啥规定领了社保就不能接着打工,对吧?甚至还可以把原来交给社保的那块放自己口袋。

所以,让你早退减拿是不可能的,忽悠大家晚退多拿的可能性比较大。




     

相关话题

  如何看待「快手」APP? 
  为什么貌似吴亦凡事件中全凭女方一张嘴,众人就断定事件真实性? 
  2021年了,放弃北京户口是个正确的决定吗? 
  客观分析,通常是追求结果的人成功还是追求过程的人成功? 
  要去柬埔寨做程序员了,可靠么? 
  印度哪些方面强于中国? 
  长得丑的女程序员如何向男程序员讨教如何写代码? 
  你吃过最奢侈的一道菜是什么? 
  如何与有好感的程序员沟通? 
  2 月 5 日虾米音乐正式关闭,虾友们有何打算? 

前一个讨论
有没有外星人造访地球的「确切证据」?
下一个讨论
扎波罗热哥萨克给奥斯曼苏丹的回信是个什么梗?





© 2024-05-14 - tinynew.org. All Rights Reserved.
© 2024-05-14 - tinynew.org. 保留所有权利