同事说,我写Java代码像写诗
文章来源:http://33h.co/kntu3
前几天空闲时间写了一遍关于平时自己写代码的一些习惯,这里跟大家分享一下。
定义配置文件信息✦
有时候我们为了统一管理会把一些变量放到 yml 配置文件中。
例如:
用 @ConfigurationProperties 代替 @Value。
使用方法:
定义对应字段的实体:
@Data
// 指定前缀
@ConfigurationProperties(prefix = "developer")
@Component
public class DeveloperProperty {private String name;private String website;private String qq;private String phoneNumber;
}
使用时注入这个 bean:
@RestController
@RequiredArgsConstructor
public class PropertyController {final DeveloperProperty developerProperty;@GetMapping("/property")public Object index() {return developerProperty.getName();}
}
用@RequiredArgsConstructor代替@Autowired✦
我们都知道注入一个 bean 有三种方式哦(set 注入,构造器注入,注解注入),spring 推荐我们使用构造器的方式注入 Bean。
我们来看看上段代码编译完之后的样子:
RequiredArgsConstructor:lombok 提供。
代码模块化✦
阿里巴巴 Java 开发手册中说到每个方法的代码不要超过 50 行(我没记错的话)。
在实际的开发中我们要善于拆分自己的接口或方法,做到一个方法只处理一种逻辑,说不定以后某个功能就用到了,拿来即用。
抛异常而不是返回✦
在写业务代码的时候,经常会根据不同的结果返回不同的信息,尽量减少返回,会显得代码比较乱。
反例:
正例:
减少不必要的db✦
尽可能的减少对数据库的查询。
举例子:删除一个服务(已下架或未上架的才能删除),之前有看别人写的代码,会先根据 id 查询该记录,然后做一些判断。
反例:
正例:
不要返回null✦
反例:
正例:
别处调用方法时,避免不必要的空指针。
if else✦
不要太多了 if else if,可以试试策略模式代替。
减少controller业务代码✦
业务代码尽量放到 service 层进行处理,后期维护起来也好操作而且美观。
反例:
正例:
利用好Idea✦
目前为止市面上的企业基本都用 idea 作为开发工具了吧。
举一个小例子:idea 会对我们的代码进行判断,提出合理的建议。
例如:
它推荐我们用 lanbda 的形式代替。
点击 replace:
阅读源码✦
一定要养成阅读源码的好习惯包括优秀的开源项目 GitHub上stars:>1000,会从中学好好多知识包括其对代码的设计思想以及高级 API,面试加分(好多面试官习惯问源码相关的知识)。
设计模式✦
23 种设计模式,要尝试代码中运用设计模式思想,写出的代码即规范又美观还高大上,哈哈。
拥抱新知识✦
像我们这种工作年限少的程序员,我觉得要多学习自己认知之外的知识,不能每天 crud,有机会就多用用有点难度的知识,没有机会(项目较传统),可以自己下班多些相关 demo 练习。
基础问题✦
map 遍历:
HashMap<String, String> map = new HashMap<>();map.put("name", "du");for (String key : map.keySet()) {String value = map.get(key);}map.forEach((k, v) -> {});// 推荐for (Map.Entry<String, String> entry : map.entrySet()) {}
optional 判空:
//获取子目录列表public List<CatalogueTreeNode> getChild(String pid) {if (V.isEmpty(pid)) {pid = BasicDic.TEMPORARY_DIRECTORY_ROOT;}CatalogueTreeNode node = treeNodeMap.get(pid);return Optional.ofNullable(node).map(CatalogueTreeNode::getChild).orElse(Collections.emptyList());}
递归
大数据量的递归时,避免在递归方法里 new 对象,可以试试把对象当作方法参数进行传递使用
注释
类、接口方法、注解、较复杂的方法,注释都要写而且要写清楚,有时候写注释不是给别人看的,而是给自己看的
判断元素是否存在✦
hashSet 而不是 list
list 判断一个元素是否存在的代码:
ArrayList<String> list = new ArrayList<>();// 判断a是否在list中for (int i = 0; i < list.size(); i++)if ("a".equals(elementData[i]))return i;
由此可见其复杂度为 On
而 hashSet 底层采用 hashMap 作为数据结构进行存储,元素都放到 map 的 key(即链表中)
HashSet<String> set = new HashSet<>();// 判断a是否在set中int index = hash(a);return getNode(index) != null
由此可见其复杂度为 O1。
统一管理线程池✦
有的会在用到多线程的地方就创建一个线程池,为了统一管理,建议建立一个线程池,统一管理,统一设置非核心线程数,拒绝策略等等。
private static volatile ThreadPoolExecutor threadPoolExecutor = null;private static final int CORE_POOL_SIZE = 0;private static final int MAX_MUM_POOL_SIZE = 1000;private static final long KEEP_ALIVE_TIME = 2;private static final TimeUnit UNIT = TimeUnit.MINUTES;private static final int CAPACITY = 1;private static final RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();private static final BasicThreadFactory factory =new BasicThreadFactory.Builder().namingPattern("aiserviceplatform-util-thread-pool-%d").build();private ThreadPoolFactory() {}public static ThreadPoolExecutor getInstance() {if (threadPoolExecutor == null) {synchronized (ThreadPoolFactory.class) {if (threadPoolExecutor == null) {threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_MUM_POOL_SIZE, KEEP_ALIVE_TIME, UNIT, new ArrayBlockingQueue<>(CAPACITY), factory, HANDLER);}}}return threadPoolExecutor;}
大量数据同步✦
在同步大数据量的信息时(常用多线程方式:如果表里有唯一索引或者对表进行 update 操作那么就会经常锁表),优先考虑添加临时表的方式。
String realTabelName = ....;
String tempTableName = realTableName + "_temp";createTable(tempTableName); // 创建临时表
boolean flag = sync(tempTableName); // 同步数据// 根据结果
if(flag) {dropTable(realTabelName);alterTabelName(realTableName, tempTableName); // 临时表改名 实际表
}else {// 同步失败 删除临时表dropTabel(tempTableName)
}
实测:比对一张表做处理会快很多而且不会出问题。
接口入参✦
定义接口的方法时,如接受一个集合类型,尽可能的用 Collection<T>,因为其他业务场景可能会穿一个 list 有的会传一个 hashSet,用起来还要改,Map 也是。
正例:
Collection<String> getNodeIds(Collection<String> ids);
锁的颗粒度✦
同步方法直接在方法上加 synchronized 实现加锁,同步代码块则在方法内部加锁,很明显,同步方法锁的范围比较大,而同步代码块范围要小点,一般同步的范围越大,性能就越差,一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好
我一般使用 lock:ReentrantLock,ReentrantReadWriteLock,减少锁的颗粒度,提高系统的并发能力。
缓存名称✦
简短,精练,以文件夹形式保存,xxx:xxx:xxx,以:隔开。
方便查看缓存信息。
@Cacheable✦
使用 Cacheable 做缓存时,也要加上缓存失效时间。
之前提出疑问怎么有的缓存没有失效时间,看代码使用 Cacheable 缓存的,不会添加就没加(???)。
@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {return new RedisCacheManager(RedisCacheWriter.lockingRedisCacheWriter(factory),this.getRedisCacheConfigurationWithTtl(1),this.getRedisCacheConfigurationMap());}private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer hour) {Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);return RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).entryTtl(Duration.ofHours(hour));}public static final String REGION_LIST_BY_CODE_CACHE_KEY = "region:list";public static final String REGION_NAME_BY_CODE_CACHE_KEY = "region:name";/*** 已知缓存名称的映射以及用于这些缓存的配置*/private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();// 自定义缓存名称对应的配置redisCacheConfigurationMap.put(REGION_LIST_BY_CODE_CACHE_KEY, this.getRedisCacheConfigurationWithTtl(24));redisCacheConfigurationMap.put(REGION_NAME_BY_CODE_CACHE_KEY, this.getRedisCacheConfigurationWithTtl(120));redisCacheConfigurationMap.put(RedisKey.MARK_SERVICE_RENEW, this.getRedisCacheConfigurationWithTtl(-1));redisCacheConfigurationMap.put(RedisKey.MARK_ORGAN_RENEW, this.getRedisCacheConfigurationWithTtl(-1));redisCacheConfigurationMap.put(RedisKey.MARK_SERVICE_STREAM, this.getRedisCacheConfigurationWithTtl(-1));redisCacheConfigurationMap.put(RedisKey.MARK_ORGAN_STREAM, this.getRedisCacheConfigurationWithTtl(-1));return redisCacheConfigurationMap;}
异步任务✦
为了提高接口的响应速度,我们会把比较耗时的操作异步处理。例如异步任务,消息队列等。
同事说,我写Java代码像写诗相关推荐
- Jupyter 配置 Java环境,写Java代码,测试成功
本次简单诉说下怎么通过jupyter安装iJava,写Java代码. 安装Java的不说了 我使用的是Java15 然后去:https://github.com/SpencerPark/IJava/r ...
- java el表达式 导航规则_诺禾:在jsp里面如何不写java代码展示数据(EL表达式的使用)...
EL表达式可以简化jsp中写的java代码 在jsp里面如何不写java代码展示数据(EL表达式的使用) 在jsp里面如何不写java代码展示数据(EL表达式的使用) 在jsp里面如何不写java代码 ...
- 写java代码时的注意事项_从方法返回Java 8的可选项时的注意事项
写java代码时的注意事项 Java 8引入的Optional类一直是该语言版本引入的最具争议的功能之一. 尽管我喜欢这个新的Java类的东西比不喜欢的东西多,但在Java方法中将其用作return类 ...
- vscode写java没有提示_VS Code报错Language Support for Java(TM)插件显示需要JDK11 写java代码没有提示...
鉴于IDEA的打开速度(电脑的垃圾),平常刷LeetCode都是在VSCode上,结果这几天老是打开给我报错 Java 11 or more recent is required to run. Pl ...
- 如何在jsp里面写java代码
jsp和html相比,最显著的优势就在于,jsp里面可以写java代码,但是html中不能. 那么如何在jsp中写java代码呢! jsp中写java代码有如下三种方式: <%! %>,这 ...
- Eclips写Java代码和CSS、Javascript、Html代码设置代码自动提示功能
按照我的方法设置后用Eclipse编写Java代码和前端代码(Html.CSS.JS)都可以自动提示代码.赶紧去试试吧. 1.打开Eclipse软件,点击Windows→Preferences→Jav ...
- jsp里写java代码报错,jsp里写java代码报错
jsp里写java代码报错 [2021-02-11 06:42:03] 简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace("/ ...
- vim java 编程_你也用Vim写Java代码?
献给所有曾试图写Java而痛苦挣扎的Vimers, 请不要害怕, 我也是你们的一员 序 文章源起于segmentfault论坛中的一个问题, 由于回答的有点尽性, 便转为文章. 题主应该是个Vim初学 ...
- 如何写出同事看不懂的Java代码?
壹.瞒天过海 我打赌你肯定想不到,有人居然会在注释里下了毒.看看下面的代码,简单到main方法中只有一行注释. public static void main(String[] args) {// \ ...
最新文章
- debounce实现 js_javascript防抖函数debounce详解
- SQL How to get the current day month and year
- 经典shell面试题整理
- jQuery的push
- Android隐藏标题栏,全屏显示
- lengthOfLongestSubstring
- 让代码看起来更舒服(1):选择适合的配色方案 (转)
- Python装饰器几个有用又好玩的例子
- 【李宏毅2020 ML/DL】补充:Support Vector Machine (SVM)
- MySQL - 常见SQL笔试题整理(长期更新)
- CAPL可以读写的几种文件
- 解析数论引论 第2章 数论函数和狄利克雷乘积
- requests+正则表达式爬取豆瓣读书top250
- Radasm 配置goasm
- 布局改变时的过场动画
- 计算机电缆一般用在哪里,计算机电缆的型号有哪些,它们的用途是什么
- Docker硬盘空间使用分析与清理
- Java8新特性-Optional类
- 在MAC下解决MAC unable to execute sex :GC overhead limit exceeded GC overhead的问题
- OpenGL 与显卡
热门文章
- 荒岛余生最后一个包裹_豆瓣评分8.5,一个人撑起整部电影,最后的彩蛋让人无语...
- 何为Java 中的多态?
- php 去掉img,php怎样去掉img标签
- 怎么把文字变成图形_PPT 中实现文字矢量化
- java864位官网_jdk8 64位下载-jdk8 64 bit windows官方版 - 极光下载站
- jfinal js 拦截_jfinal全局数据拦截器
- 求n!(n的阶乘)和1!+2!+....n! (阶乘求和) ----C语言实现
- PTA基础编程题目集-6-8 简单阶乘计算
- SP10628 COT - Count on a tree (树剖+可持久化线段树)
- GCD or LCM ---- 处理gcd和lcm同时出现的情况 1499D - The Number of Pairs