网友吐槽:刚入职一周的同事提交了一个新增 2w和删减1.4w的代码,不想review代码,头大~

文摘   2024-12-11 15:41   陕西  

作为一名程序员,每次看到这种吐槽,总有种深有同感的感觉。

说实话,刚入职一周的同事就提交了一个新增2w行代码、删减1.4w行代码?这就有点“让人头大”了啊 😂。

这种情况其实很常见,尤其是对刚入职的新手来说,他们往往对公司的代码库和现有架构不够熟悉,代码写起来往往很“放飞自我”。

你说他写得不对吧,毕竟新手嘛,也不能太过苛责;但从开发者的角度来看,提交这么大一波改动,简直就是给reviewer带来了巨大的心理负担和代码维护的压力。谁能看得下去啊?还不如直接带个链接,把整个项目给改了算了 🧐。

我觉得最关键的还是沟通。新同事在提交这种大规模改动前,应该先和团队的资深开发讨论一下,明确哪些是必须的,哪些可以优化,避免盲目“干掉”一大堆代码。毕竟,维护性和可读性才是代码的灵魂呀。

所以,大家在面对这种时,可能需要心态放平,不仅要耐心审查代码,还得给新手一些指导,不然自己也会变成“代码审查的老大难” 😅。

算法题:解数独

嗨,大家好!今天我们来聊聊一个经典的编程题:数独。说到数独,相信很多人都不陌生,尤其是对于我们程序员来说,这种题目就是练手的好材料。它不仅能锻炼你的逻辑思维,还能提升你对于回溯算法的理解。

今天我们就用Java来解一下这个问题,当然,不仅仅是给你代码,而是通过它,让我们更加深入地理解背后的算法思想。

首先,我们来回顾一下数独的规则:

  • 数独是一个9x9的矩阵,每个小格子内填一个数字。
  • 每行、每列和每个3x3的小格子里,数字1到9不能重复。
  • 你需要填充的数字是那些为空的格子,目标是填充整个棋盘,使得所有的行、列、3x3小格子都符合数独的规则。

要解决这个问题,回溯算法(Backtracking)无疑是最合适的选择。为什么?因为数独的本质是一个“试探-回退”的过程。你尝试填充某个数字,如果填充后规则没有被破坏,你就继续填下一个数字;如果规则被破坏了,那就回退到上一步,换个数字再试。这不就和回溯算法的思想一模一样吗?

好了,我们直接进入代码吧。

public class SudokuSolver {
    public void solveSudoku(char[][] board) {
        solve(board);
    }

    private boolean solve(char[][] board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                // 找到一个空格
                if (board[i][j] == '.') {
                    // 尝试1-9数字
                    for (char num = '1'; num <= '9'; num++) {
                        if (isValid(board, i, j, num)) {
                            board[i][j] = num;  // 填充数字
                            
                            // 递归尝试填充剩下的格子
                            if (solve(board)) {
                                return true;
                            }
                            
                            // 如果当前数字填不下去,回退
                            board[i][j] = '.';
                        }
                    }
                    return false;  // 所有数字都不行,回退上一层
                }
            }
        }
        return true;  // 数独完成
    }

    private boolean isValid(char[][] board, int row, int col, char num) {
        // 检查行是否有重复数字
        for (int i = 0; i < 9; i++) {
            if (board[row][i] == num) {
                return false;
            }
        }
        
        // 检查列是否有重复数字
        for (int i = 0; i < 9; i++) {
            if (board[i][col] == num) {
                return false;
            }
        }
        
        // 检查3x3小格子是否有重复数字
        int startRow = row / 3 * 3;
        int startCol = col / 3 * 3;
        for (int i = startRow; i < startRow + 3; i++) {
            for (int j = startCol; j < startCol + 3; j++) {
                if (board[i][j] == num) {
                    return false;
                }
            }
        }
        
        return true;  // 通过所有检查
    }
}

这段代码的核心思想就是“试错+回退”。solve方法通过递归的方式,逐步填充空格。在每一次填充时,它都会调用isValid方法来验证填入的数字是否符合数独规则。如果当前数字符合条件,就递归尝试下一个格子;如果不符合规则,回退到上一层,换一个数字重新尝试。直至数独被填充完成。

对于回溯算法,可能有些同学听起来会觉得有点复杂,其实它就像是一个迷宫探索的过程——你在迷宫中尝试走不同的路,每走一条路,你都可能会碰到死胡同。如果遇到死胡同,你就退回来,换一条路继续走,直到找到正确的出口。

在实现数独时,isValid方法非常关键。它不仅检查当前行和列是否符合规则,还需要检查3x3小格子中的数字是否重复。至于3x3小格子的检查,我们通过计算出当前格子所在小格子的起始位置(startRowstartCol),然后遍历这个小格子中的所有元素。

这一点在代码中很巧妙,因为我们不需要为每一个3x3小格子写额外的代码,只需要通过简单的数学计算,就能确定当前格子属于哪个小格子。

代码优化

有些同学可能会觉得,数独的解法效率不高,毕竟在递归过程中,每一次都尝试1-9的数字,复杂度看起来不小。实际上,我们可以通过一些策略来优化代码:

  1. 先填最少空格的行、列或小格子。如果我们每次都选择填充空格最少的地方,可能会更早发现解,这样减少不必要的尝试。

  2. 行列小格子的标记。我们可以通过标记哪些数字已经出现过,来避免每次都进行完全的遍历检查。

不过对于大多数数独题目来说,当前的回溯方法已经足够高效。关键是要理解回溯

-END-


ok,今天先说到这,老规矩,给大家分享一份不错的副业资料,感兴趣的同学找我领取。

以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言

程序员老鬼
10年+老程序员,专注于AI知识普及,已打造多门AI课程,本号主要分享国内AI工具、AI绘画提示词、Chat教程、AI换脸、Chat中文指令、Sora教程等,帮助读者解决AI工具使用疑难问题。
 最新文章