为什么 StackOverflow 上的代码片段会摧毁你的项目?
昨天公司里碰到一件令人哑然失笑的事情。帮朋友公司做的一个项目,做SIT测试的时候发现一些bug,仔细查了下原因,原来是因为当初觉得这个项目比较简单,交给了几个新入职的新丁,也算是给他们练练手,结果其中一位写了一段代码出现了问题结果导致bug的出现。
虽然问题不大很快就修复了,但是正所谓初生牛犊不怕虎,这位出问题的新丁不太服气,一直嚷嚷着他这段代码是从CSDN上找到的,别人都说好用他才用的。问了问他是否理解原文中那么写的原因,结果才支支吾吾了半天讲不清楚,最后也承认他只是看到那段代码的结果是他要的,并不是理解中间一些方法的运用到底是什么逻辑。
真是又好气又好笑,想想现在的年轻人真是有个性,自己当年遇到这种情况只敢虚心求教,哪敢都没明白就去用一段代码,别人指出问题还忿忿不平。
也许是自己老了吧。晚上和一个刚从国外归国的同学说起这个事情,他倒是深有体会,说到他们在国外留学时,遇到技术问题想到网上咨询用的最多的是StackOverflow,相比起国内的CSDN,他觉得StackOverflow上提问题的人和回答的人都更加严谨,不会有太多的废话和问题之外的讨论。按他的理解,CSDN上很多国内的技术新手纯粹是缺乏独立思考的能力,都只是来求代码完成目标,不去探究为什么这么写,本身CSDN上问题回答质量不高,这样很容易出事。
同学的看法,一方面可能是因为国内程序员需求极大,但整体浮躁、功利性的大环境导致很多培训机构没有培训到位,很多程序员都是一边开始工作一边学习;但另一方面,不排除他崇洋媚外的自满情绪。于是,我便去查阅了下StackOverflow上面的内容和相关资料。

仔细研究后发现,其实StackOverflow没有同学说的那么好,即使是该网站上的回答,也有很多有问题的代码。看来这还是一个世界性通用的难题~
对于国外的程序员来说,StackOverflow就是他们的CSDN,是他们遇到各种问题查询的第一选择,很多国外的程序员,会到StackOverflow上需求帮助,找到他们需要的解决问题的代码,然后不假思索的直接复制使用,和我公司出问题的那位年轻人一样,这个习惯很不好。
代码复制本身来说并不是什么坏事,我们学开发的时候,肯定老师都教过我们代码复用能有效提高软件的开发效率。已经被解决了的问题,实在没有必要再去重新写一遍代码。但是这个前提是,使用者,也就是开发人员,必须知道你要用的这段代码的来龙去脉真正含义,就是你要真正明白你用的代码。
简单举个例子:
- 几年前,很多程序员发现,在windows上使用Docker老是会碰到无法启动的问题,原因一直不明,很多人都是重装了系统什么的才解决。后来有一个大神发文解释原因后我们才知道了为什么
当 Windows 后台启动了 Razer Synapse 时,再去启动 Docker 就会触发此问题。根本原因是,Razer Synapse 运行后,Docker 就会认为已经有一个 Docker 实例正在运行中,所以不会再启动一个实例,也就是真的Docker。
为什么会有这种情况呢?
因为有一段代码中,返回的 GUID 类型是 System.Reflection.RuntimeAssembly(系统层面的运行时程序集),而不是 Windows 中对应 Docker 程序集中定义的类型。Docker处理的逻辑就是在同一时间只允许运行一个实例,判断的方式就是通过判断 GUID 是否存在,但在获取GUID 时,用的是系统层面的而非自己独立程序集里面,从而导致了这个问题。问题代码如下:
var name = string.Format("Global\{0}", (object)
Assembly.GetExecutingAssembly().GetType().GUID);
当然了,如果系统只有一个应用程序使用了上面的错误代码,那么这个问题还是不会出现,因为只有一个实例。但实际情况是很多应用程序都使用了这一段错误代码,结果就不允许两个实例同时运行。
那这些应用程序,想必你已经猜到,都用了这段代码,而且都是从StackOverflow上下载后不假思索的使用导致的。
- Andreas Lundblad,国外一位大神,Palantir 的 Java 开发人员,同时也是 StackOverflow 上排名最高的贡献者之一。
他有一段代码,作用是将字节计数转换为更易于阅读的格式。打个比方,1024字节转换为1kB,1048576 字节转换为1MB。他最初在2010年将这一段代码放到了StackOverflow上,根据官方统计,他的这段代码是StackOverflow上被拷贝次数最多的Java代码,GitHub上使用这段代码的项目有6千多个。
当Andreas Lundblad知道此事后,出于负责,很小心谨慎的重新检查了下这段代码,随后发现这段代码里有一些问题,于是他马上更新了版本,并发博告诉大家:
- StackOverflow 上的代码可能存在 bug,不管他的好评是多少。
- 如果你拿了StackOverflow的代码,一定记住要测试所有的可能的情况。
- 在复制代码时,一定要包括其来源和贡献者,当出问题时,能快速帮你定位。

同样的,在去年,国外另一位大神Morteza Verdi发表了一篇研究论文指出,StackOverflow上流传最广的一段c++代码存在着69个重大安全隐患漏洞,GitHub上使用这段C++代码的项目也有近3千多个。
所以,无论是StackOverflow还是CSDN,无论是国外和国内,都务必记住一点,在复用别人的代码时,一定要搞清楚别人代码的含义,并做好充分的测试工作,并不是说你运行了一次没问题,就是真的没问题,可能只是你运气好,没有触发问题场景罢了。
引用 Ryan Donovan 的一句话,就是:
If you borrow things and you don’t understand the content of what you’re borrowing, then you fall in this trap of reusing code that has potential vulnerabilities. Then you are just spreading those things around.”
If you’re going to reuse code, you need to understand that code.
复用代码,一定要理解代码!
你复用代码时遇到过什么问题?一起讨论下吧!
欢迎关注我的公众号:程序猿DD,获得独家整理的免费学习资源助力你的Java学习之路!另每周赠书不停哦~
为什么 StackOverflow 上的代码片段会摧毁你的项目?的更多相关文章
- 微信小程序开发——上传代码片段到git仓库
微信开发者工具除了自带的git版本管理(本地服务)之外,还可以推送到在线git仓库中去,这样别人也可以通过git来拉取你的代码片段或小程序. 一.1.登录git 一.2.点击创建项目 一.3.填写项 ...
- SSH文件上传代码片段
一.文件上传限制: 在web.xml中配置Struts前端控制器时,设置初始化参数:如下图所示 二.controller代码 @Namespace("/") @ParentPack ...
- (转:亲测)cnblogs博文浏览[推荐、Top、评论、关注、收藏]利器代码片段
authour: Others(hoojo) updatetime: 2015-04-25 09:30:23 friendly link: http://www.cnblogs.com/hoojo/a ...
- VSCode保存插件配置并使用 gist 管理代码片段
setting sync 保存配置 由于公司和家里都使用 VSCode 作为主要编辑器,同步配置是最紧要的.VSCode 提供了setting sync插件,很方便我们同步插件配置.引用网上教程: 在 ...
- Visual Studio使用技巧,创建自己的代码片段
1.代码片段的使用示例 在编写代码中常会使用代码片段来提高我们的编写代码的效率,如:在Visual Studio中编写一个 for(int i = 0; i < length;i++) { } ...
- VS Code项目中共享自定义的代码片段方案
VS Code项目中共享自定义的代码片段方案 一.问题背景 项目中注释风格不统一,如何统一注释风格 一些第三方组件库名称太长,每次使用都需要找文档,然后复制粘贴 部分组件库有自己的Snippets插件 ...
- 拥有的50个CSS代码片段(上)
1. CSS 重置 ;;;font-size: 100%; font: inherit; vertical-align: baseline; outline: none; -webkit-box-si ...
- 127个常用的JS代码片段,每段代码花30秒就能看懂(上)
127个常用的JS代码片段,每段代码花30秒就能看懂(上) JavaScript 是目前最流行的编程语言之一,正如大多数人所说:“如果你想学一门编程语言,请学JavaScript.” FreeCode ...
- iPhone较为基础的代码片段
Iphone代码片段导航 1.给UITableViewController添加ToolBar. self.navigationController.toolbarHidden = NO; //默认是隐 ...
随机推荐
- Java多线程中的虚假唤醒和如何避免
先来看一个例子 一个卖面的面馆,有一个做面的厨师和一个吃面的食客,需要保证,厨师做一碗面,食客吃一碗面,不能一次性多做几碗面,更不能没有面的时候吃面:按照上述操作,进行十轮做面吃面的操作. 用代码说话 ...
- Spring Cloud 学习 (三) Feign
新建 spring-cloud-eureka-feign-client Module pom <parent> <artifactId>spring-cloud-parent& ...
- Python中判断字符串是否为数字、字母、标识符、浮点数、大小写、可打印的方法
1.判断s是否都是大写字母:s.isupper(): 2.判断s是否都是小写字母:s.islower(): 3.判断s中的每个单词首字母是否都是大写字母且其他位置无大写字母:s.istitle(),要 ...
- PyQt(Python+Qt)学习随笔:QTableWidget设置项的setItem方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget表格部件中setItem用于在表格部件QTableWidget创建后,设定指 ...
- luogu P6835 概率DP 期望
luogu P6835 概率DP 期望 洛谷 P6835 原题链接 题意 n + 1个节点,第i个节点都有指向i + 1的一条单向路,现在给他们添加m条边,每条边都从一个节点指向小于等于自己的一个节点 ...
- git clone 速度太慢解决方法
本来想下载一个翻墙软件,实在是忍受不了每秒十几K的龟速,查阅各种资料,终于找到了失传已久的秘籍 先附图,实测有效,这速度简直要上天了啊啊啊啊啊(只支持HTTPS方式,SSH无效) 方案:使用githu ...
- selenium.common.exceptions.WebDriverException: Message: 'chromedriver'解决
相信很多第一次学习selenium的同学们也对这个异常不陌生了,但具体该如何解决这个bug呢? 主要的原因还是因为selenium模拟的客户端对浏览器的操作,但相应浏览器的驱动版本不匹配导致的. 为了 ...
- mycat启动失败
1.问题 使用mycat配置主从读写分离,启动mycat报错信息如下: STATUS | wrapper | 2020/06/17 17:00:11 | --> Wrapper Started ...
- 遍历出字母A-Z(a-z)的四种方式
# 四种方式打印出A-Z(a-z) import string l1 = [chr(i) for i in range(ord("A"), ord("Z") + ...
- Collections.synchronizedList 并发
1.背景 集合类中的map,大家一定熟悉,知道它非线程安全.使用的方法有两种,一种是在map上加同步器(锁),另一种是创建容器时使用Collections中的静态方法对map进行包装. java ap ...