综述

  • JDK版本:JDK8/JDK7 + OracleJDK/OpenJDK
  • Java开发框架:Spring Boot/Spring + Hibernate/MyBatis
  • 前后端分离:单页应用/模板引擎
  • 前后端接口文档自动生成:Swagger
  • 业务端逻辑校验框架:Functional Validator/Fluent Validator/Hibernate Validator
  • CT框架:Rundeck
  • UT框架:TestNG/JUnit
  • 历史操作记录方案:Canal/AOP/硬编码

1. JDK版本

1.1 Why JDK8?

  • 开发效率的提升:用更少的代码完成更多的工作(Lambda代替匿名内部类、易于并行)
  • 可以使用函数式思维编程(高阶函数解放思想、消除副作用、简洁、各语言发展的趋势)
  • 未来趋势:一些开源项目及框架开始基于java8开发
  • JVM新特性:元空间代替永久代(避免JDK以及前期版本中常见的永久内存错误OOM:PermGen)

1.1.1 JDK8与JDK7代码对比

JDK7
JDK8

for (int i = 0; i < arr.length; i++) {

if (arr[i] % 2 != 0) {

arr[i]++;

}

System.out.println(arr[i]);

}

Stream.of(arr)

.map(x →(x % 2 == 0 ? x : x + 1))

.forEach(System.out::println);

Optional:优雅的处理null

JDK7
JDK8

public User getUser() {

return user;

}

public List<Order> getOrders() {

User user = getUser();

if (user != null) {

return user.getOrders();

} else {

return Collections.emptyList();

}

}

public Optional<User> getUser() {

return Optional.ofNullable(user);

}

public List<Order> getOrders() {

return getUser().map(u → u.getOrdes())

.orElse(Collections.emptyList());

}

建议:如果接口的返回值有可能是null,请用Optional封装

  • 优雅,下游不用写恶心的if-else判断
  • 安全:告知接口的使用方返回值可能为null,需要处理,以避免代码缺陷
  • 文档化:接口中可能为空的值文档化

1.1.2 易于并行

统计1-1000000内所有质数的数量

串行
并行

IntStream.range(1, 1000000)

.filter(PrimeUtil::isPrime)

.count();

IntStream.range(1, 1000000)

.parallel()

.filter(PrimeUtil::isPrime)

.count();

增强的Future:CompletableFuture

读写锁的改进:StampedLock(乐观的读策略增加系统的并行度)

原子类的增强:LongAdder(更快的原子类)、LongAccumulator

1.1.3 JVM新特性:元空间代替永久代

参考:

http://www.infoq.com/cn/articles/Java-PERMGEN-Removed?from=groupmessage&isappinstalled=0

http://www.6gdown.com/softedupage/59348.html

  • JDK7:“永久的”数据存放在一个叫做永久代的区域。永久代一段连续的内存空间,我们在JVM启动之前可以通过设置-XX:MaxPermSize的值来控制永久代的大小,32位机器默认的永久代的大小为64M,64位的机器则为85M。永久代的垃圾回收和老年代的垃圾回收是绑定的,一旦其中一个区域被占满,这两个区都要进行垃圾回收。但是有一个明显的问题,由于我们可以通过‑XX:MaxPermSize 设置永久代的大小,一旦类的元数据超过了设定的大小,程序就会耗尽内存,并出现内存溢出错误(OOM)。
  • JDK8:“永久的”数据被移到了一个与堆不相连的本地内存区域(元空间),这项改动是很有必要的,因为对永久代进行调优是很困难的。永久代中的元数据可能会随着每一次Full GC发生而进行移动。并且为永久代设置空间大小也是很难确定的,因为这其中有很多影响因素,比如类的总数,常量池的大小和方法数量等。将元数据从永久代剥离出来,不仅实现了对元空间的无缝管理,还可以简化Full GC以及对以后的并发隔离类元数据等方面进行优化。

移除永久代的影响:

  • 由于类的元数据分配在本地内存中,元空间的最大可分配空间就是系统可用内存空间。因此,我们就不会遇到永久代存在时的内存溢出错误,也不会出现泄漏的数据移到交换区这样的事情。最终用户可以为元空间设置一个可用空间最大值,如果不进行设置,JVM会自动根据类的元数据大小动态增加元空间的容量。
  • 注意:永久代的移除并不代表自定义的类加载器泄露问题就解决了。因此,你还必须监控你的内存消耗情况,因为一旦发生泄漏,会占用你的大量本地内存,并且还可能导致交换区交换更加糟糕。

元空间数据管理:

  • 元空间的内存管理由元空间虚拟机来完成。先前,对于类的元数据我们需要不同的垃圾回收器进行处理,现在只需要执行元空间虚拟机的C++代码即可完成。在元空间中,类和其元数据的生命周期和其对应的类加载器是相同的。话句话说,只要类加载器存活,其加载的类的元数据也是存活的,因而不会被回收掉。

元空间调优:

  • 默认情况下,-XX:MaxMetaspaceSize的值没有限制,因此元空间甚至可以延伸到交换区,但是这时候当我们进行本地内存分配时将会失败。
  • 为了避免频繁的GC,建议将–XX:MetaspaceSize设置为一个相对较高的值。对于一个64位的服务器端JVM来说,其默认的–XX:MetaspaceSize值为21MB。这就是初始的高水位线。一旦触及到这个水位线,Full GC将会被触发并卸载没有用的类(即这些类对应的类加载器不再存活),然后这个高水位线将会重置。新的高水位线的值取决于GC后释放了多少元空间。如果释放的空间不足,这个高水位线则上升。如果释放空间过多,则高水位线下降。如果初始化的高水位线设置过低,上述高水位线调整情况会发生很多次。
  • 经过多次GC之后,元空间虚拟机自动调节高水位线,以此来推迟下一次垃圾回收到来。
  • 有这样两个选项 ‑XX:MinMetaspaceFreeRatio和‑XX:MaxMetaspaceFreeRatio,他们类似于GC的FreeRatio选项,用来设置元空间空闲比例的最大值和最小值。我们可以通过命令行对这两个选项设置对应的值。

获取元空间信息的工具:

  • jmap -clstats PID:打印类加载器数据(-clstats是-permstat的替代方案)
  • jstat -gc LVMID:打印元空间的信息
  • jcmd PID GC.class_stats:连接到运行的JVM并输出详尽的类元数据的柱状图。

存在的问题:元空间虚拟机采用了组块分配的形式,同时区块的大小由类加载器类型决定。类信息并不是固定大小,因此有可能分配的空闲区块和类需要的区块大小不同,这种情况下可能导致碎片存在。元空间虚拟机目前并不支持压缩操作,所以碎片化是目前最大的问题。

1.1.4 关于垃圾收集

参考:http://developer.51cto.com/art/201508/489420.htm

1.2 OracleJDK和OpenJDK

稳妥起见,建议OracleJDK。

2. Java开发框架

2.1 Why Springboot?

参考《JavaEE开发的颠覆者:Spring Boot实战》

理念:“习惯优于配置”(项目中存在大量的配置,此外还内置一个习惯性的配置,让你无须手动进行配置),让项目快速运行起来。使用Spring Boot很容易创建一个独立运行(运行jar,内嵌Servlet容器)、准生产级别的基于Spring框架的项目,使用spring Boot你可以不用或者只需要很少的Spring配置。

核心功能:

  • 独立运行的Spring项目:Spring Boot可以以jar包的形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar来运行。
  • 内嵌Servlet容器:Spring Boot可选择内嵌Tomcat、Jetty或者Undertow,这样我们无须以war包形式部署项目。
  • 提供starter简化Maven配置:如使用了spring-boot-starter-web时,会自动加入相关依赖包。
  • 自动配置Spring:Spring Boot会根据在类路径中的jar包、类,为jar包里的类自动配置Bean。
  • 准生产的应用监控:提供基于http、ssh、telnet对运行时的项目进行监控。
  • 无代码生成和xml配置:条件注解而不是xml配置。

优点:

  • 快速构建项目
  • 对主流开发框架的无配置集成
  • 项目可独立运行,无须外部依赖Servlet容器
  • 提供运行时的应用监控
  • 极大地提高了开发、部署效率
  • 与云计算的天然集成

缺点:

  • 书籍文档较少且不够深入

2.2 Hibernate和MyBatis

参考http://blog.csdn.net/firejuly/article/details/8190229

MyBatis优势:

  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
  • MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优势:

  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

3. 前后端分离:单页应用 OR 模板引擎

4. 前后端接口文档自动生成:Swagger

参考:http://blog.csdn.net/wangnan9279/article/details/44541665

Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

5. 业务端校验框架

FunctionalValidator介绍:http://jiebaojie.com/2017/01/28/FunctionalValidator/

主要优点:

  • 校验逻辑与业务逻辑解耦(HibernateValidator只能解决单参数的校验)
  • 目标提供更优雅、更易用的函数式业务逻辑验证框架(相比FluentValidator的优势)

缺点:

  • 不支持JDK7及以下版本
  • 需要对java8语法及函数式编程思想有一定了解

6. CT框架:Rundeck

参考:http://www.tuicool.com/articles/22me6zA

rundeck是一款开源的可以帮助你在数据中心或者云环境自动运行日常程序的软件,rundeck提供了一些特性来缓解费事繁琐的工作,并且很容易让你扩展自己的自动化成果。rundeck允许你在web界面或者命令行上指定在任何节点运行任务。rundeck也包含了其他特性来容易的扩展的你的自动化成果,例如:访问控制、工作流构建、调度、日志等等。

特性:

  • 提供web api
  • 分布式命令执行
  • 可插拔的系统插件
  • 多步骤工作流构建
  • 以守护进程执行job或者调度运行
  • 图形化web控制台来控制job执行
  • 基于规则的访问控制,支持LDAP/AD
  • 历史及构建日志查看
  • 可以集成到外部工具
  • 命令行控制工具

7. UT框架:TestNG和JUnit

参考:http://www.mkyong.com/unittest/junit-4-vs-testng-comparison/

中文翻译版:http://www.importnew.com/16270.html

TestNG 在参数化测试、依赖测试以及套件测试(组)方面功能更加强大。TestNG 意味着高级的测试和复杂的集成测试。它更加的灵活,特别是对大的套件测试。

8. 历史操作记录方案

9. MOCK框架

Mockito和JMockit。

两者的区别是,前者不能mock static method和final class、final method,后者可以,本项目mockito足以。

java技术选型的更多相关文章

  1. atitit.技术选型方法总结为什么java就是比.net有前途

    atitit.技术选型方法总结为什么java就是比.net有前途 #----按照不同的需要有不铜的法... 一般有开发效率,稳定性上的需要.. 作者 老哇的爪子 Attilax 艾龙,  EMAIL: ...

  2. Java开源生鲜电商平台-系统架构与技术选型(源码可下载)

    Java开源生鲜电商平台-系统架构与技术选型(源码可下载) 1.  硬件环境 公司服务器 2.   软件环境 2.1  操作系统 Linux CentOS 6.8系列 2.2 反向代理/web服务器 ...

  3. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

  4. Web开发技术选型之Java与PHP

    PHP与J2EE的对比 网上有很多关于PHP与J2EE之间的对比,细观无非以下几点: 1.语言特征 PHP为脚本语言,解释型语言,弱类型,专为Web开发打造.Java为C语言系编程语言,编译型,强类型 ...

  5. 点菜网---Java开源生鲜电商平台-技术选型(源码可下载)

    点菜网---Java开源生鲜电商平台-技术选型(源码可下载) 1.内容简介 点菜网目前选用的是最流行的微服务架构模式,采用前后端分离的开发模式,具备高可用,高负载,支持千万级别的数据量的请求. 2. ...

  6. 2020 年了,Java 日志框架到底哪个性能好?——技术选型篇

    大家好,之前写(shui)了两篇其他类型的文章,感觉大家反响不是很好,于是我乖乖的回来更新硬核技术文了. 经过本系列前两篇文章我们了解到日志框架大战随着 SLF4j 的一统天下而落下帷幕,但 SLF4 ...

  7. JAVA开源软件的技术选型--开源软件诞生2

    技术准备--第2篇 用日志记录“开源软件”的诞生 赤龙ERP开源地址,点亮星标,支持一下,万分感谢 码云:https://gitee.com/redragon/redragon-erp github: ...

  8. #数据技术选型#即席查询Shib+Presto,集群任务调度HUE+Oozie

    郑昀 创建于2014/10/30 最后更新于2014/10/31   一)选型:Shib+Presto 应用场景:即席查询(Ad-hoc Query) 1.1.即席查询的目标 使用者是产品/运营/销售 ...

  9. 老王讲自制RPC框架.(一.前言与技术选型)

    (#)背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构 当网站流量很小时,只 ...

随机推荐

  1. Windows Server2008 R2中的角色

    AD Certificate Services 官方说明: Active Directory 证书服务 (AD CS) 提供可自定义的服务,用于颁发和管理使用公钥技术的软件安全系统中的证书.可以使用 ...

  2. Jenkins maven 构建乱码,修改file.encoding系统变量编码为UTF-8

    一切都是windows的控制台默认编码GBK问题 情景: 使用jenkins构建,console 输出的中文乱码.代码编码格式是utf-8,因为Jenkins会默认读取当前系统的编码格式,导致构建日志 ...

  3. Linux/Unix 下自制番茄钟

    习惯使用番茄工作法,在Linux上工作时也需要一个番茄钟. 安装一个Linux下番茄钟工作软件? 其实根本没必要,我们可以用Linux下经典的at命令实现一个简单的番茄钟. 安装AT 一般Linux基 ...

  4. Druid.io SQL乱码问题

    1.场景 1.1.依赖版本 avatica-core 1.11.0 druid 0.12.0 1.2.问题重现: 使用Avatica JDBC查询语句:SELECT score FROM studen ...

  5. 【译】第四篇 Replication:事务复制-订阅服务器

    本篇文章是SQL Server Replication系列的第四篇,详细内容请参考原文. 订阅服务器就是复制发布项目的所有变更将传送到的服务器.每一个发布需要至少一个订阅,但是一个发布可以有多个订阅. ...

  6. Django 安装 —Django学习 (一)

    Django Django 是一个python 框架, 采用MTV的模式,模型,模板,视图 注意事项 Django 版本和 python 的版本是一一对应的,安装时一定要注意相应的版本信息. 如下图: ...

  7. phpStudy apache无法启动 apache启动后又停止

    一.是防火墙拦截: 二.是80端口已经被别的程序占用,如IIS,迅雷等: 三.是没有安装VC9运行库,php和apache都是VC9编译: 四.虚拟机配置路径中有中文: 五.在检测端口后强制重启 把配 ...

  8. JavaScript新手学习笔记(一)

    1.JavaScript 对大小写敏感. JavaScript 对大小写是敏感的. 当编写 JavaScript 语句时,请留意是否关闭大小写切换键. 函数 getElementById 与 getE ...

  9. Linux下配置镜像源

    清华大学地址: https://mirrors.tuna.tsinghua.edu.cn 选择对应ubuntu的版本 在linux下用终端敲 cd /etc/apt/source.list 把里面的内 ...

  10. Python的日志记录-logging模块的使用

    一.日志 1.1什么是日志 日志是跟踪软件运行时所发生的事件的一种方法,软件开发者在代码中调用日志函数,表明发生了特定的事件,事件由描述性消息描述,同时还包含事件的重要性,重要性也称为级别或严重性. ...