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

老哥们,我感觉我写的代码像 shi 一样。。求指点

  •  
  •   uselessVisitor · 2020-11-13 22:45:24 +08:00 · 3087 次点击
    这是一个创建于 1259 天前的主题,其中的信息可能已经有所发展或是发生改变。

    故事是这样子的。。。

    领导让我制定个代码规范(小部门刚成立),然后看了阿里的规约,看到他们不推荐使用三个 left join 以上,心血来潮想测一下 left join 和在 java 中拼哪个快。

    由于实力不行,模拟了 200000 条数据,当一次左连接并且加上索引时,很快啊,所有数据大概 200ms,然后我用 java 拼接,算了好久也没出结果。。现在我怀疑是我写的两个 for 复杂度太高了,请大佬们帮忙看一下我的 shi 一样的代码。。

    //service 层拼
    public Page<PersonInfoDTO> getPersonByJava() {
            long startTime = System.currentTimeMillis();
            IPage<PersonDO> personPage = personMapper.selectPage(new Page<>(),null);
            IPage<AddressDO> addressPage = addressMapper.selectPage(new Page<>(),null);
            //todo 获取 person 信息
            List<PersonDO> personDOList = personPage.getRecords();
            List<PersonInfoDTO> personInfoDTOList = new ArrayList<>();
           //todo 获取所有 address 信息
            List<AddressDO> addressDOList = addressPage.getRecords();
            int personSize = personDOList.size();
            int addressSize = addressDOList.size();
            for (int i = 0; i < personSize ; i++) {
                PersonDO personDO = personDOList.get(i);
                PersonInfoDTO personInfoDTO = new PersonInfoDTO();
                personInfoDTO.setName(personDO.getName());
                personInfoDTO.setSex(personDO.getSex());
                personInfoDTO.setId(personDO.getId());
                for (int j = 0; j < addressSize; j++) {
                    AddressDO addressDO = addressDOList.get(j);
                    if (addressDO.getName().equals(personInfoDTO.getName())){
                        personInfoDTO.setAddress(addressDO.getAddress());
                        personInfoDTOList.add(personInfoDTO);
                    }
                }
            }
            Page<PersonInfoDTO> personInfoDTOPage = new Page<>();
            personInfoDTOPage.setRecords(personInfoDTOList);
            long endTime = System.currentTimeMillis();
            long usedTime  = endTime - startTime;
            System.out.println(usedTime);
            return personInfoDTOPage;
        }
    
     <!--name 加了索引-->
     <select id="getPersonByJoin" resultType="com.hpy.convertfoodemo.convert.entity.DTO.PersonInfoDTO">
            select t1.id,
                   t1.name,
                   t1.sex,
                   t2.address
            from test.person t1
            left join test.address t2 on t1.name = t2.name
     </select>
    
    14 条回复    2020-11-14 14:46:18 +08:00
    taogen
        1
    taogen  
       2020-11-13 23:32:18 +08:00 via Android
    1. 代码有个错误,personInfoDTOList.add(personInfoDTO); 把这行放到第一层 for 循环最后一行而不是第二层 for 循环。修改后再试试时间吧。
    2. 数据库 join 也和两层 for 循环类似,数据库可以有索引(索引效率 n^2 => nlogn ),Java 也可以构建类似索引,如 hashmap 。
    3. 建议 Java 中构建索引(把第二层 for 循环用 addressMap.get(person.getAddress()) 替代,再试试时间效率。
    taogen
        2
    taogen  
       2020-11-13 23:33:21 +08:00 via Android
    代码错误 2:
    if (addressDO.getName().equals(personInfoDTO.getName()))
    to
    if (addressDO.getName().equals(personInfoDTO.getAddress()))
    taogen
        3
    taogen  
       2020-11-13 23:47:34 +08:00 via Android
    另外,测试 SQL 执行时间。SQL 应该直接在数据库中执行,不要用 JDBC 。
    xuanbg
        4
    xuanbg  
       2020-11-14 08:04:53 +08:00   ❤️ 1
    所谓屎味代码,归纳下来就是这几种情况:
    1 、多余,绕来绕去不知所云的无效代码。解决办法:理清业务逻辑,干掉重写。
    2 、逻辑不完备,一旦出现特殊情况就会出 bug 。解决办法:多分析,然后进行归纳,使归纳后的逻辑能覆盖所有的可能性。
    3 、低效,使用了不合适的方法处理数据。解决办法:不要因循守旧,也不要人云亦云。扩展视野,多尝试新技术新思路新方法。
    jzphx
        5
    jzphx  
       2020-11-14 08:50:51 +08:00   ❤️ 1
    有时候觉得自己写出了完美的业务代码,多一个字符都破坏美感,在产品刀架脖子的情况下不得不 if else
    hbolive
        6
    hbolive  
       2020-11-14 10:09:40 +08:00
    @jzphx 这种情况很常见
    HolmLoh
        7
    HolmLoh  
       2020-11-14 10:50:19 +08:00
    @jzphx #5
    经常碰到这种情况...我的做法是如果后续会拓展很多分支我就会开始翻设计模式
    noparking188
        8
    noparking188  
       2020-11-14 10:59:12 +08:00   ❤️ 1
    我每天工作都糊 💩 就很难受,祖传💩 ⛰ 愈发硕大,今天看昨天的代码很糟糕,明天看今天的代码也很糟糕,想去重写下需求太多又没时间,需求一波未完一波又起,赶着你糊 💩
    AEDaydreamer
        9
    AEDaydreamer  
       2020-11-14 11:32:32 +08:00
    @noparking188 太精辟了,第二天 review 一下代码发现能优化的地方很多.可是新的需求又来了,真的没时间改.
    fangcan
        10
    fangcan  
       2020-11-14 13:23:50 +08:00
    你们重构完不需要测试部再测下么?还是都是自己测试吗
    uselessVisitor
        11
    uselessVisitor  
    OP
       2020-11-14 13:54:34 +08:00
    @taogen 感谢
    darklowly
        12
    darklowly  
       2020-11-14 14:41:27 +08:00   ❤️ 1
    1 好好写注释,注释的格式是 // 后需要空格

    2 好好排版,把代码分成逻辑上的段

    3 好好取名字 getPersonByJava,这个名字看起来是单数,正常情况下应该是 listUsers

    4 不熟悉 java 不知道 personMapper.selectPage 是干嘛的,选择某一页?

    5 分解为两个函数,可能更快,伪代码

    UserDTO getUserByID(string id) {
    user = getUserRecord(id)
    addr = getAddrRecord(id)
    return buildUserDTO(user, addr)
    }

    Page<UserDTO> listUsers() {
    // 分页查询用户 ID,具体的看你框架的语法
    ids = queryUserIDs()

    usersDTO = new ArrayListXXXXXXXXXXXX()
    for (id := range ids) {
    user = getUserByID(id)
    usersDTO.add(user)
    }

    usersDTO
    }
    darklowly
        13
    darklowly  
       2020-11-14 14:42:43 +08:00
    1 好好写注释,注释的格式是 // 后需要空格

    2 好好排版,把代码分成逻辑上的段

    3 好好取名字 getPersonByJava,这个名字看起来是单数,正常情况下应该是 listUsers

    4 不熟悉 java 不知道 personMapper.selectPage 是干嘛的,选择某一页?

    5 分解为两个函数,可能更快,伪代码

    ```
    UserDTO getUserByID(string id) {
    user = getUserRecord(id)
    addr = getAddrRecord(id)
    return buildUserDTO(user, addr)
    }

    Page<UserDTO> listUsers() {
    // 分页查询用户 ID,具体的看你框架的语法
    ids = queryUserIDs()

    usersDTO = new ArrayListXXXXXXXXXXXX()
    for (id := range ids) {
    user = getUserByID(id)
    usersDTO.add(user)
    }

    usersDTO
    }
    ```
    darklowly
        14
    darklowly  
       2020-11-14 14:46:18 +08:00
    不知道怎么支持 markdown,将就看吧。

    还有一点,你的代码也是密密麻麻的,不好看。函数内部,不同的逻辑区,需要分段,段之间用一个空行隔开。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1448 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:29 · PVG 01:29 · LAX 10:29 · JFK 13:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.