V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qwerthhusn
V2EX  ›  程序员

如何强行吃透一座屎山代码?

  •  1
     
  •   qwerthhusn · 78 天前 · 10497 次点击
    这是一个创建于 78 天前的主题,其中的信息可能已经有所发展或是发生改变。
    领导叫我把一套代码的逻辑吃透,重写合入到另外一个 baseline 项目,但是写那个代码的人水平是真的次,应该是刚毕业的,都没咋写过代码就直接上手项目。(我们现在在做工业上位机项目,都是现场开发功能的,没有代码质量管理)。

    这个成为屎山有点夸张了,顶多是一个屎堆,但是味儿绝对正点。

    * 代码没任何注释
    * 到处都是类级别的变量
    * 变量和函数和类都是随意起名字 id ,根据名字完全看不出来这个 identifier 是干嘛的,需要去看引用的地方才能看出来,但是有的引用层次关系网异常复杂,绕几下都忘记我要看的是哪个变量了。
    * 手拼 JSON ,Split 拆 JSON 等这种操作到处都是。
    * 巨无霸代码,所有东西写在一起,有好几个 10000+行数的代码文件。

    虽然我工作这么多年也见过非常多的屎山项目,以前做互联网后端,微服务兴起之前,我见到过比这大得多的多的屎山代码,全量编译都能编译个一二十分钟的都有。但是以前是只是在项目上再加点料就行了,而现在要做的是把整个项目吃透,我该怎么办?有没有啥好的策略?

    PS:跑路不能算是一个好策略,我在看这坨代码的时候晕头转向,满脑子都在想着跑路,但是现在工作太难找了,经历过后疫情的裁员后找工作从希望到失望到绝望的感觉,我宁愿继续啃这坨代码。
    104 条回复    2024-09-19 09:09:47 +08:00
    1  2  
    auhah
        1
    auhah  
       78 天前
    先往里拉点屎融入屎山就好了

    融的多了就知道怎么改了

    一点点改
    lyxxxh2
        2
    lyxxxh2  
       78 天前
    既然是刚毕业的,项目能有多复杂。
    理解需求,直接重构。
    STillSB
        3
    STillSB  
       78 天前
    尝试下借助 AI 的力量
    prosgtsr
        4
    prosgtsr  
       78 天前 via iPhone
    拉个分支,重构一下来理解,然后再回头来改原先的分支
    crocoBaby
        5
    crocoBaby  
       78 天前
    直接加自己的屎山就好了,之前的屎山我都是不管的,只要功能需求能实现就行
    fregie
        6
    fregie  
       78 天前
    能吃透的就不叫屎山
    Jinnrry
        7
    Jinnrry  
       78 天前 via iPhone
    找产品要产品文档,然后直接重构,不看代码
    重构完再找测试要测试用例,跑一遍搞定
    cccvno1
        8
    cccvno1  
       78 天前   ❤️ 18
    这种项目先不要去关注代码细节,先找到各个操作的输入输出理清业务会简单很多
    reallycool
        9
    reallycool  
       78 天前   ❤️ 2
    举个例子,怎么吃透一个人的武功,你比他强,吃透就很简单,你不如他,那就觉得和屎一样难理解
    XiaoXiaoMagician
        10
    XiaoXiaoMagician  
       78 天前   ❤️ 1
    为什么喜欢隔这吃屎呢?都定屎山了,要么搅乱,要么别管,让后你自己拉坨新的,你为什么要去研究怎么吃透.......
    zhangeric
        11
    zhangeric  
       78 天前
    用 vs 开发的话,可以用 vs 自带的分析工具先分析一下.
    rossroma
        12
    rossroma  
       78 天前
    借助 AI 吧,最近都在吹 cursor ,你要么装一个试试
    rossroma
        13
    rossroma  
       78 天前
    可以看下这篇使用 cursor 感受的文章: https://mp.weixin.qq.com/s/shmpkeH_FmZ53GZDpKimQw
    willchen
        14
    willchen  
       78 天前
    别想着一口气吃透了 写一块看一块 慢慢打补丁吧
    ytmsdy
        15
    ytmsdy  
       78 天前
    只能借助 AI ,一个函数一个函数拆解了。让 AI 给你写注释,然后你快速看一下,大概那些功能在那些函数里面。
    你如果要新增功能的话,单独开新的问题,单独写。
    xuelang
        16
    xuelang  
       78 天前
    如果能知道代码的功能,比如有配套测试的话,干脆让 AI 重构一下
    zh584728
        17
    zh584728  
       78 天前
    吃不透的,用 AI 看一下,能用的就用,不能用的就重新写
    lightjiao
        18
    lightjiao  
       78 天前 via iPhone
    写测试用例,花时间,一点点重构
    guanzhangzhang
        19
    guanzhangzhang  
       78 天前
    先尝试看看几个重要功能测试正常不,看那块大概逻辑和产品文档一致,看不下去那块代码就整个重构得了
    LitterGopher
        20
    LitterGopher  
       78 天前
    如果是我的话我不会从代码入手,而是从业务入手。两个原因:

    1. 旧代码中指不定存在一些不管你水平如何都要加个 if 的那种被迫垃圾的代码,而且有些情况不是很好判断具体是水平问题还是业务要求,别一不小心 “优化” 掉了。
    2. 代码本来就服务于业务,更好的了解业务才能明白整个代码,而且即便代码看不下去想要从写也能有的放矢。尤其是对于整体代码逻辑的构建(代码框架)。
    wangshushu
        21
    wangshushu  
       78 天前
    ai 是一个方向,说不定将来 AI 继续 Scale Up ,真的有机会解决屎山问题
    sn0wdr1am
        22
    sn0wdr1am  
       78 天前
    屎要一口一口吃。🐶

    先找主干,再找分支。

    抓大放小,找主体结构。

    再抽抽丝剥茧,层层扒拉,熟悉细节。
    pkoukk
        23
    pkoukk  
       78 天前
    @LitterGopher 业务要是真那么逻辑清晰讲道理,代码就不会写成屎山了。
    majianglin
        24
    majianglin  
       78 天前
    钱给够吃屎都行,屎山代码算啥
    blankqwq
        25
    blankqwq  
       78 天前
    不如吃透业务
    karnaugh
        26
    karnaugh  
       78 天前   ❤️ 1
    硬吃呗,不过这东西就像医学一样,你如果上来就从底层细胞开始研究,那因为代码互相调用影响啥的,你很难从底层推出上层会发生什么

    所以可以考虑从上层研究,先把功能点列出来,或者做个图谱之类的,然后从功能点一个一个下去看源码如何实现,这样子
    karnaugh
        27
    karnaugh  
       78 天前
    哦对了,可以申请个带鱼屏,便宜的也就 1000 来块钱,超长屏幕同时看 4 段代码不成问题😂
    BugCry
        28
    BugCry  
       78 天前 via Android
    当成黑盒,包一层不就行了
    又不是不能用.jpg
    Codingxiaoshi
        29
    Codingxiaoshi  
       78 天前
    @cccvno1 我觉得这哥们儿说的可行
    MrVito
        30
    MrVito  
       78 天前   ❤️ 2
    我建议的两种解法,一种是直接把这部分代码封装,当成第三方库扔到 baseline 里面,然后根据需求在里面加点屎;另一种就是完全重写,从业务出发,完全不看这些屎。
    tool2dx
        31
    tool2dx  
       78 天前
    @pkoukk OP 这个是工业项目,需求感觉也还好,仅仅是代码乱一点。APP 业务的需求,才是天花乱坠。
    mingliao
        32
    mingliao  
       78 天前
    @sn0wdr1am 精辟
    mars2023
        33
    mars2023  
       78 天前
    既然都重写了,那么你应该只需要梳理业务需求,然后结合测试用例重新写一个就好了。
    又不是让你重构 🐶
    lasuar
        34
    lasuar  
       78 天前
    钱够就猛吃,不够就慢慢吃,总会吃完的,反正都得吃。PS: 只吐槽不会凸显你的技术水平多好。
    fredweili
        35
    fredweili  
       78 天前
    借助 copilot 之类的吧
    sss15
        36
    sss15  
       78 天前
    画图,现在很多在线画图的画布都是无限大的,你就一层一层绕,一边绕一边画就行了
    zhu327808
        37
    zhu327808  
       78 天前
    我最近接手的项目就是这样,只有一份代码,没有文档,只有一个可用的环境,我的方式是这样的,先理解产品的功能,从功能出发猜测大概是怎么实现的,当然要看的是主流程的功能,把一个整个功能流程了解透,再思考如果是自己做该怎么做

    有了上一步的一个梳理带着到底是不是这么实现的,来看代码中的主要流程,先不要关注细节,梳理流程,然后把一整个代码的流程串起来

    然后就可以开始解遗留的 bug 了,解 bug 的过程就是了解细节的过程,边解边把一些觉得值得重构的点打上 TODO

    再然后就是接新的需求了,新的需求肯定是要改造现有的代码的,那就按自己思路做分层,实在改不动的代码就他妈先包成一个函数,写个自己能懂的函数名字,打上注释能用,不要轻易改动

    我现在就是尽量自己的新写的代码就把以前的功能完全重构掉,改不动就封装起来,下层的代码尽量要稳定,上层可以快速迭代

    当然屎山就是屎山,不可能一步到位,只能走一步看一步了,也没有时间来完全重写

    ps:我这里是一个 golang 的项目,然后被各位大佬硬是写成了 java 的风格,我也是服气的,然后上了他们手撸的依赖注入,导致看代码逻辑都是乱的,你都不知道这个对象是从哪里来的,我的妈呀,头疼
    xloger
        38
    xloger  
       78 天前
    灵活应用 Copilot ,让 AI 来辅助你理解代码。
    然后,要重构或者基于它改代码,重要的思路是:你自己要理清楚整个业务上怎么样的,结合现实中这个业务的流程和代码的实现,整理出一套接口 驱动这个旧代码。
    这样里面的具体实现没那么重要了,你可以在不用完全理解里面实现细节的情况下驾驭它,哪怕有问题也能快速定位。

    但是,但是哦,如果自己水平欠佳或者梳理到一半凑合了。后人接手你的代码,那观感就是这层山上又叠了一大层......
    sagaxu
        39
    sagaxu  
       78 天前   ❤️ 1
    从功能出发,先熟悉这个程序的功能,然后看看需求文档(大概率没有或者出入较大),再自己从零开始设计一个方案,想想看自己开发会怎么做。

    然后开始看代码,忽略细节,只到文件或类层级,把几个主干类加上注释,理清脉络,画出一个整体结构来,跟自己设计的方案对比一下,也许这个时候需要修正自己的方案。

    接下来就是翻译了,把 A 架构代码翻译到 B 架构。在翻译前,把测试用例准备好,不用很全,覆盖主要功能就行。这个时候再去抠变量名和代码细节,边翻译边加注释。

    我重写过很多个零文档的项目,别看代码量唬人,可能很多是复制粘贴重复的,很多是压根儿就没用到。
    lanif
        40
    lanif  
       78 天前
    分成一个个小的部分丢给 chatgpt
    meeop
        41
    meeop  
       78 天前
    1 把所有代码喂给 ai
    2 让 ai 梳理:
    请帮我梳理所有业务逻辑,梳理文档
    请帮我梳理所有上下游依赖
    请帮我梳理所有方法调用链和相关逻辑
    3 重构
    请帮我重构整个项目,按照 xx 规范 xx 结构重写项目

    看代码量,数千行的 cursor 应该就能做到了,更多代码量暂时不能这么干,但也快了
    7gugu
        42
    7gugu  
       78 天前
    先从画流程图开始,把整个项目的流程梳理清楚,不然重构都无从下手
    whp1473
        43
    whp1473  
       78 天前
    1 、可以先读完整的产品设计,然后自己先设计一套
    2 、给核心接口写单元测试,以及 Debug 代码流程
    3 、在这个过程中完善自己那套设计的细节
    4 、输入输出保持不变,重写所有方法的逻辑
    5 、执行所有单元测试通过
    6 、编写历史数据迁移脚本
    7 、提交给测试进行回归测试
    whp1473
        44
    whp1473  
       78 天前
    @whp1473 核心逻辑就是面向单测重构,一本书里专门讲了,这种是最保险的,缺点就是成本比较高
    oncethink
        45
    oncethink  
       78 天前 via iPhone
    别光想着和代码硬刚,一定要和领导讲清楚重构这些系统的难度,确定要让意识到不是你能力不行,而是重构有这些问题的旧系统,对任何技术水平的开发者都有难度;
    第二是用 AI 来梳理代码,不要想着直接用 AI 重构,而是先用 AI 大概解读一下代码的功能,当前的 AI 还是解释能力强于重构能力。
    楼上提到用 AI 直接梳理依赖关系目前还不现实,但是你可以用 AI 来写一些代码依赖的分析脚本,在这些脚本的加持下增进对代码的理解。
    cccvno1
        46
    cccvno1  
       78 天前
    @sagaxu [可能很多是复制粘贴重复的,很多是压根儿就没用到] 太对味了
    oncethink
        47
    oncethink  
       78 天前 via iPhone
    还有楼上提到的梳理数据的思路也很好,采用滑铁卢风格理清整个系统的数据转换比理清楚代码行为更容易增强对系统的理解。
    darkengine
        48
    darkengine  
       78 天前
    完全看不出来这个 identifier 是干嘛的
    -------
    看懂一个 identifier 之后,马上用一个合理的名字把它换掉,记得使用 IDE 的 rename 功能(千万不要全局替换!!)。
    oncethink
        49
    oncethink  
       78 天前 via iPhone   ❤️ 1
    另外你可以考虑用使用一些代码的复杂度计算工具,例如看看循环复杂度,代码的不稳定度,然后从循环复杂度最低的函数开始看起,从易到难,然后再去重构哪些循环复杂度高的代码。
    spadger
        50
    spadger  
       78 天前
    刚毕业的写不出 10000+行的代码的
    Dogtler
        51
    Dogtler  
       78 天前
    要么重构,要么离职。
    屎山代码一般都失去业务拓展可能性,钱给够就留,没给够看 offer
    Rorysky
        52
    Rorysky  
       78 天前
    这种脏活累活只能交给 gpt 了
    guanhui07
        53
    guanhui07  
       78 天前 via iPhone
    @Dogtler 没必要自己离职,到点下班 就得
    Ackvincent
        54
    Ackvincent  
       78 天前
    能用就不要动,不能用就包一层,只有屎山里只能存在屎。
    RandomJoke
        55
    RandomJoke  
       78 天前
    先理解业务,再理解代码,准备测试用例,再考虑一点点重构
    winterbells
        56
    winterbells  
       78 天前 via Android
    别吃了,我几年都没搞定公司服务器怎么连接
    只能用现成的库
    各种魔改 OKHTTP ,没有注释
    里面的第三方库复制粘贴不知道改了什么,也不知道是粘贴的哪个版本,反正我替换成最新的就不能用了
    十几个 class 内容相似,有些大小写不一样,有些属性不一样,但挡住 class 名称绝对分不清。它们之间有的可以互相转换,有的不能。现在要加变量,问是都加还是只加用到的。当然是都加,因为不知道什么鸟地方最后传个 API 了,少个值就报错了
    winterbells
        57
    winterbells  
       78 天前 via Android
    @winterbells 还有奇葩的点是 A 里面的 xxx 和 B 里面的 xxx 可能不是一个类型,转换的时候要把 xxx 转成的 yyy 。变量名也不是 JSON 名,因为有的指定了 serialization name…
    shapper
        58
    shapper  
       78 天前
    先把主框架给梳理出来(可以通过调试快速画出来 [函数调用] ),主框架出来了,分支可以细化分析
    jjwjiang
        59
    jjwjiang  
       78 天前
    首先现在有 AI ,可以非常大的降低这种事情的难度。

    其次慢慢的做安全级别很高的重构,比如通过 IDE 或者 AI 把大块的业务摘出来,作为子方法,让主流程留下的是业务上的抽象方法,然后再挨个分析。

    个人觉得这个不算多屎,因为他把所有东西放一起了,那充其量就是有点菜有点恶心而已。真正的屎是充满了自以为是的过度抽象化设计,不进断点都看不出来代码是怎么跑的那种。
    dododada
        60
    dododada  
       78 天前
    先黑盒,简单了解输入输出,有空了再白盒吧
    messaround
        61
    messaround  
       78 天前
    说白了就是不会梳理代码,同时有怨气
    fffq
        62
    fffq  
       78 天前
    输入输出了解清楚,里面想怎么拉怎么拉,不对,想怎么写就怎么写
    blankmiss
        63
    blankmiss  
       78 天前
    我劝你不要不知好歹 哈哈哈
    gjnevergo
        64
    gjnevergo  
       78 天前
    用 co-pilot
    MrZhangLo
        65
    MrZhangLo  
       78 天前
    @XiaoXiaoMagician 不吃透,怎么拉新的。。
    NjcyNzMzNDQ3
        66
    NjcyNzMzNDQ3  
       78 天前
    @BugCry 嘿嘿嘿 我也是包一层
    wjhmrc
        67
    wjhmrc  
       78 天前 via Android
    先去翻 prd ,试图从代码理解业务是很困难的
    JackSlowFcck
        68
    JackSlowFcck  
       78 天前
    @cccvno1 #8 可行,先解决架构问题
    JackSlowFcck
        69
    JackSlowFcck  
       78 天前
    领导叫我把一套代码的逻辑吃透,重写合入到另外一个 baseline 项目
    ---
    首先,时间给多久?很少,跑路吧。很多,不妨作为练手过程。
    其次,建议从架构维度去看,一个系统无法是为了解决具体问题,那么这个项目是为了解决什么,其功能点是什么,对应代码块在哪,梳理清楚,大概八九不离十了。
    然后,莫名其妙的地方,先忽略,遇到再说。
    最后,把自己需要写的地方加上。
    polo3584
        70
    polo3584  
       78 天前
    不建议一次全改,容易长时间得不到正反馈,还容易被小问题卡进度。先跑通一个主支,然后逐渐往里加功能
    NX2023
        71
    NX2023  
       78 天前
    @cccvno1 #8 要是有完善的单测就好了((直接看单测的输入输出一个个自己在糊一次
    vevlins
        72
    vevlins  
       78 天前
    代码理解不了的,从业务理解。

    有些代码其实早就是没用的代码,或者重要性没那么高,你就算没实现也不会有什么问题。只要业务本身没那么复杂,一样可以抽出来比较简单的实现。
    yufeng0681
        73
    yufeng0681  
       78 天前
    @MrVito #30 封装思路不错,可能实操方面,最好分出来几个特性,然后逐个封装合入。 这样有一定的解耦性,会更灵活一些。 不会,每次有问题,都要全部翻看一遍代码。 累球死人。
    cccvno1
        74
    cccvno1  
       78 天前
    @NX2023 确实,但是这种项目写单测的太少了,想加都很困难,有些离谱的 debug 都不行
    kinkin666
        75
    kinkin666  
       78 天前
    生产上拉日志看输入输出都是咋回事
    ala2008
        76
    ala2008  
       78 天前
    可能功能没那么多,反正是重写,重新设计
    JeffersonHuang
        77
    JeffersonHuang  
       78 天前
    屎山,吃透也没意义。因为吃的是屎
    nyxsonsleep
        78
    nyxsonsleep  
       78 天前
    想要避免被失去利用价值可太简单了。这种工控程序的,连代码管控都没有,写个二进制的包作为关键依赖组件,根本用不着什么史山。
    还是写测试用例,从关键函数输入输出着手吧。
    yyysuo
        79
    yyysuo  
       78 天前
    当然是打包引用了,没有 bug 就别改了,我估计也没人能说得清业务需求。
    zypy333
        80
    zypy333  
       78 天前
    在想有没有 ai 助手,给一个文件夹,他自己帮忙拆开喂给 gpt ,然后告诉你每个地方都是干嘛的,或者在每个方法每个变量加注释
    yikyo
        81
    yikyo  
       78 天前
    最优的方式是先写测试,确保输入输出一致来重构代码,借助 AI 的能力,项目如果不是特别巨大的话,应该还是可以搞的。
    lxh1983
        82
    lxh1983  
       78 天前
    让你重写又不是维护屎山,这种不是应该吃透业务逻辑就行了吗?
    lvtuyukuai
        83
    lvtuyukuai  
       78 天前
    听起来是脏活累活,但其实是个好活(如果时间充裕的话)
    wusheng0
        84
    wusheng0  
       78 天前
    重写还是比较爽的,

    因为之前的设计,你想写好代码也没法写,只能被迫拉屎才是坠痛苦的
    a1b2c3T
        85
    a1b2c3T  
       78 天前
    @STillSB #3 老哥,我想问下 AI 能给他发个项目链接他给我分析下项目整体架构吗?
    jiayouzl
        86
    jiayouzl  
       78 天前
    嫌麻烦用 AI 帮你啊!屎山代码我都借助 AI 的,最新 o1 和克劳拉 3.5 都能完美解决.~
    vipfts
        87
    vipfts  
       78 天前
    @rossroma #13 文章说会替代初级, 可是初级没有工作机会, 以后也不会有高级了, 不过我们公司高级都忙着跟项目需求拉扯, 根本没时间打理新人的脏活, 替代倒是很难
    adian
        88
    adian  
       78 天前
    强行吃屎还是掉头发,选一个吧
    fooso
        89
    fooso  
       78 天前   ❤️ 1
    小口慢吃。记得吹一吹,不然烫嘴
    sumarker
        90
    sumarker  
       78 天前
    业务优先,然后一点点改吧,没其他办法
    LitterGopher
        91
    LitterGopher  
       78 天前
    @pkoukk #23 那可就不好说了。并非每个人都注重代码质量的。比如 1+1+1+.....(100 个 1) 写起来太长了咋办?正常人一般想法是写成 1*100 ,但我聪明的同事选择写成 100 行,每行一个 1 。

    你感受过打开 VSCode 的时候一个 200 行的源代码有 201 个 warrning ?
    EndlessMemory
        92
    EndlessMemory  
       77 天前
    理解功能吧,看逻辑是不可能了
    774157009
        93
    774157009  
       77 天前
    吃屎啦你 XD
    cheneydog
        94
    cheneydog  
       77 天前
    封装
    Nothing9527
        95
    Nothing9527  
       77 天前
    工业上位机领域的代码屎山多很正常, 很多时候要出差到甲方工厂根据现场调试代码, 大部分时候都工期很急, 基本都是想到啥就写啥.
    建议:
    1. 找个代码架构视觉化工具, 比如 understand, 如果你是.Net 的话, VisualStudio 也有个生成代码视觉树的功能, 把各个模块之间的关系理清楚, 一开始不要死抠细节
    2. 模块间关系搞清楚之后, 再尝试理解模块的运行逻辑
    3. 一个个模块合并到 baseline 项目中, 有条调机测试的话就调机测试
    piero66
        96
    piero66  
       77 天前
    让 ai 线帮你加一遍注释
    Flyfish233
        97
    Flyfish233  
       76 天前 via Android
    有 AI 都不一定可行,有个几年前的加密库用了十几年前的另一个库,全网只有它这唯一实现,虽然开源,几乎没几行注释,后者连测试都没有,现在第一个库都没怎么看懂逻辑,由于代码冗长,AI 很难起比较大的作用,copilot 乱说,我从 ChatGPT 刚开始就在使用,有一定 prompt engineering 积累,但实在搞不定,加上不是太重要,已经搁置等死
    janus77
        98
    janus77  
       75 天前
    吃透不太可能,我一直坚持的理念就是屎山不是一个人写出来的,是多人合作的情况下才会出现的,所以只要是多人合作,那必须就有信息不对称的情况,没有一个人可以通晓全部,哪怕是原作者也不行,因为原作者都只是其中一部分功能或者一部分时期的开发者。
    但是通晓一部分功能点是可以做到的,无非就是硬啃呗
    honus
        99
    honus  
       74 天前
    时间 重构,靠这个读透了一份屎山代码
    daimiaopeng
        100
    daimiaopeng  
       74 天前
    问 chatgpt
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2608 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 10:32 · PVG 18:32 · LAX 02:32 · JFK 05:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.