一个新人如何学习在大型系统中添加新功能和Debug
文章背景:
今年七月份正式入职,公司主营ERP软件,楼主所在的组主要负责二次开发,使用的语言是Java。
什么叫二次开发呢?ERP软件的客户都是企业。而这些企业之间的情况都有所不同,一套标准版本的企业资源管理系统必然难以百分之一百地满足每一家公司的所有要求。所以,在客户提出需求之后,程序员对系统进行增减修改,这就是二次开发。
另外,我们组还负责修复客户报上来的各种漏洞。
学会如何添加新模块新功能
为什么说从头到尾只看代码是不可行的?
基本上,财务系统跨越的年限都会有十几二十年,代码数千万级别,更迭的版本多达十几个,更重要的是,连一份设计说明文档或者技术说明文档都没有。光看代码,根本就不可能准确地知道每一个类都是做什么的用的,类里面的方法是如何被调用,数据时如何流转处理的。
光靠猜,根本不可能猜出来。
熟悉代码的一个好方法就是做一个简单的新模块
以一个最简单的系统登录界面为例子(见上图),现在就来做一个练习:要求建立一个新的页面,把“物流管理系统”六个字改为“人事管理系统”,把“账号”改为“用户名”,把“密码”标签和栏位去掉,用户名正确即可直接登录。
代码都是现成了,直接新建相应的文件并且复制粘贴就行,再根据需求做更改。完成若干个这样的练习之后,就可以了解每个标签和栏位的作用,这是最快捷的方法。另外,我建议在看代码的同时写注释,有助于巩固记忆和加深理解。
复杂的功能要用到断点
如果把需求改为添加一个并不简单的功能呢?有的时候,我们可能不需要一个现成模块的所有内容和功能,只是把其中一个功能移植到另外一个模块当中去,显然是不可以简单粗暴地把所有的代码都复制过去,可是我们又不知道这个功能设计到哪些代码块,要怎么办呢?
这个时候,我们要用到断点(Break Point)调试。
如何添加断点,我这里就不赘述了,网上的教程一大把。如果有需要的话,我过几天找几篇好的综合一下给大家贴出来。
在调试的过程中,可以很轻松知道哪些方法牵涉其中,一一标记即可。
谈谈如何debug
首先,你要确定这到底是不是一个bug
一天,网管小明被一个上网的客人叫过去,说自己的QQ被盗了,肯定是在网吧的电脑中病毒害的,要求他负责。小明面无表情地按了一下键盘上的Caps Lock(大写锁定),然后让客人再输一次密码。然后,登陆成功。
上面举的这个例子是常识性的问题,但是很多时候用户犯的错误恰好是对系统的陌生,或者对业务知识的不熟悉。例如下面这么一个例子。前几天接到这么一个bug:用户要做一个付款单据,在付款单据页面中却读取不到。
这时候,如果我对这一个业务知识点不熟悉,很可能会先去查数据库,看是不是数据丢失了,或者是代码的问题,某一个筛选条件设错了。可当时我的第一反应就是,会不会他已经对该张欠款单做过付款单了?(ps:可以这么理解,一张欠款单已经做过了对应的付款单,意味着你们公司已经给对方付过钱了,不可能再付一次)
结果到他们的系统一看,果然如此。
在基本确定是一个漏洞之后,你最好能够在本地系统中重视这个故障
因为用户的系统都在使用当中,其中的数据也非常重要(分分钟几十万上下,出了问题码农搬十辈子砖都担不起),所以没办法任意地在用户的系统中做测试和验证。所以,你做好能够在本地系统中重视这个故障。
另外,在本地重视故障的过程中,你也会对这个故障发生的条件有一个更为全面的了解。例子:假设一天用户过来跟你说,他有这么一个瞬间,看太阳是绿色的,你就向他询问具体情况,以便重现。他告诉你说他昨天下午五点的抬头以仰角四十五度看太阳是绿色的,而且之前还连续看了三个小时的岛国爱情动作教育片。这个时候你就可以用同样的条件一试。如果试成功了,说明条件基本完全,如果不成功,还可以继续询问客户还是不是有其他的情况。
判断可能的方向,利用BreakPoint逐步缩小范围
在确定了客户所报上来的故障基本情况之后其实基本就可以知道bug可能的方向。例如前几天我接到了一个bug,说用户一直在用一个功能,平时都没事,知道周二那天下午突然就不行了。
查了相关的更新记录,那天并没有其他的同事对这个客户的代码进行更新,所以问题很有可能出现在数据库。后来发现,果然是用户做的一张单据的数量超过了系统限制,印发某个存储过程发生错误。
如果是代码方面的问题,我们可以用前面所讲过的断点测试逐步缩小可疑的范围,找到问题所在。例如一个数据发生了错误,我们可以从跟数据库交互的方法开始查看,直到最后显示数据的方法为止。参数传递过程中,可能中间经历了几个十几个,甚至几十个的方法,使用半分法设置断点就能够快速地定位问题的所在。
做完整的测试,证明自己的修复方案是正确可行的
一般来说,如果被一个bug纠缠了好几天,一旦找到了问题所在一定会高兴得要死,恨不得从椅子上跳起来。可这个时候,程序员们在欣喜之余要保持足够的冷静,因为你并不一定找到全部的答案,甚至根本就没有找到答案。
不止一次,我觉得我已经可以修复这个漏洞了,可当我以书面的形式提交修复方案的时候,总觉得不够有说服力,老大看到之后肯定会有所质疑。所以又缓了缓,再想了想,发现自己离发现问题的根本原因还差得远,更别提能够给出一个合理的解决方法。
所以我建议大家必须要在修复bug之后做完整的测试,直到证明自己的修复方案的确是完完全全地解决了问题,并且没有引入新的问题为止。
最后说几句题外话
好久没有写技术博客了。
正式上班其实也不算很忙,港资企业(深圳分公司)本来就节奏不快,再加上又不是互联网行业,加班几乎也就是意思意思,基本六点左右就可以走人。不过再怎样也没有在学校里面这么闲,所以前阵子就光忙着应付公司的培训,顾不上来博客园。最近总算开始适应了工作的方方面面,抽出空来写这篇文章,给自己前三个月做一个工作总结。
我有一个公众账号“华工小y”,每天都会分享自己工作的点点滴滴,以及业余爱好的林林种种,感兴趣的朋友可以关注一下。下面这条链接,是我前两天写的一篇文章,可以看一看。
(如果觉得这篇文章对你有帮助,可以轻轻点击下方的“推荐”按钮,同时也期待你的评论与楼主进行交流)
一个新人如何学习在大型系统中添加新功能和Debug的更多相关文章
- 自己动手在win2003系统中添加虚拟网卡
运用虚拟网卡我们可以更好地使用我们的网络,那么在win2003中该怎么操作呢?下面就为大家介绍下具体的步骤 虚拟网卡是用软件来实现虚拟的网卡,通过运用虚拟网卡我们可以更好地使用我们的网络.但是虚拟 ...
- 在WordPress后台菜单系统中添加Home链接
在wordpress后台如果想打开前台的话,要想先把鼠标移动到左上角菜单,然后在下拉菜单中点击“查看站点”,很是麻烦,能不能在 WordPress 后台菜单系统中添加 Home 链接呢? 将下面代码复 ...
- 详解VMware 虚拟机中添加新硬盘的方法
一.VMware新增磁盘的设置步骤 (建议:在设置虚拟的时候,不要运行虚拟机的系统,不然添加了新的虚拟磁盘则要重启虚拟机) 1.选择“VM”----“设置”并打开,将光标定位在“硬盘(SCSI)”这一 ...
- SQLSERVER2014中的新功能
SQLSERVER2014中的新功能 转载自:http://blog.csdn.net/maco_wang/article/details/22701087 博客人物:maco_wang SQLSER ...
- VMware 虚拟机中添加新硬盘的方法(转载)
随着在虚拟机中存储的东西的逐渐的增加,虚拟机的硬盘也逐渐告急,因此急需拓展一块新的虚拟磁盘.以下便是在VMware 中添加新的虚拟磁盘的方法: 一.VMware新增磁盘的设置步骤 (建议:在设置虚 ...
- 在ubuntu中添加新硬盘
在ubuntu中添加新硬盘 转载于 http://www.cnblogs.com/unipower/archive/2009/03/08/1406230.html 前言 安装新硬盘这种事情并不会经常 ...
- 如何在Linux中添加新的系统调用
系统调用是应用程序和操作系统内核之间的功能接口.其主要目的是使得用户 可以使用操作系统提供的有关设备管理.输入/输入系统.文件系统和进程控制. 通信以及存储管理等方面的功能,而不必了解系统程序的内部结 ...
- C# 往Datatable中添加新行的步骤
以一个实例说明 //录入年份绑定 public void YearList(FineUIPro.DropDownList ddlYear) { //年份从15年到当前年//起止年份 ; int yea ...
- Spring中添加新的配置表,并对新的配置表进行处理
实习过程中boss交代的任务(以下出现的代码以及数据只给出小部分,提供一个思路) 目的:Spring中添加新的配置表,并对新的配置表进行处理:替换的新的配置表要友好,同时保证替换前后功能不能发生变化. ...
随机推荐
- UWP Jenkins + NuGet + MSBuild 手把手教你做自动UWP Build 和 App store包
背景 项目上需要做UWP的自动安装包,在以前的公司接触的是TFS来做自动build. 公司要求用Jenkins来做,别笑话我,之前还真不晓得这个东西. 会的同学请看一下指出错误,不会的同学请先自行脑补 ...
- Ubuntu菜鸟入门(六)—— 有道词典安装
一.在有道辞掉官网上下载安装包: youdao-dict_1.1.0-0-ubuntu_amd64.deb 二.安装 1.打开下载目录,进行安装 sudo dpkg -i youdao-dict_1. ...
- spring spring data jpa save操作事务
整合spring spring data jpa的时候,在save方法上加了@Transactional注解.此时调用springdatajpa save方法并不会真的把数据提交给数据库,而是缓存起来 ...
- POJ 3415 Common Substrings ——后缀数组
[题目分析] 判断有多少个长度不小于k的相同子串的数目. N^2显然是可以做到的. 其实可以维护一个关于height的单调栈,统计一下贡献,就可以了. 其实还是挺难写的OTZ. [代码] #inclu ...
- 使用IHTMLDocument2解决弹出"为了让该网站给你提供个人化信息,是否允许在你计算机放置cookie?"
mshtml可以说是一个不错的解析html利器,对于像我这样一直都是不用webbrowser,直接用socket或者WebRequest进行HTTP通讯 然后再用IHTMLDocument2.writ ...
- bzoj1051Tarjan裸题
tarjan缩点+判断出度为0的点 所以不需要新建边 #include <cstdio> ,time=,T=,sum=,ans=; ],to[],nex[],fir[],dfn[],low ...
- js get browser vertion (js获取浏览器信息版本)
1问题:js get browser vertion (js获取浏览器信息版本) 2解决方案 Copy this script into your JavaScript files. It works ...
- IDEA+Tomcat+JRebel热部署
在完成idea工程简单应用后,接下来实现热部署. 简单应用地址:http://wibiline.iteye.com/admin/blogs/2072454 一.安装JRebel插件 1. 在线安装 F ...
- Linux Shell 重定向与管道【转帖】
by 程默 在了解重定向之前,我们先来看看linux 的文件描述符. linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以 ...
- HTTP协议入门要点
应用层协议.基于tcp HTTP/0.9 命令 GET 特点 服务器只能回应HTML字符串 服务器发送完毕后就关闭tcp连接 HTTP/1.0 命令 GET POST HEAD 特点 每次通信都必须包 ...