趁着国庆节, 系统的整理了自己在开发的时候比较常用的类库、Linux命令。
有时候,“虚惊一场”这四个字是人世间最美好的成语,比起什么兴高采烈,五彩缤纷,一帆风顺都要美好百倍。你可懂什么叫失去。这些时间来,更觉如此。愿悲伤恐惧能够过去,事外之人更懂珍惜。
- Java 篇
- Linux篇
- SQL相关
- 处理老数据的策略
- 数据回滚
- 服务端请求执行模型
- 参考资料
Java 篇
- Excel导入导出
这方面比较常用的是POI,EasyPOI,大文件导出。其中有三个比较核心的对象:
HSSFWorkbook:是操纵Excel2003以前(包括2003)的版本,扩展名是.xls。上限是65535行,超过就会报错。
XSSFWorkbook:是操纵Excel2007后的版本,扩展名是.xlsx。最多可以导出104万行,但是到达一定的条数,也会OOM,原因在于,写入的操纵全在内存中进行。
SXSSFWorkbook: 也是操纵Excel2007之后的, 处理大文件导出。处理大文件的写入。做的改进是在写入过程中将数据持久化到磁盘,来减少对系统内存的占用。
- HttpClient 工具
JDK11 新实现了HttpClient, 直接用就好了。JDK 11 以下,我们常用的还是Apache提供的HttpClient.
- 日期工具类
SimpleDateFormat Date Calendar
- Guava 类库
这个类库还是一个宝藏库,说到这个库我想起我刚工作的时候碰见的一个场景,将数组、List转成逗号分隔。
我当时选择自己去实现,后来才发现我们项目引入了Guava,Guava有做好了的函数。像下面这样:
private static void joinerExample() { List<String> stringList = new ArrayList<>(); stringList.add("aaa"); stringList.add("bbb"); stringList.add("ccc"); Joiner joiner = Joiner.on(",").skipNulls(); System.out.println(joiner.join(stringList)); }
Guava还内置了固定排序器,我当时的项目还有这样一个需求, 比如按照固定顺序去排序,比如输入时{北风,1}, {西风,2},{南风,3},{东风:4},要求按照东风、南风、北风,西风去排,不在东西南北风的排在最后。Java内置的也可以实现,只不过要稍微费一点手脚,使用Guava的话更简单一点。其实Apache Commons也提供了固定比较器FixedOrderComparator。
- Apache commons-lang3 对应的依赖用关键词去maven搜索即可
这个类库算是开发中另一个比较常用的类库了,我日常常用的也就是StringUtils。这个命名对应的是java.lang。粗略的说commons.lang是对java.lang的扩展。所以当你想用java.lang下面一些类的utils的时候,可以先不要着急封装,先去commons-lang3下面找找。
- Apache commons-collections
这个类库是对java集合类的扩展。丰富了java的集合类型。
- Apache commons-codec
处理常用的编码方法的工具类包 例如DES、SHA1、MD5、Base64等.
- Apache commons-IO
文件IO相关
- Apache commons-math
数学相关:数学分析、线性代数、概率论。
- 计算工具类
NumberFormat 货币百分比相关 JDK内置
- 图形工具类 Thumbnailator
提供对图片的旋转、裁剪、压缩。
- 序列化场景
Jackson
Linux篇
- df -h 查看磁盘可用
- pwd 查看当前所处路径
- cat 文件名 查看文件内容,整个打开。文件较大时,慎用。
- systemctl stop firewalld.service 关闭防火墙
- systemctl status firewalld.service 查看防火墙状态
- systemctl start firewalld 启动防火墙
- touch 文件名 创建文件
- more 文件名 分页查看文件内容,按空格或回车,会继续加载文件内容,按q退出查看。当加载到文件末尾时,会自动退出查看
- less 文件名 分页查看文件内容,按空格继续加载文件,按q退出查看,不会自动退出查看
- head -n 文件名 表示查看文件的前n行数据
- tail -n 文件名 n是一个正整数,表示查看文件的后n行数据
- tail -f 文件名 动态的查看文件的最后几行内容(查看文件时,等待文件更新,如果文件更新了,会显示出新的内容)
- cd 目录路径 进入一个目录,目录路径可以是绝对路径(以/开始的路径都是绝对路径),也可以是相对路径 相对路径:以非/开始的路径, 注意: "."表示当前目录 "…"表示当前目录的上一级目录,它可以多个一起使用 "~"表示当前用户的根目录 例如:root用户时,~表示/root目录 bow用户时,~表示/home/bow目录
cd / #表示进入系统根目录 cd usr/ #表示进入当前目录下的usr目录 cd local/ #表示进入当前目录下的local目录 cd ./bin #表示进入当前目录下的bin目录 cd .. #表示进入当前目录的上一级目录 cd ../.. #表示进入当前目录的上级目录的上一级目录 cd /usr/local/bin #进入/usr/local/bin目录 cd ../etc #表示进入和当前目录同级的etc目录 #..表示当前目录的上一级目录 ../etc表示当前目录上级目录下的etc目录(和当前目录同级) cd ~ #表示进入当前用户的根目录(cd ~ 和直接执行cd后不加目录的效果相同) #例如:root用户进入/root目录,bow用户进入/home/bow目录 cd ~/data #表示进入当前用户根目录下的data目录 例如:root用户则进入了/root/data目录
- free -h 查看系统内存使用状况
- jps 这个命令属于Linux,查看Linux下运行的Java进程
- top命令: top命令提供了运行中系统的动态实时视图
- ps -ef|grep 进程名 显示该进程名的相关信息。
- kill -9 pid
SQL相关
有个一对多的关系,比如说学生表和成绩表,一个学生对应多门成绩,但是我们希望一行中显示学生的所有信息和所有成绩,多门成绩用逗号分隔。下面的数据库函数就能帮助我们实现我们的要求。
- MySQL : group_concat([DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator '分隔符'])
- Oracle: listagg(measure_expr,delimiter) within group ( order by order_by_clause);
measure_expr: 可以是基于任何列的表达式 delimiter 分隔符 order_by_clause 排序字段
- PostgreSQL : STRING_AGG ( expression, separator order by [order_by_clause] )
expression 列或表达式,separator 分隔符,order_by_clause排序字段。
处理老数据的策略
之前对接老数据的时候,涉及十几张个表,但是又希望显示在一个表格上,没办法我就用join,我预计这个页面的查询最终肯定会很慢,结果果然不出我所料。加索引也架不住,好在oracle有物化视图这个语法,物化视图相等于将依据视图将视图变成一张真正的表,定时抽取数据。这是个处理老数据的不错方法。还有在对接老数据的时候,有些一对多的建表,比如人员和部门, 人员表存的部门编码存的多个是放在一行,像下面这样:
name | deptCode |
张三1 | 1,2 |
张三2 | 1,4 |
这样我查找某个部门下的人,我们其实可以采用模糊匹配的方式,假设这张表叫person,那我们写查询的时候就可以这么写:
SELECT * FROM PERSON WHERE ‘,’||deptCode || ‘,’ like ‘%,1,%’ , oracle下 || oracle下拼接字符串的符号。MySQL下这个需要用contact函数。】
那么如果想实现in操纵呢,我们借助MyBatis,循环此操纵即可。假设想查找部门编号是1或者2的,最终形成的SQL语句应该是:
SELECT * FROM country where CONCAT(',',country,',') like '%,A,%' OR CONCAT(',',country,',') like '%,B,%' mysql
数据回滚
开发人员有的时候会误删、误改数据, 对此我深有体会,我之前做项目的时候就有一次不小心将一张比较核心的表全表改了,我自然想到了回滚。oracle刚好提供了这样的机制,在oracle中称之为闪回,可以做到将一张表回滚到指定时间。其他数据库也有对应的支持,不过跟Oracle存在一定的差异。
服务端请求执行模型
几乎每个Java程序员都了解过Spring MVC的执行流程, 毕竟这是面试的高频知识点, 那在配合上Tomcat呢? 有一道经典的面试题是在浏览器输入url后发生了什么。这是在考网络和前端,那我们将问题变一下呢, 即前端或者浏览器请求Controller的某个方法,到方法的执行发生了什么?这里屏蔽掉三次握手之类的东西,不再考虑页面渲染,只是考虑请求到Tomcat或其他应用服务器,由Tomcat到Spring MVC,再到执行的方法, 它的执行流程是怎么样的, 这个其实只用在原先Spring MVC执行流程上加上以下步骤即可:
- 请求到达Tomcat
- Tomcat将请求提交给线程池
- 线程池任意选中一个线程来执行对应的Servlet, 即调用Spring MVC的DispatcherServlet
- 所以每次请求都是不同的线程来执行对应Controller的请求方法
我们可以在请求方法中打印当前线程的名字来验证我们的论断,代码相当简单:
@RestController public class HelloWorldController { @GetMapping("hello") public void test() { System.out.println(Thread.currentThread().getName()); } }
输出:
参考资料
- java 中指定顺序排序,这里有多种方案 https://zhuanlan.zhihu.com/p/92149083
- Commons Math学习笔记——目录(随时更新) http://www.blogjava.net/changedi/archive/2010/12/10/340282.html
- 来不及解释!Linux常用命令大全,先收藏再说 https://www.zhihu.com/search?type=content&q=Linux%20%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4