V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
gpsbird
V2EX  ›  问与答

读代码的时候,什么时刻最破防?

  •  
  •   gpsbird · 65 天前 · 5273 次点击
    这是一个创建于 65 天前的主题,其中的信息可能已经有所发展或是发生改变。
    58 条回复    2024-05-11 11:08:17 +08:00
    MillaMaxwell
        1
    MillaMaxwell  
       65 天前
    不得不提一嘴现在维护的代码了,上一任开发没有交接就跑路了,是真的逆天。技术是纯 python ,Django Rest Framework 。
    前任开发使用了大量的非定向 try except,不指定异常类型甚至互相调用,一个 1000 行的函数,最外层套俩 try ,入参不校验,出参不格式化。
    举一个真实的应用场景
    使用 orm 查询一个值是否存在:
    正常人思维:
    if a.models.objects.filter(pk=1).exists():
    xxxx
    else:
    xxxx
    if:
    xxxx
    elxs:
    xxxx
    他的做法
    try:
    a.models.objects.get().pk
    xxxx
    except:
    xxxxx
    try:
    xxxx
    except:
    xxxx
    MillaMaxwell
        2
    MillaMaxwell  
       65 天前
    @MillaMaxwell #1 .排版炸了
    ShundL
        3
    ShundL  
       65 天前
    读了半天读不懂的时候
    tool2dx
        4
    tool2dx  
       65 天前   ❤️ 2
    读自己以前写的代码。
    hahastudio
        5
    hahastudio  
       65 天前   ❤️ 21
    谁写的这么弱智,看我 blame 一下
    啊,原来是几年前的我
    tooyoungtoo
        6
    tooyoungtoo  
       65 天前   ❤️ 1
    看到一堆 shit 代码,心里骂娘这代码写的什么玩意儿,git blame 一看是自己😅
    waytodelay
        7
    waytodelay  
       65 天前
    和同事一起看代码,看到一段代码写得烂得批爆还没注释,嘴里还在骂,
    然后点开提交记录发现是自己提交的时候
    villivateur
        8
    villivateur  
       65 天前
    比如现在我接手的某个屎山,里面有一个某位大神写的 modbus 库,我研究了半天,发现这个库并没有在主程序中使用,主程序用的是一坨屎一样的 modbus 代码。这个大神库现在是僵尸代码。
    coderluan
        9
    coderluan  
       65 天前
    破防一般是指感情层面的吧,读代码顶多是绷不住,在怎么样也不至于破防,除非答案也包括读着读着发现代码是已故同事写的这种.....
    Dream95
        10
    Dream95  
       65 天前
    在严格禁止魔法值后
    kylebing
        11
    kylebing  
       65 天前
    写了挺多,在没有 commit 之前,一不小心 rollback 到了上次 commit 。
    Dream95
        12
    Dream95  
       65 天前
    同事写出这样的代码 public static final Integer INIT_INTEGER_TWO = 2;
    public static final Integer INIT_INTEGER_THREE = 3;
    public static final Integer INIT_INTEGER_FOUR = 4;
    inhzus
        13
    inhzus  
       65 天前
    看别人调用我们 SDK 的代码,写了行注释:
    // we must do xxx separately
    // **what can i say**
    zzping
        14
    zzping  
       65 天前
    @MillaMaxwell
    老哥你们用 := 的多吗
    我们都是 if account := Account.objects.filter(id=1): 的
    zzping
        15
    zzping  
       65 天前
    @MillaMaxwell if account := Account.objects.filter(id=1).first():
    laobobo
        16
    laobobo  
       65 天前
    @hahastudio 这种情况说明成长了
    MillaMaxwell
        17
    MillaMaxwell  
       65 天前
    @zzping #14 已经是一个老项目了,3.6 的 py ,没有用到这个
    vainl1
        18
    vainl1  
       65 天前   ❤️ 1
    @MillaMaxwell 前面提到的各种问题确实逆天。仅针对最后提到的正常人思维,如果只有少数时候值不存在,那么 try 的用法其实更合适,运行效率会更高。在 python 中有个说法叫 EAFP ,可以参考: https://stackoverflow.com/questions/1835756/using-try-vs-if-in-python
    leonx9527
        19
    leonx9527  
       65 天前
    @kylebing local history
    Vegetable
        20
    Vegetable  
       65 天前
    @zzping 如果为了判断是否存在没必要 first 。文档里说的很清楚 exists 会尝试使用最简单快速的方法判断是否存在
    Justin13
        21
    Justin13  
       65 天前 via Android
    破防到没有,最多偶尔气笑了
    iyiluo
        22
    iyiluo  
       65 天前
    给一份屎山代码,需要加一个新功能,明天上线
    falsemask
        23
    falsemask  
       65 天前
    @Dream95 这个是不是因为项目配了 check style 不允许出现魔法数字
    godloveplay
        24
    godloveplay  
       65 天前
    公司有个项目,注释都是看代码能看出来的:“遍历 list 去出 字段 xxx ”,“去 xxx_xxx 表中查询字段 xxx”
    反倒是一句业务含义的注释都没有,十分无语。
    AchieveHF
        25
    AchieveHF  
       65 天前
    屎上雕花
    xiangran0028
        26
    xiangran0028  
       65 天前
    进这个公司的时候,上一任已经跑了,没有交接,留下了 4 个机型,然后我发现每个机型居然都用的不同的框架(因为前任有好几个),最离谱的是一个 function 居然有 15K 行,里面各种全局变量各种赋值
    Aruok
        27
    Aruok  
       65 天前
    变量随意命名, 拼音变量就不说了, a1, a2 这种的, 方法名 handleData, deleteItem 的, 不注释的话根据不知道干嘛的. 一个方法还写的老长了...
    GeruzoniAnsasu
        28
    GeruzoniAnsasu  
       65 天前
    Morii
        29
    Morii  
       65 天前
    昨天发现同事写了一段

    delete ( redisKey );
    set(redisKey,value);

    不知道要干啥,直接 set 不行吗?
    assiadamo
        30
    assiadamo  
       65 天前
    for (int i = 0; i < 3; i++) {
    if (i == 0) {
    // ...
    } else if (i == 1) {
    // ...
    } else if (i == 2) {
    // ...
    }
    }
    chawuchiren
        31
    chawuchiren  
       65 天前
    @Dream95 这个有什么问题嘛,不是业务变量,我们常量池就这么定义的
    lucifer9
        32
    lucifer9  
       65 天前 via iPhone
    刚工作时候接过个紧急需求,改一位前 acm 金牌同事的代码。里面变量名真的是 a ,b ,c…这种
    hhhh115
        33
    hhhh115  
       65 天前
    @hahastudio #5 回旋镖
    cndenis
        34
    cndenis  
       65 天前
    @MillaMaxwell 你还别说, 这是 Python 的 EAFP 风格, 请求宽恕比许可更容易(Easier to Ask for Forgiveness than Permission), 用 try...except 代替前置的 if 判断
    https://docs.python.org/3/glossary.html#term-EAFP

    对于并发的场合, 这种做法是必要的, 比如你从一个并发的任务列队中取值, 即使先用 if 判断队列非空, 取回来的值也有可能是空的, 正确的做法是 try 取值干活 except Empty ...
    fredweili
        35
    fredweili  
       65 天前
    用 copilot refactor
    Sawyerhou
        36
    Sawyerhou  
       65 天前 via Android
    debug 一个老同事的跑不起来的脚本,一打开

    一行注释都没有,一个空行都没有
    空格一会没有,一会一个,一会几个,完全随机

    自认为脾气挺好,当时差点直接骂人
    MillaMaxwell
        37
    MillaMaxwell  
       65 天前
    @cndenis #34 但是这种的前提是代码是可控的,捕获到的异常是已知且清晰的,我遇到的情况就是单纯的懒得做判断,直接 try except 一把梭
    hzjseasea
        38
    hzjseasea  
       65 天前
    全局变量在项目里乱飞的时候
    ExiFeng
        39
    ExiFeng  
       65 天前
    @Morii 更新缓存吧, 先删了重新添加
    Morii
        40
    Morii  
       65 天前
    @ExiFeng

    直接 set 效果一样额
    cannotagreemore
        41
    cannotagreemore  
       65 天前
    @cndenis 你说的这个风格即使在文档里也只是处理并发情况的 option ,--- This issue can be solved with locks or by using the EAFP approach. 作为一个合格的开发者,访问并发资源需要加锁才更是合理的做法吧。
    上面的提到的场景,普通的查询不存在明明是一个业务分支直接 if 处理就可以了,异常才需要进行捕获
    v135ex
        42
    v135ex  
       65 天前
    经常看到有人说看到自己多年前写的代码不认识,我一直表示有点理解不了... 可能是我的代码风格太鲜明了吧(整洁/命名/函数归类强迫症),读很早之前的代码哪怕完全没有一点印象了也能一眼认出来是自己写的代码
    msg7086
        43
    msg7086  
       65 天前
    不是破防,只是这两天看到了感叹一下。
    同事移植了个上古的用 C 写的代码到 Java 。
    以前 C 代码有个缓冲区大小限制是 2000000 字节,同事直接照搬过来了。
    前几天遇到要处理一个文件,2000010 字节。

    程序抛了异常。文件过大。
    israinbow
        44
    israinbow  
       65 天前
    daxin945
        45
    daxin945  
       65 天前
    where 1 = 1
    ecloud
        46
    ecloud  
       65 天前
    错误的英文拼写和错误的用词作为变量/方法名
    gavin810
        47
    gavin810  
       65 天前
    @cndenis EAFP ,我更喜欢把它意译成 先斩后奏,效率当然高啦。
    Karte
        48
    Karte  
       65 天前
    @daxin945 这个大概率是为了拼接条件, 而且是 mybaits.

    ```xml

    SELECT * FROM <table>
    WHERE 1=1

    <if test="a != 0" >
    AND a = #{a}
    </if>

    ```

    如果没有这个 1=1, 那就变成 `WHERE AND a = #{a}`. 无法通过 MySQL 的解释器.
    Karte
        49
    Karte  
       65 天前
    这种不需要优化, 解释器会直接删掉这个条件, 因为怎么都是 TRUE.

    如果你看的不爽, 可以这样改

    ```xml

    SELECT * FROM <table>
    WHERE

    <where>
    <if test="a != 0" >
    AND a = #{a}
    </if>
    </where>

    ```

    参考 [MyBatis XML 文档]( https://mybatis.org/mybatis-3/dynamic-sql.html#trim-where-set)
    > The where element knows to only insert “WHERE” if there is any content returned by the containing tags.
    Furthermore, if that content begins with “AND” or “OR”, it knows to strip it off.
    madizmChou
        50
    madizmChou  
       65 天前
    函数参数永远都是一个 json Object
    behindeye
        51
    behindeye  
       65 天前
    前公司的代码注释:
    // 张总说,这里要怎么怎么做,所有要怎样怎样!!!!
    laikick
        52
    laikick  
       65 天前
    @GeruzoniAnsasu 现在去问下 chatgpt 都明白了.
    k9982874
        53
    k9982874  
       64 天前 via Android
    @behindeye 看到了开发当时愤怒又无奈的心情
    daxin945
        54
    daxin945  
       64 天前
    @Karte 如果我说是在 Flask 接口里面看到的 where 1=1 呢 而且还是我司内部安服找到的我..
    Karte
        55
    Karte  
       64 天前
    @daxin945 这是什么操作? web 为什么要拼接 SQL?
    windy0925
        56
    windy0925  
       64 天前
    有一个定义 type xx map[string]map[string]map[string]map[string]interface{}
    完全不想接着看下去
    daxin945
        57
    daxin945  
       64 天前
    @Karte
    就是拼接条件方便 只不过条件的来源是用户从输入框输入进来的 - -
    安服发现 sql 注入 然后我看代码发现了这个 where 1=1 应该只是为了拼接的时候不用拼 where 部分吧..
    Karte
        58
    Karte  
       64 天前
    @daxin945 应该是不想判断 AND. 1 = 1 后面直接拼条件就行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   901 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 20:12 · PVG 04:12 · LAX 13:12 · JFK 16:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.