你知道的,我们上午是不写代码的!

8,241 阅读8分钟

刚入职的实习生总会问:“哥,你们为啥上午都不写代码啊?一个个对着屏幕划水,到了下午就跟打了鸡血一样敲键盘?”

我笑着拍了拍他的肩膀:“这不是划水,是程序员的‘上午蓄力法则’——真正的程序员,上午从来不是用来写代码的,而是用来‘避免下午写垃圾代码’的。”虽然表面上你会准备以下几种说辞:

  1. 上午要开会解决oncall哪有时间写呀
  2. 昨天加班晚了,得先把昨天的事情沉淀沉淀
  3. 小同志,上厕所,打水,吃午饭都要排队滴,不要太急,给自己留点buffer~
  4. 哪有时间balabala,真羡慕你可以有大块时间写代码!

很多外行人甚至刚入行的新人都以为,程序员的工作就是“坐在电脑前敲代码”,但实际上,写代码只占程序员工作的40%,剩下的60%,全是“铺垫工作” ——而这些铺垫,恰恰最适合放在上午完成。

今天就用程序员能看懂的方式(架构图、流程图、伪代码),好好聊聊:为啥正常程序员,上午都不写代码?

先上结论:上午的核心任务,是“拆解问题”,不是“解决问题”

程序员的工作,本质上是“将复杂需求转化为可执行代码”的过程。这个过程就像盖房子:上午是“画图纸、备材料、定方案”,下午才是“搬砖砌墙”。

如果上午直接上手写代码,就相当于“没画图纸就开始砌墙”——看似高效,实则大概率会出现“砌到一半发现墙歪了、材料不对了、结构错了”,最后只能推倒重来,反而更浪费时间。

我们先通过一张程序员每日工作架构图,看看上午和下午的工作重心差异:

image.png

从架构图能清晰看到:上午的“蓄力层”是下午“执行层”的基础,没有上午的充分准备,下午的代码编写就会充满阻碍——要么卡在校验逻辑,要么停在依赖缺失,要么写一半发现需求理解错了。

这也是为啥我们常说:上午多花1小时梳理,下午能省3小时返工

流程图拆解:上午不写代码,到底在忙啥?

很多人觉得“上午不写代码就是摸鱼”,其实是没看到程序员上午的“隐性工作”。我们用一张上午工作流程图,还原程序员的真实上午:

image.png

这张流程图,每一步都在为“下午高效写代码”铺路:

  • 需求梳理:避免“理解偏差”导致代码返工;

  • 方案推演:避免“技术选型错误”导致后期重构;

  • 环境准备:避免“下午编码到一半,发现环境崩了”的尴尬。

举个真实例子:之前有个实习生,入职第二天就上午直接写代码,结果写了2小时,发现自己理解的需求和产品要的完全不一样,接口依赖也没确认,最后只能全部删掉——这就是“上午不蓄力,下午白费力”。

伪代码佐证:上午写代码,为啥效率极低?

我们用一段“伪代码”,模拟“上午直接写代码”和“上午蓄力、下午写代码”的效率差异,就能直观感受到为啥上午不适合写代码。

场景:实现一个“用户登录校验”功能

反面案例:上午直接写代码(效率极低)

// 上午9:30,直接上手写代码,未梳理需求和依赖
public class LoginController {
    // 1. 未确认需求:不知道需要校验手机号/邮箱,还是两者都支持
    // 2. 未确认依赖:不知道用户数据库接口是否就绪
    // 3. 未推演逻辑:未考虑密码加密、token生成、异常处理
    
    public Result login(String account, String password) {
        // 第一步:写登录校验,发现不知道account支持什么格式
        if (account == null || account.isEmpty()) {
            return Result.fail("账号不能为空");
        }
        // 此时才去问产品:账号支持手机号还是邮箱?(浪费10min)
        // 产品回复:两者都支持,需要分别校验格式
        // 返工:添加格式校验
        if (!isPhone(account) && !isEmail(account)) {
            return Result.fail("账号格式错误(手机号/邮箱)");
        }
        
        //------------------------------------
        // *****老板:昨天的会议待办咱对一下~~~~
        //------------------------------------
        
        // 第二步:查询用户,发现数据库接口未对接(浪费20min)
        UserService userService = new UserService();
        User user = null;
        try {
            user = userService.getUserByAccount(account);
        } catch (Exception e) {
            // 排查发现:数据库连接未配置,接口未开发完成
            return Result.fail("服务异常,请稍后再试");
        }
        
        // 第三步:密码校验,发现未确认密码加密方式(浪费15min)
        // 去问后端同事:密码是MD5加密还是BCrypt加密?
        // 同事回复:BCrypt加密,需要调用工具类
        // 返工:添加密码加密校验
        if (!BCrypt.checkpw(password, user.getPassword())) {
            return Result.fail("密码错误");
        }
        
        //------------------------------
        // *****插入事项:线上来问题了~~~~
        //------------------------------
        
        // 第四步:生成token,未考虑token过期时间(浪费10min)
        String token = TokenUtil.generateToken(user.getId());
        // 产品提醒:token过期时间需要设为2小时
        // 返工:修改token生成逻辑
        String token = TokenUtil.generateToken(user.getId(), 7200);
        
        // 第五步:未考虑异常场景(如用户被禁用)
        // 测试提醒:需要校验用户状态
        // 返工:添加用户状态校验
        if (user.getStatus() == 0) {
            return Result.fail("账号已被禁用");
        }
        
        return Result.success(token);
    }
    
    // 额外浪费时间:上午思路混乱,代码冗余、格式不规范,下午还需要重构(浪费30min)
}

统计:上午写代码,总共花费2小时,其中返工+等待时间占1小时45min,有效编码时间仅15min 。。。

正面案例:上午蓄力,下午写代码(效率极高)

    // 上午9:30-12:00,蓄力准备(不写核心代码)
    // 1. 需求梳理(30min):确认账号支持手机号/邮箱,需要校验格式;密码BCrypt加密;token过期2小时;校验用户状态
    // 2. 依赖确认(20min):确认用户数据库接口已开发完成,数据库连接配置就绪;Token工具类可用
    // 3. 逻辑推演(40min):梳理执行流程,预判异常场景(账号为空、格式错误、密码错误、用户禁用、服务异常)
    // 4. 准备测试用例(20min):设计正常登录、异常场景的测试数据

    // 下午14:00,开始写代码(思路清晰,无返工)
    public class LoginController {
        @Autowired
        private UserService userService;
        
        public Result login(String account, String password) {
            // 1. 账号非空校验
            if (account == null || account.isEmpty()) {
                return Result.fail("账号不能为空");
            }
            // 2. 账号格式校验(手机号/邮箱)
            if (!isPhone(account) && !isEmail(account)) {
                return Result.fail("账号格式错误(手机号/邮箱)");
            }
            // 3. 查询用户,处理服务异常
            User user;
            try {
                user = userService.getUserByAccount(account);
            } catch (Exception e) {
                log.error("查询用户异常:{}", e.getMessage());
                return Result.fail("服务异常,请稍后再试");
            }
            // 4. 用户不存在校验
            if (user == null) {
                return Result.fail("账号或密码错误");
            }
            // 5. 密码校验(BCrypt加密)
            if (!BCrypt.checkpw(password, user.getPassword())) {
                return Result.fail("账号或密码错误");
            }
            // 6. 用户状态校验(未禁用)
            if (user.getStatus() == 0) {
                return Result.fail("账号已被禁用");
            }
            // 7. 生成token(过期2小时)
            String token = TokenUtil.generateToken(user.getId(), 7200);
            
            return Result.success(token);
        }
    }

统计:下午写代码,总共花费40min,无返工,代码规范,可直接测试

两段伪代码对比,差距一目了然:上午直接写代码,大部分时间都浪费在“返工、等待、排查问题”上;而上午做好蓄力准备,下午写代码就能“一气呵成”,效率提升3倍以上。

不是“不写代码”,是“不盲目写代码”

最后必须澄清一点:程序员上午不写代码,不是“摸鱼”,而是“不盲目写代码”。

真正高效的程序员,都懂“蓄力比执行更重要”——上午的每一份准备,都是为了下午能更专注、更高效地写代码,避免做“无用功”。

就像我们常说的:程序员的核心竞争力,不是“敲代码的速度”,而是“解决问题的效率” 。上午梳理清楚问题,下午就能快速解决问题;上午盲目敲代码,下午就只能在返工中内耗。

所以下次再看到程序员上午对着屏幕“划水”,别再以为他们没干活——他们可能正在梳理需求、推演方案、准备环境,为下午的“代码冲刺”蓄力呢!

最后送所有程序员一句梗式真理:上午不写代码,不是不 ,是缓写,慢写,优写,有次序的写——让梳理好的需求先写,让没有依赖的模块先写,让预判好的逻辑先写,才能先写带动后写;也要具体情况具体写,上午蓄力、下午写代码,不管早写晚写,能写出无bug、高可用的代码,都是好代码!

互动话题

你上午会写代码吗?有没有过“上午写代码,下午全删掉”的尴尬经历?欢迎在评论区分享你的日常工作节奏~

关注我,分享更多程序员日常、技术干货,带你看透程序员的“摸鱼式高效”!