本文是本人给公司2020年招聘的应届毕业生进行为期一天的java培训课程课件。主要目的是:让应届生对系统及系统权限、开发流程、开发注意事项有个基本的认识;便于后续进入项目组快速融入团队、快速上手开发
01
—
J2EE基础开发与代码规约
1、JDK的发展历程
JDK从1991年发展至今,经历了快20余载;商业上目前用的最多的版本主要是:JDK6、JDK8。2020年3月已发布JDK14;对待新版本的态度还是处于观望中。

2、CS与BS的区别
目前商业中除了CS/BS架构外,还存在着CBS混合的架构类型,通过下图的对比我们能清楚的知道:无论是BS还是CS都有各自的优缺点。

1、安全性:C/S端交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据;
2、性能:B/S端的稳定性高于C/S端,只需要保证服务器的稳定性,而不需要关注客户端的情况;
3、维护成本:C/S的客户端维护成本高;
4、可应用性:BS的可应用性强,只需要有浏览器即可
5、可移植性:BS的由于无客户端,只需解决浏览器的兼容性问题,CS端需要考虑各种机型的适配
6、用户体验:C/S能充分发挥客户端PC的处理能力,响应速度快、操作界面漂亮

3、架构设计的历史背景
架构设计的主要目的是为了解决软件系统复杂度带来的问题,由下图可知,软件架构的出现是有其必然性:
3.1、机器语言:特点:太难写、太难读、太难改;
3.2、汇编语言:①需要了解计算机底层的知识:CPU指令、寄存器、段地址; ②编写复杂,不同的CPU的汇编指令和结构是不同的,需要为不同的CPU编写不同的指令
3.3、高级语言:
①高级语言让程序员不需要关注机器底层的低级结构和逻辑,而只需要关注具体的问题和业务;
②高级语言可以被编译为适合不同CPU指令的机器语言;程序员只需要写一次程序,就可以在多个不同的机器上编译运行,无须根据不同的机器指令重写整个程序.
3.4、结构化程序设计的主要特点:
①抛弃goto语句,采取“自顶向下、逐步细化、模块化”的指导思想;
②结构化程序设计本质上还是一种面向过程的设计思想,但通过“自顶向下、逐步细化、模块化”的方法,将软件的复杂度控制在一定范围内,从而从整体上降低了软件开发的复杂度;
3.5、面向对象编程的历史背景:
结构化程序设计虽然能够缓解软件逻辑的复杂性,但是对于业务变化带来的软件扩展却无能为力,软件领域迫切希望找到新的银弹来解决软件危机,在这种背景下,面向对象的思想开始流行起来;
3.6、软件架构的出现有其历史必然性
①系统规模庞大,内部耦合严重,开发效率低;
②系统耦合严重,牵一发动全身,后续修改和扩展困难;
③系统逻辑复杂,容易出问题,出问题后很难排查和修复。

4、架构是什么?
架构是基础结构,框架是规范;
按照规范搭建系统的基础结构后,再进行组件与模块的开发;
把有关联的模块与组件按照一定的规则进行集成运作,我们称之为(子)系统;
一个个(子)系统按照一定的规则进行组合则称之为一个系统


架构与框架的区别
5、谈谈对系统的认识?
一个系统的从开发到上线,需要经过如下以下步骤:
a、架构师按照框架的规范来搭建系统的基础架构;
b、开发人员根据系统的架构来进行业务逻辑代码的编写开发,形成一个个组件或者模块;
c、将开发好的模块、组件按照业务规则进行对接,集成为一个系统。
那么一个好的系统架构需要包括哪些基本的功能呢?
1、需要具备基本的人员管理、组织机构管理、角色权限管理、日志管理、数据字典管理等基本的功能模块;
2、对于角色权限的管理需要更细力度的区分数据权限和角色权限;
3、需要具备saas化的能力。

基本功能模块图
6、开发规约的好处?
好的编码规范可以尽可能的减少一个软件的维护成本,没有任何一个软件是在其整个生命周期中均由最初的开发人员来维护;
好的编码规范可以改善软件的可读性,可以让开发人员尽快而彻底地理解新的代码;

02
—
接口与多线程的开发
1、接口的定义
1.继承抽象类的子类们的本质都是相似的,它们体现的是一种 “is-a" 的关系,就像动物中的猫和狗;
2、对于接口的继承更多的是一种行为的相似,是一种 “like-a” 的关系,比如飞机和鸟,它们都具有飞的行为,却并不需要在本质上相似。
3、抽象类可以拥有任意范围的成员数据,既可以是抽象,也可以是非抽象;
4、接口,所有的方法必须是抽象的,所有的成员变量必须是 public static final的,某种程度上来说,接口是对抽象类的一种抽象。
5、一个类只能继承一个抽象类,但却可以实现多个接口。

2、访问权限

3、常用接口
基本数据类型
java为int、byte、boolean、short、long、float、double、char等基本数据类型提供了包装类,除了int的是Integer,char的是Character,其他都是把开头字母改成大写,其功能就是将这些基本数据类型转储成对象。
字符串类型
1、String 不可变长度
2、StringBuilder和StringBuffer一样是可变字符串,使用方法也都差不多,StringBuilder效率比StringBuffer要高,但是线程的安全性较低(没有用synchronized修饰符)
4、接口开发注意事项

5、进程与线程
进程:是具有一定独立功能的程序关于某个数据集合上的一次活动,是系统进行资源分配和调度的一个独立单位。
线程:是进程的一个实体,是cpu调度和分派的基本单位,他是比进程更小的能够独立运行的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源。一个线程可以创建和撤销另一个线程。
线程的实现方式:
1)继承Thread类创建线程
2)实现Runnable接口创建线程
3)使用Callable和Future创建线程
线程常用方法:

线程的生命周期

6、死锁
什么是死锁?
死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。
死锁不仅仅是在线程之间会发生,存在资源独占的进程之间同样也可能出现死锁。
通常来说,我们大多是聚焦在多线程场景中的死锁,指两个或多个线程之间,由于互相持有对方需要的锁,而永久处于阻塞的状态。
如何定位死锁?
定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位互相之间的依赖关系,进而找到死锁。
如果是比较明显的死锁,往往jstack等就能直接定位,类似JConsole甚至可以在图形界面进行有限的死锁检测。
如果程序运行时发生了死锁,绝大多数情况下都是无法在线解决的,只能重启、修正程序本身问题。
所以,代码开发阶段互相审查,或者利用工具进行预防性排查,也是很重要的。
死锁发生的原因?
1、互斥条件,类似java中Monitor都是独占的,要么是我用,要么是你用;
2、互斥条件是长期持有的,在使用结束之前,自己不会释放,也不能被其他线程抢占;
3、循环依赖关系,两个或者多个个体之间出现了锁的链条环。
避免死锁的方法有哪些?
1、尽量避免使用多个锁,并且只有需要时才持有锁;嵌套的synchronized或者lock是非常容易出问题的;
2、如果必须使用多个锁,尽量设计好锁的获取顺序;
3、使用带超时的方法,为程序带来更多可控性
死锁案例代码
package test;public class DeadLockDemo extends Thread {private String first;private String second;public DeadLockDemo(String name,String first,String second){super(name);this.first=first;this.second=second;}public void run(){synchronized (first){System.out.println(this.getName()+"="+first);try{Thread.sleep(1000L);synchronized (second){System.out.println(this.getName()+"="+second);}}catch (Exception e){//}}}public static void main(String[] args) throws Exception{String lockA="lockA";String lockB="lockB";//传入顺序相同的两个锁,不会发生死锁/** DeadLockDemo t1 = new DeadLockDemo("Thread1",lockA,lockB);DeadLockDemo t2= new DeadLockDemo("Thread2",lockA,lockB);*//**开启2个线程,两个锁的顺序相反,发生死锁*/DeadLockDemo t1 = new DeadLockDemo("Thread1",lockA,lockB);DeadLockDemo t2= new DeadLockDemo("Thread2",lockB,lockA);t1.start();t2.start();t1.join();t2.join();}}
原文作者:小南瓜开发平台;如有侵权,请联系管理员删除。