“程序怎么运行不了,不应该啊?”

“程序怎么能运行了,不应该啊!”

这句话是不是让程序员朋友们的 DNA 动了呢?今天鱼皮分享一些新手程序员常犯的小 Bug,很多是我自己或者网友们的亲身经历,相信绝大多数程序员都写过这些 Bug~

程序员经典小 Bug

1、标点符号错误

刚学编程语言的很多同学应该都被这个错误折磨过,比如在代码中使用中文逗号()或引号(“”),结果就导致了编译错误。

// 使用了中文逗号,编译会报错
Map<String, Integer> map = new HashMap<>();
map.put("key1", 1);

我之前就遇到过一位同学,把类似上面的代码拍了个照,然后问我哪里有错,我当时快把眼珠子瞪出来了,也没发现问题:

结果后面他自己发现问题了,我知道真相后直接红温了。

其实这类 Bug 很好自己解决,开发工具都会给出提示的,只不过由于新手不知道要去看错误信息罢了。

2、更新数据没指定范围

现在的数据库操作框架封装得太好了,以至于很多同学都不怎么自己写 SQL,查询语句可能还写过一点儿,但更新语句基本上没写过。这就导致了很多低级问题,比如在更新或删除数据时,忘记加上 WHERE 条件。像之前我分享过,我们团队一位同学更新某个用户权限的时候,不小心把所有用户的权限都刷成了 “管理员”。

UPDATE orders SET role = 'admin';

一般有经验的开发者看到数据更新或删除操作,就条件反射想到要加 WHERE 条件:

UPDATE orders SET role = 'admin'
WHERE id = xxx

企业中通常也会给数据库加上限制,防止范围更新和删除。

3、资源忘记释放

在开发中,文件、数据库连接、内存、网络连接都属于资源,如果打开了资源没有释放,就有可能因为资源泄露导致程序崩溃,很多线上 Bug 都是这么来的。

比如打开一个文件,却没有关闭:

public void readFile(String path) throws IOException {
   FileReader reader = new FileReader(path);
   char[] buffer = new char[1024];
   reader.read(buffer);
   // 忘记关闭文件
}

平时要养成好的习惯,只要打开了资源,都要看看有没有 close 方法。如果有的话,再确认该资源会不会自动关闭;如果不会自动关闭,就要手动释放资源。

在 Java 中,可以在 finally 块中、或者使用 try-with-resources 语法自动释放资源:

public void readFile(String path) throws IOException {
   try (FileReader reader = new FileReader(path)) {
       char[] buffer = new char[1024];
       reader.read(buffer);
  }
}

4、明文存储隐私数据

这也是一类低级错误,比如在数据库中明文存储用户的密码:

INSERT INTO users (username, password)
VALUES ('admin', '123456');

好好好,这下管理员爽翻了!

标准做法是,使用哈希算法 + 盐值加密存储密码:

String hashedPassword = BCrypt.hashpw("123456", BCrypt.gensalt());

虽然这个错误很低级,但可千万别小看它。某公司因为明文存储密码被处罚了 9100 万欧元!

类似的错误还有直接从前端明文发送密码给后端,虽然可以通过 HTTPS 协议增强安全性,但 HTTPS 只保证传输加密,服务端和客户端仍能看到密码明文,攻击者可能通过日志窃取密码。

5、前端存储秘钥

这也是一类低级错误,经常出现于调用第三方 API 的时候。

比如需要调用一个第三方天气服务 API,为了省事,前端直接将秘钥写到了 JS 代码中:

// 第三方 API 秘钥
const API_KEY = "yupi123456";
// 调用 API
async function getWeather(city) {
 const url = `https://codefather.cn/weather?city=${city}&apikey=${API_KEY}`;
 const response = await fetch(url);
 const data = await response.json();
 console.log(data);
}

这样一来,用户直接打开 F12 控制台,就能看到你的秘钥了,即使对 JS 代码加密混淆,也能轻而易举被找到。

所有前端的内容都是不安全的。 如果有调用第三方 API 的需求,最好还是通过后端进行转发。

6、忘记区分环境

刚在企业中接触多环境的同学,可能会不小心把测试环境的代码或配置部署到生产环境。

比如 Java 项目使用 application.yml 文件来管理配置,测试代码时,我先把数据库改为测试库:

spring:
datasource:
  url: jdbc:mysql://localhost:3306/dev_db

结果上线前,忘了把配置改回来,导致线上环境找不到这个数据库或者因为网络隔离无法连接。

标准的做法是,通过配置文件后缀区分多环境,在启动项目时指定对应的环境值即可。比如 application-dev.yml 表示开发环境、application-prod.yml 表示生产环境。

7、强行合并或推送代码

我见过一些急性子的同学,在提交或推送代码的时候遇到了代码冲突,觉得麻烦就强行合并或推送了。

# 忽略代码冲突,强行合并
git merge branch-feature --strategy-option=theirs

# 强行推送,覆盖远程代码
git push --force

此举可谓图一时之快,但后患无穷矣。

很快你的同事就会找上门:我的码呢?

你的领导也会找上门:没通过审核的代码怎么就推到主分支了?

所以遇到代码冲突之后,一定要仔细处理冲突,不要强行合并或推送,除非你能接受这么做的最坏结果。

对于管理者,最好在代码管理平台中开启保护分支,禁止成员把未审核通过的代码直接推送到主分支。

8、提交敏感信息

很多朋友的数据保护意识是比较差的,尤其是刚接触 Git 代码提交的同学,可能一不小心,就把包含了数据库账号密码的配置文件提交到 GitHub 等开源平台了,开源精神令人感动。

不信的话,你可以在 GitHub 搜索和秘钥有关的关键词,一抓一大把。

我自己也经历过这事,曾经提供了一个免费的图床给编程导航的同学使用,结果有不止一个人把我的图床秘钥开源到了 GitHub 上。

好在有些大厂的云服务会自动检测你有没有将秘钥提交到开源平台,如果出现了,会给你发送邮件。

解决这个问题的方法也很简单,我们可以准备两套配置文件,一套开源,一套自用,在 Git 中忽略掉自用配置文件的提交即可。


OK 就分享到这里,大家还见过哪些常见的、或者 “有点儿东西” 的 Bug 呢?欢迎评论区分享~

更多编程学习资源

这些小 Bug,99% 的程序员都写过!的更多相关文章

  1. 99%的程序员都在用Lombok,原理竟然这么简单?我也手撸了一个!|建议收藏!!!

    罗曼罗兰说过:世界上只有一种英雄主义,就是看清生活的真相之后依然热爱生活. 对于 Lombok 我相信大部分人都不陌生,但对于它的实现原理以及缺点却鲜为人知,而本文将会从 Lombok 的原理出发,手 ...

  2. 听说,99% 的 Go 程序员都被 defer 坑过

    原文链接: 听说,99% 的 Go 程序员都被 defer 坑过 先声明:我被坑过. 之前写 Go 专栏时,写过一篇文章:Go 专栏|错误处理:defer,panic 和 recover.有小伙伴留言 ...

  3. 【Mood-10】每个程序员都应该读的30本书

    “如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西.” 很多程序员响应,他们在推荐时也写下自己的评语. ...

  4. StackOverflow程序员推荐:每个程序员都应读的30本书

    “如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西.” 很多程序员响应,他们在推荐时也写下自己的评语. ...

  5. 【转】StackOverflow程序员推荐:每个程序员都应读的30本书

    “如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西.” 很多程序员响应,他们在推荐时也写下自己的评语. ...

  6. 每个程序员都应该了解的 CPU 高速缓存

    每个程序员都应该了解的 CPU 高速缓存 英文原文:Memory part 2: CPU caches 来源:oschina [编者按:这是Ulrich Drepper写“程序员都该知道存储器”的第二 ...

  7. 关于Unicode,字符集,字符编码,每个程序员都应该知道的事

    关于Unicode,字符集,字符编码,每个程序员都应该知道的事 作者:Jack47 李笑来的文章如何判断一个人是否聪明?中提到: 必要.清晰.且准确的概念,是一切思考的基石.所谓思考,很大程度上,就是 ...

  8. 每个程序员都应该学习使用Python或Ruby

    每个程序员都应该学习使用Python或Ruby 如果你是个学生,你应该会C,C++和Java.还会一些VB,或C#/.NET.多少你还可能开发过一些Web网页,你知道一些HTML,CSS和JavaSc ...

  9. 为什么二流程序员都喜欢黑php?

    为什么二流程序员都喜欢黑php? 为什么程序员都喜欢黑php?这个嘛!你骂一句php是垃圾试试,保准php程序员不揍扁你!这就好像自己的母校,纵然有很多不好的地方,但是只允许自己调侃,不允许外人骂半句 ...

  10. 把99%的程序员烤得外焦里嫩的JavaScript面试题

    最近有学员给出一段令人匪夷所思的JavaScript代码(据说是某某大厂面试题),废话少说,上代码:   var a = 10; { a = 99; function a() { } a = 30; ...

随机推荐

  1. python之调用高德、百度api解析经纬度地址

    调用高德 # 高德地图根据经纬度反查地址,每天只能调用5000次 def gaode_excute_single_query(coordStrings ,currentkey='你自己的api-key ...

  2. My SQL 列转行操作

    原表结构如下,我们可以发现,"日运输量"和"车次"是在同一张表中相互独立的两个字段,即独立的两列数据,下面,我将系统中的测试数据以及代码全部放出来,以解释列转行 ...

  3. UniswapV2Factory细节

    UniswapV2Factory合约是Uniswap V2协议中的关键部分,负责管理和创建所有的流动性池(交易对).以下是对UniswapV2Factory合约中所有主要方法及其参数的详细讲解. 方法 ...

  4. Antlr4 语法解析器(下)

    Antlr4 的两种AST遍历方式:Visitor方式 和 Listener方式. Antlr4规则文法: 注释:和Java的注释完全一致,也可参考C的注释,只是增加了JavaDoc类型的注释: 标志 ...

  5. Air780E软件指南:UDP应用示例

    一.UDP概述 UDP(用户数据报协议,UserDatagramProtocol)是一种无连接的.不可靠的传输层协议,主要用于实现网络中的快速通讯.以下是UDP通讯的主要特点: 1.1 无连接通讯: ...

  6. CF2023C C+K+S 题解

    题面 给您两个强联通的 \(^{\dagger}\) 有向图,每个图都有精确的 \(n\) 个顶点,但可能有不同数量的边.仔细观察后,您发现了一个重要特征--这些图中任何一个环的长度都能被 \(k\) ...

  7. 开发工具之DevToys

    DevToys 号称开发人员的瑞士军刀,可以帮助完成一些日常任务,比如格式化 JSON.比较文本.测试正则等,无需使用许多不真实的网站来处理的数据. 借助智能检测,DevToys 能够检测出可以处理在 ...

  8. Redis集群搭建-多服务器

    条件 l 基于redis5.0.*版本进行集群的搭建 l 集群要求至少六个节点,即每个主节点配置1个从节点,本集群是使用了3个主节点并每个下面挂一个从节点,三个主节点分布在3台服务器上 l 集群配置信 ...

  9. Node.js Express 框架(1)

    1.Express介绍 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. Express的特点: 实现 ...

  10. Kettle连接MySQL数据库时提示Driver class 'org.gjt.mm.mysql.Driver' could not be found

    使用Kettle连接MySQL数据库时,提示以下连接提示信息导致我们无法对数据库进行连接: Driver class 'org.gjt.mm.mysql.Driver' could not be fo ...