本文已被 https://yourbatman.cn收录; 女娲Knife-Initializr工程可公开访问啦;程序员专用网盘 https://wangpan.yourbatman.cn;技术专栏源代码大本营: https://github.com/yourbatman/tech-column-learning;公号后台回复“ 专栏列表”获取全部小而美的 原创技术专栏
你好,这里是Java方向盘,我是方向盘(YourBatman),坐稳扶好,开始发车。
Title | Link |
---|---|
所属专栏 | 【方向盘】-IntelliJ IDEA |
源代码 | https://github.com/yourbatman/FXP-java-ee |
程序员专用网盘公益上线啦,注册送1G超小容量,帮你实践做减法 | https://wangpan.yourbatman.cn |
Java开发软件包(Mac) | https://wangpan.yourbatman.cn/s/rEH0 提取码:javakit |
女娲工程 | http://152.136.106.14:8761 |
版本约定 | [Mac OS 12.5],[IntelliJ IDEA 2021.2] |
📚前言
上篇文章【方同学】是如何高效的使用IntelliJ IDEA 再一次勾起了较多读者对IDEA的兴趣,让我没想到的是一个小小的IDE开发工具而已,甚至都与Java语言没有直接关系,竟然也能写成一个系列。也许它代表着一种态度,一种程序员对工具使用的态度,not only code。
认识我的朋友可能比较清楚,笔者近些年一直从事和带领团队从事基础架构、中间件的研发工作。众所周知,写基建代码与业务开发有不同,它对代码质量、可靠性、性能、软件长久生命力均会有更高要求,毕竟基础不牢,地动山摇是共识。
本文就为你分享,笔者是如何借助IDEA自带的一些能力,对书写的代码进行(质量)审查的。工具的出生就为提效,熟练使用对个人甚至团队都有好处。
✍正文
提高代码质量的手段
代码作为软件的载体,是软件最为重要的组成部分。所以一个软件的质量如何,很大程度上是由代码质量决定的。也许在写几句hello world的时候软件质量尚可,但随着时间的推移、代码量的增加、需求的多变、团队协作日益复杂等因素的加入,往往在质量这条路上渐行渐远。蓦然回首,是不是感觉自己已忘初心,但依旧砥砺前行呢?
殊不知,代码并非编译通过,万事大吉,编译只是最最最最基础的保证而已。
大部分程序员是期望写出高质量的代码,对自己的代码质量要求是较高追求的。可一旦遇到赶工压力,尤其是在 deadline 之前,就很可能会把完成度很低的代码交出去,心想“反正有人给我检查,到时候再说吧”。但是,这些代码就好比是一台“行走的Bug制造机”,后患无穷。作为你的领导看到这样的代码上线,可谓慌得一批。
既然赶工期、deadline这种“事件”无法避免,并且团队内程序员的水平/追求也高低不一,怎么办?随着软件行业的发展,出现了一批又一批的方法论、手段、工具用于整体提升软件质量,下面按照离程序员由近及远的顺序从两个方面简要了解一下。
✌程序员侧 - 最行之有效
代码是由程序员写的,最了解它的莫过于程序员自己。因此在本侧若能够做好质量把控关,是最行之有效的。正所谓在离“用户”最近的地方发现问题、解决问题往往效率最高的。
当然,从品控的方式方法上,自然也有成套的解决方案。处在程序员侧,有个非常大的优势:可借助IDE提供的“超强”能力,高效的进行代码审查工作。
IDE通用代码审查
什么叫通用代码审查?说白了就是关乎代码格式、方法/变量命名、基础语法合理性等等,一般的IDE都有这样的能力。
比如本文接下来将要讲的IDEA代码审查能力,就是提供的这方面的能力。
静态代码检测
借助checkstyle、p3c这类工具,对代码进行静态检测,能够提早发现很多运行期潜在的bug/风险点。静态代码检测对Java这种静态语言效果极佳,这也是静态语言的巨大优势之一:健壮性强。它对动态语言(如Python、PHP等)有点无能为力,效果欠佳。
拿Java举例,像Long.equals(Integer)
这种无数人踩过的坑,通过静态代码检测就可以规避。另外,代码规范、格式等等都可以通过静态代码检测来实现很好的约束。值得注意的是,别看只是格式,这也很重要,很多时候程序出现bug,代码格式才是原罪。对于一个普通的程序员来讲,第一任务是要写出人能看得懂的代码,其次才是机器。
单元测试
单元测试(UT),是指对软件中的最小可测试单元进行检查和验证。那什么叫最小可测单元呢?以Java语言为例,最小可测单元就是一个方法/函数。
写出一个可单测的代码其实是非常困难的,有工作经验的程序员或多或少经历过“拒绝写单元测试”的情况,根据我的经验,出现这种畏难情绪的根本原因是:不会写,没有可“抄”的,毕竟ctrl c + ctrl v才是第一生产力嘛,让自己去搞,没有的事。
国内的开发环境尚处在初、中期,普遍对单元测试的重视度不够。主要原因我认为有两点:
- 写好UT需要花费一定时间,而国内行情一般“工期紧”,较少做中长期规划
- 业务逻辑代码分层不够、耦合严重,导致写UT代码时工作量剧增,近乎无法单测
久而久之,积重难返。等到最后上级领导说要关注代码质量要求写单元测试的时候,受到的阻碍情绪将会是空前的,然后就陷入了恶性循环。
关于UT,开发者公认的事实:UT是确保代码健壮性极其有效的手段。根据现实情况,我本人对UT的态度是:尽量不要自顶向下的强推,而应疏。
单元测试其实是一门严重被低估的“学问”,经常是领导大嘴一巴说要写,至于怎么写可能领导自己也不知道,甚至可能从来没写过。正所谓己所不欲勿施于人,我认为UT覆盖率问题应该上升到方案级别,而不只是只有一个字:写。
畏难情绪是顺人性的,是天性的表现。在代码的世界了,不会才觉得难,才会抗拒。毕竟写UT远没有写业务代码来得那么的“轻松”。针对此问题,可采用榜样的力量逐步疏通、渗透。对于个人来讲,应该迎难而上,追求更高质量的代码。
✌CI/CD侧 - 统一卡点
虽然说在程序员侧进行一些质量把控环节效果是最佳的,但此方式高度依赖程序员本身的综合水平和自觉性,可靠性是明显不够的。因此在实际生产上,需要辅助一些集中式卡点行为来做保障。
Code Review
对每个提测的分支,(至少在上线前)必须要进行CR(code review)环节。此环节比较出名的工具有:Gitlab(商业版)、Fisheye等
集中式静态代码检测
简而言之,就是将你本地静态代码监测的能力搬到云端,进行集中检测。一般可分为全量检测和增量检测。此环节比较出名的工具有:sonar、cubase等
集成测试
对多个系统进行集成测试、边界测试。该环节一般属于QA人工介入阶段,和业务逻辑强关联,是最为耗时的阶段之一。
持续集成流水线工具
在软件发布阶段,也会有一些相应的审核、卡点机制。此环节比较出名的工具有:jenkins、hudson等
借助IDEA审查你的代码
做个小调查:有多少同学从来没有使用过甚至从来没有看过IDEA的code菜单呢?
不管你看没看过,应该直接或间接的使用过其相关功能。比如这个Generate...
自动为JavaBean生成get/set方法、构造器、hashCode()、toString()等方法。也许你会说现在用lombok基本不使用它了,对,这是事实。但是,再不济,像Override Methods、Implement Methods这些功能都用过吧,毕竟我不信方法复写、方法实现这种模板代码你会一字一句手敲~
那么,接下来重点向你介绍code菜单里面的代码审查功能,顺带也分享笔者是如何利用IDEA提供的这些能力去帮助自己、甚至帮助团队提高代码质量、保证代码质量的。
代码审查相关功能在Code菜单这里(如下图)。两条灰色的线条将这几项归为一类:
以这段示例代码为例审查:
package cn.yourbatman;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@SpringBootApplication
public class Application {
private String name;
private String agee;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
public boolean fun1(boolean bool) {
return bool ? true : false;
}
public String fun2(String s) {
return s.toString();
}
}
✌Inspect Code...审查你的代码
Inspect:检查、审查。
点击OK运行,在problem视窗里可以看到“有问题”的代码:
经过审查,本工程里的“坏味道”代码就在problem视窗指出了。如图,IDEA针对性的提供了便捷的一键处理按钮,你可以快速处理,非常智能化和人性化有木有。
到这,你可能不禁想问:IDEA怎么知道这是坏味道代码的?遵照什么规则?显然,一切都是“有法可依”,它在这:设置 -> Editor -> Inspections
一般来讲,Inspections保持默认即可。但我会把拼写检查(毕竟英语并非咱母语,偶尔单词拼写错误甚至用拼音是可以原谅的,关掉它以节约点性能开销嘛)相关的关掉:Spelling、Typo
注意:Inspect Code只会帮你把坏味道代码“揪出来”,改还是不改的决策权还在于你自己。
✌Code Cleanup...精炼你的代码
不同于Inspect Code帮你指出坏味道的代码,它比较“狠”,会拿你的代码直接开刀。如下:
执行该动作不需要同意,IDEA会直接动手修改你的代码。
当然喽,你duck不必担心它改乱了:它有且只做同等语义的替换,使得代码组织起来更优雅,绝不会影响到程序的正确执行。
Tips:有时候人容易理解和优雅写法是相冲的,这个时候你就得三思是否有必要执行此功能喽
✌Analyze Code...分析你的代码
它是一个功能集的统称。
问:为何这些功能被放在二级目录下?
答:相对来说不太常用。这是基本的产品设计逻辑嘛:常用的放在一级目录,不常用的功能下层
Silent Code Cleanup
静悄悄的完成精炼你的代码操作,执行结果同Code Cleanup。
我的使用情况:基本不用
Run Inspection by name
如果觉得每次运行Inspect Code把所有的规则都走一遍太慢了,那么就可以使用此功能:只运行指定名称的规则
我的使用情况:基本不用。现在微服务开发模式,每个应用“体积”都很小,1s和0.5s的差异who care呢
View Offline Inspection Results
离线查看代码分析的结果。此功能的存在,是因为problem结果是可以导出的:
我的使用情况:只使用过几次。那是我要给团队做分享,所以通过导出文件来保留“现场”,从而在分享时在导入方便说明问题。
Infer Nullify
Infer:推断。此功能作用是在方法参数、返回值里帮你推断:哪些必须不能为null、哪些可以为null
以这个方法为例:
public String fun2(String s) {
return s.toString();
}
内部调用了s的toString()方法,因此s肯定不能为null,进而推断出返回值也就不可能为null。因此,运行IDEA的此功能后,代码会被改成这样:方法签名的语义更加明确
public @NotNull String fun2(@NotNull String s) {
return s.toString();
}
值得注意的是,注解它只用于表达语义,运行期无任何作用。另外,该功能要正常执行需要此依赖包才行:
若没有此依赖,执行时会弹出提示你添加依赖:
此时点击ok就能自动帮你把依赖加上了,非常方便。
Tips:点ok后此框不会消失,但实际依赖已经加上,不用重复点哦,否则会重复添加依赖的。这是IDEA的一个小bug
我的使用情况:从未使用过。因为我习惯使用功能更强大的Bean Validation,不仅语义明确,runtime时期也会生效。
Locate Duplicate
顾名思义,帮你定位重复代码,以便做封装、抽象。
我的使用情况:在review组员代码的时候,用得较多。查找结果还是蛮有参考价值的,推荐使用
Dependencies...
IDEA在Project视窗,把依赖统一全部放在了External Libraries
里,就像这样:
若是一个多模块的项目,此时只想查看某1个模块的依赖的话,通过External Libraries
就无能为力了。这个时候一般有两种办法来查看具体某个模块的依赖:
- 通过Maven视窗查看
这种方式,它对于中小型服务可以解决绝大部分问题,因为依赖不多不难定位。但是它的明显缺点是:不够直观。并不能一眼看出来模块的最终依赖。比如某个依赖是间接依赖进来的,这时通过这种方式就非常不直观了;又比如多个地方引入了a.jar,也就无法一眼看出来最终使用的是哪个版本的a.jar啦
- 通过本处的Dependencies功能
这个依赖分析功能非常、非常、非常强大。它不仅仅能帮你分析出每个类(粒度非常细)依赖哪些库,还能分析出依赖了本project的哪些类。该功能在阅读他人代码(or开源代码)时非常有用
我的使用情况:较为频繁。我在阅读开源代码的时候使用较多,通过依赖分析,能够较快的掌握作者的整体设计意图,具有更全面的视野。
Backward Dependencies...
上面功能是查看自己依赖了谁,该功能表示谁依赖了自己。
Module、Cycle Dependencies...
用于分析本工程的模块粒度的依赖关系,是否存在循环依赖等,使用起来比较简单,不详细解释了。
✌Analyze Stack Trace or Thread Dump...
又一神器,这个工具我可太爱了。字面含义:分析堆栈,或者内存dump。
例如有这么一个场景:线上服务出bug抛了异常,日志文件里留下的是堆栈信息,面对这个堆栈信息你如何快速定位到问题代码呢?
这个时候一般是在这个黑框里逐行的找,找到“熟悉”的一行(有行号),然后返回到IDEA里找到对应的类,问题定位路径其实还蛮长的。
其实duck不必这么麻烦,IDEA为咱们提供了非常好用的分析工具,你只需要:
- 复制堆栈信息
- 在IDEA里Code -> Analyze Stack Trace or Thread Dump打开分析窗口
点击ok,控制台里就能显示出堆栈信息,和本地调试一模一样的效果了有木有
这里我演示的是该功能的最简单使用场景,除了分析这种简单的堆栈外,还可以分析dump文件,还可以自定义分析器(比如class文件混淆、加密了)等等,最终目的就是让开发者有种本地化“分析线上问题”的体验。
关于本功能的更多使用方式,感兴趣的同学在真正用起来的时,可自己发现。
✍总结
本文以IDEA作为着力点,我主要想输出的两个观点是:
- 单元测试被低估了
- IDEA的代码审查能力被低估了
作为一个开发者,很多时候人与人的差异体现在知道的多与少、知道和不知道上,毕竟大家的教育背景、智商大都差异不大,会得多一点并且让这些能支撑自己总是好的。
关于IDEA你还有哪些故事呢?你还想知道哪些故事呢?期待你的分享呀~
推荐阅读
- 【方同学】是如何高效的使用IntelliJ IDEA
- 【方向盘】IntelliJ IDEA 2020.2正式发布,诸多亮点总有几款能助你提效
- 【方向盘】IntelliJ IDEA 2020.1正式发布,你要的Almost都在这!
- 【方同学】女娲Knife-Initializr工程可公开访问啦
- 【方向盘】轰动从未停止,感动从未消失。他,是周杰伦
- 【方向盘】阿里巴巴入选的JCP最高执行委员会,何方神圣?
我是方向盘(YourBatman):前25年不会写Hallo World、早已毕业的大龄程序员。高中时期《梦幻西游》骨灰玩家,网瘾失足、清考、延期毕业、房产中介、保险销售、送外卖...是我不可抹灭的黑标签
- 🎓2013.07 清考、毕业答辩3次未通过、延期毕业
- 🏷2013.08-2014.07 宁夏中介公司卖二手房1年,毕业后第1份工作
- ️️🏷2014.07-2015.05 荆州/武汉,泰康人寿卖保险3月、饿了么送外卖2月,还有炸鸡排、直销等第2345份工作
- 🏷2015.08 开始从事Java开发,闯过外包,呆过大厂!擅长抽象思维,任基础架构团队负责人
- 🏷2021.08 因“双减政策”失业!历经9面,终获美团外卖L8的offer
- 🙅🏻♀️Java架构师、Spring开源贡献者、CSDN博客之星年度Top 10、领域建模专家、写作大赛1/2届评委
- 📚高质量代码、规范践行者;DDD领域驱动深度实践;即将出版书籍
《Spring奇淫巧技》
序号 | 专栏名称 | 简介 |
---|---|---|
01 | 【方向盘】-程序人生 | 程序人生,人生程序 |
02 | 【方向盘】-资讯/新特性 | IDEA、JDK、Spring技术栈......新特性 |
03 | 【方向盘】-IntelliJ IDEA | 熟练使用IDEA就相当拥有物理外挂,助你高效编码 |
04 | 【方向盘】-Bean Validation | 熟练掌握数据校验,减少90%的垃圾代码 |
05 | 【方向盘】-日期时间 | 帮你解决JDK Date、JSR 310日期/其实 的一切问题 |
06 | 【方向盘】-Spring类型转换 | Spring类型转换-框架设计的基石 |
07 | 【方向盘】-Spring static | static关键字在Spring里的应用 |
08 | 【方向盘】-Cors跨域 | 关于跨域请求问题,本专栏足矣 |
09 | 【方向盘】-Jackson | Almost Maybe是最好的Jackson专栏 |
10 | 【方向盘】-Spring配置类 | 专讲@Configuration配置类,你懂的 |
11 | 【方向盘】-Spring技术栈 | 暂无所属小分类的,Spring技术栈大分类 |
12 | 【方向盘】-JDK | 暂无所属小分类的,JDK技术栈大分类 |
13 | 【方向盘】-Servlet | Servlet规范、Web相关内容专题 |
14 | 【方向盘】-Java EE | 从Java EE到Jakarta EE,30年弹指一挥间 |
15 | 【方向盘】-工具/提效 | 开发工具、软件工具,目标是提效 |
16 | 【方向盘】-Spring技术栈新特性 | Spring Framework、Spring Boot、Spring Cloud、Spring其它技术 |
17 | 【方向盘】-基本功 | 每个Javaer,都需要有扎实的基本功 |
... | ... | ... |
99 | 源代码库 | 大多数专栏均配有源代码,都在这里 |