Java中级开发工程师知识点

时间:2020-11-13 16:31:21 JAVA认证 我要投稿

Java中级开发工程师知识点

  根据IDC的统计数字,在所有软件开发类人才的需求中,对Java程序员的需求达到全部需求量的60%~70%。同时,Java程序员的薪水相对较高。yjbys小编收集了一些关于Java中级开发工程师知识点,希望大家认真阅读!

Java中级开发工程师知识点

  一、版本更新说明:

  2015.03.09--------文章发布

  2015.03.11--------添加了Java IO机制中的种类和应用场景的解释,添加了Java内存模型的相关知识点

  2015.03.13--------文章按技术划分,增加J2EE规范的解释

  2015.04.25--------增加对LRU缓存设计的描述

  2015.04.26--------增加对比较流行的开源技术和开源框架的介绍,对于这些技术的理解或使用可以增加自己的竞争优势,同时扩展自己的眼界

  2015.04.27--------增加对数据库事务的描述

  二、正文

  (一)Java

  1.接口和抽象类的区别

  ①抽象类里可以有构造方法,而接口内不能有构造方法。

  ②抽象类中可以有普通成员变量,而接口中不能有普通成员变量。

  ③抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。

  ④抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽象方法只有public和默认类型。

  ⑤ 抽象类中可以包含静态方法,接口内不能包含静态方法。

  ⑥抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。

  ⑦一个类可以实现多个接口,但只能继承一个抽象类。

  ⑧接口更多的是在系统框架设计方法发挥作用,主要定义模块之间的通信,而抽象类在代码实现方面发挥作用,可以实现代码的重用。

  2.Java虚拟机的运行时数据区有几块?线程私有和线程共享区域有哪些?

  ①程序计数器:线程私有,当前县城执行的字节码的行号指示器。

  ②虚拟机栈:线程私有,存放基本数据类型、对象引用和returnAddress类型。

  ③本地方法栈:为虚拟机使用到的Native方法服务。

  ④Java堆:线程共享,存放对象的实例,也是GC回收器管理的主要区域。

  ⑤方法区:线程共享,存放已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

  ⑥运行时常量池:方法区的一部分,存放编译期生成的各种字面量和符号引用。

  ⑦直接内存:不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,容易引起OOM异常,NIO会调用,不受Java堆大小的限制。

  3.HashMap和HashTable区别?

  ①Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

  ②Hashtable的方法是同步的,而HashMap的方法不是,因此HashTable是线程安全的,但是代码的执行效率上要慢于HashMap。

  ③HashMap允许空值和空键,但是HashTable不可以。

  ④HashMap非同步实现Map接口,是一个“链表数组”的数据结构,最大承载量是16,可以自动变长,由Entry[]控制(key,value,next),hashCode()判断key是否重复。

  ⑤建议需要做同步,使用ConcurrentHashMap,降低了锁的粒度。在hashMap的基础上,ConcurrentHashMap将数据分为多个segment,默认16个(concurrency level),然后每次操作对一个segment加锁,避免多线程锁得几率,提高并发效率。这里在并发读取时,除了key对应的value为null之外,并没有使用锁。

  4.ArrayList和LinkedList区别?

  ArrayList基于数组实现,LinkedList基于链表实现,ArrayList增加和删除比LinkedList慢,但是LinkedList在查找的时需要递归查找,效率比ArrayList慢。关于多线程方面,如果要求线程安全的,有一个Vector,不过比较多的使用的是CopyOnWriteArrayList替代ArrayList,CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。发生修改时候做copy,新老版本分离,保证读的高性能,适用于以读为主的情况。

  5.Set接口

  ①HashSet是Set接口的典型实现,HashSet按hash算法来存储元素,因此具有很好的存取和查找性能。特点:不能保证元素的排列顺序,顺序有可能发生变化;HashSet是异步的;集合元素值可以是null;当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该HashCode值来确定该对象在HashSet中存储的位置。HashSet还有一个子类LinkedHashSet,其集合也是根据元素hashCode值来决定元素的存储位置,但它同时用链表来维护元素的次序,这样使得元素看起来是以插入的顺序保存的,也就是说,当遍历LinkedHashSet集合元素时,它将会按元素的添加顺序来访问集合里的元素。所以LinkedHashSet的性能略低于HashSet,但在迭代访问全部元素时将有很好的性能,因为它以链表来维护内部顺序。

  ②TreeSet是SortSet接口的唯一实现,TreeSet可以确保集合元素处于排序状态。TreeSet不是根据元素插入顺序进行排序的,而是根据元素的值来排序的。TreeSet支持两种排序方法:自然排序和定制排序。

  ③EnumSet中所有值都必须是指定枚举类型的值,它的元素也是有序的,以枚举值在枚举类的定义顺序来决定集合元素的顺序。EnumSet集合不允许加入null元素,否则会抛出NullPointerException异常。EnumSet类没有暴露任何构造器来创建该类的实例,程序应该通过它提供的static方法来创建EnumSet对象。

  ④总结:A、HashSet的性能比Treeset好,因为TreeSet需要额外的红黑树算法来维护集合元素的次序,只有当需要一个保持排序的Set时,才会用TreeSet。B、EnumSet是性能最好的,但它只能保存枚举值。

  C、它们都是线程不安全的。

  注:Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。

  关于HashSet,条目数和容量之和来讲,迭代是线性的。因此,如果迭代性能很重要,那就应该慎重选择一个适当的初始容量。容量选得太大,既浪费空间,也浪费时间。默认的初试容量是101,一般来讲,它比你所需要的要多。可以使用int构造函数来指定初始容量。要分配HashSet的初始容量为17:

  Set s=new HashSet(17);

  HashSet另有一个称作装载因数(load factor)的"调整参数(tuning parameter)"。

  区别:

  1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。

  2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能.

  3. hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可.

  a. hashCode是用来计算hash值的,hash值是用来确定hash表索引的.

  b. hash表中的一个索引处存放的是一张链表, 所以还要通过equal方法循环比较链上的每一个对象 才可以真正定位到键值对应的Entry.

  c. put时,如果hash表中没定位到,就在链表前加一个Entry,如果定位到了,则更换Entry中的value,并返回旧value

  4. 由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较.当然也是用Comparator定位的.

  a. Comparator可以在创建TreeMap时指定

  b. 如果创建时没有确定,那么就会使用key.compareTo()方法,这就要求key必须实现Comparable接口.

  TreeMap是使用Tree数据结构实现的,所以使用compare接口就可以完成定位了.

  6.Java中Collection和Collections的区别

  ①java.util.Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法。java.util.Collections 是一个包装类。

  ②它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

  7.Java容器

  JAVA的容器---List,Map,Set

  Collection

  ├List

  │├LinkedList

  │├ArrayList

  │└Vector

  │ └Stack

  └Set

  Map

  ├Hashtable

  ├HashMap

  └WeakHashMap

  !其中的Vector和Stack类现在已经极少使用。

  8.Cookie Session区别

  具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案.同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择.

  cookie机制.正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie.然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie.而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的.浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器.

  cookie的内容主要包括:名字,值,过期时间,路径和域.路径与域一起构成cookie的作用范围.若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失.这种生命期为浏览器会话期的cookie被称为会话cookie.会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的.若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间.存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口.而对于保存在内存里的cookie,不同的浏览器有不同的处理方式

  session机制.session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息.

  当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存.

  保存这个sessionid的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器.一般这个cookie的名字都是类似于SEEESIONID.但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器.

  经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面.还有一种技术叫做表单隐藏字段.就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器.比如:实际上这种技术可以简单的用对action应用URL重写来代替.

  9、面向对象和面向过程的区别:

  面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

  面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

  10、Java内存模型

  ①Java内存模型分为主内存和工作内存两个部分,其中主内存存放变量,工作内存由每个线程创建和管理,保存被该线程使用到的变量的主内存的副本拷贝。变量从主内存复制到工作内存,顺序执行read和load操作,变量从工作内存同步到主内存的时候,顺序执行store和write操作。

  对于volatile变量在各个线程的一致性:在各个线程的工作内存中,volatile存在不一致的情况,但在每次使用前都会刷新,执行引擎看不到不一致的情况,因此可以认为不存在一致性问题。

  ②原子性、可见性和有序性

  ③先行发生原则

  11、Java垃圾回收机制

  Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。

  System.gc();

  Runtime.getRuntime().gc();

  上面的方法调用时用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。

  12、类加载器,类加载时机

  类初始化的时机,有且仅有四个:

  A、遇到new、getstatic、putstatic、invokestatic这四条字节码指令的时候。

  B、使用java.lang.reflect进行反射调用的时候。

  C、当初始化一个类的时候,发现其父类还没有初始化,那么先去初始化它的父类。

  D、当虚拟机启动的时候,需要初始化main函数所在的类。

  13、 Java IO和NIO区别

  ①NIO操作直接缓存区,直接与OS交互,Selector IO复用机制。

  IO NIO

  面向流 面向缓冲

  阻塞IO 非阻塞IO

  无 选择器

  Selector:Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

  ②NIO与Netty:A、NIO的类库和API复杂,使用麻烦,需要熟练使用Selector、ServerSocketChannel、SOcketChannel、ByteBuffer等。B、NIO涉及到Reactor模式,需要了解Java多线程和网络编程。C、JDKNIO Bug-epoll bug容易导致Selector空轮询,最终导致CPU100%占用,虽然JDK1.6 update18修复了这个问题,但是直到JDK1.7问题依然存在,只是降低了发生的概率。

  ③Netty的优点:A、API简单,开发门槛低;B、功能强大,预置了多种解码功能,支持多种主流协议;C、可以通过ChannelHandler对通信框架进行灵活的扩展;D、性能高,Netty的综合性能是最好的;E、Netty修复了一经发现了所有的JDKNIO BUG,成熟,稳定。

  同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

  引申:

  Java中IO的种类和应用场景:

  A、同步阻塞式:BIO。用于连接数目较小且固定的架构,对服务器资源占用高。

  B、伪异步IO变成:线程池和任务队列。

  C、NIO编程:a、缓冲徐ByteBuffer;b、通道channel全双工,同时用于读写;c、多路复用器selector。用于连接数目多且较短的架构,如聊天服务器等,但是编程复杂,存在epoll bug,导致Selector空轮询,直至CPU占用达到100%,虽然在JDK1.6 update18中有对这个bug的修复,但是在JDK1.7中依然可能会出现这个问题,只是降低了bug出现的概率。

  D、AIO编程:用于连接数目多且较长的架构,如相册服务器等,充分调用OS参与并发操作,基于JDK1.7。

  阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

  14、Java锁机制

  ①synchronized:把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性和可见性。作用:A、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。B、当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。C、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

  A、原子性:原子性意味着个时刻,只有一个线程能够执行一段代码,这段代码通过一个monitor object保护。从而防止多个线程在更新共享状态时相互冲突。

  B、可见性:可见性则更为微妙,它要对付内存缓存和编译器优化的各种反常行为。它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的。

  C、volatile只保证可见性和禁止重排序,不保证原子性。

  ②synchronized限制:

  A.它无法中断一个正在等候获得锁的线程;

  B.也无法通过投票得到锁,如果不想等下去,也就没法得到锁;

  C.同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行,多数情况下,这没问题(而且与异常处理交互得很好),但是,确实存在一些非块结构的锁定更合适的情况。

  ③java.util.concurrent.lock:

  ReentrantLock 类实现了Lock,它拥有与synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。

  用sychronized修饰的方法或者语句块在代码执行完之后锁自动释放,而是用Lock需要我们手动释放锁,所以为了保证锁最终被释放(发生异常情况),要把互斥区放在try内,释放锁放在finally内。

  ④ReentrantWriteReadLock中的ReadLock和WWriteLock,在全为读时实现并发读,并发读写或并发写时候加锁。

  总结:synchronized是Java原语,阻塞的,竞争锁机制;新锁更加面向对象,并且支持中断和支持公平锁。

  15、Java基本数据类型

  boolean(1)、byte(8)、16)、short(16)、int(32)、float(32)、long(64)、double(64)

  16、Java内存模型

  ①特点:原子性、可见性、有序性。

  A、原子性:read、load、use、store、write,synchronized关键字保证原子性

  B、可见性:synchronized、volatile、final保证可见性

  C、有序性:synchronized保证有序性

  17、设计模式

  ①分类:

  创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

  结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

  行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

  其实还有两类:并发型模式和线程池模式。

  ②设计模式6大原则:

  A、开闭原则(Open Close Principle)

  开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

  B、里氏代换原则(Liskov Substitution Principle)

  里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科

  C、依赖倒转原则(Dependence Inversion Principle)

  这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。

  D、接口隔离原则(Interface Segregation Principle)

  这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

  F、迪米特法则(最少知道原则)(Demeter Principle)

  为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

  F、合成复用原则(Composite Reuse Principle)

  原则是尽量使用合成/聚合的方式,而不是使用继承。

  18、Java反射

  反射机制指的是程序在运行时能够获取自身的信息。

  为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,

  静态编译:在编译时确定类型,绑定对象,即通过。

  动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

  一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中

  它的灵活性就表现的十分明显。

  作用:①首先得根据传入的类的全名来创建Class对象。 ②获得类方法的方法。③ 获得类中属性的方法。

  缺点:①性能第一:反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。②安全限制:使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet。③内部暴露:由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。

  19、Java引用

  ①假设我们在函数中写了如下这个简单的语句:

  StringBuffer str= new StringBuffer("Hello world");

  别看这个语句简单,其实包含了如下三个步骤:

  首先,new StringBuffer("Hello world")在堆里申请了一坨内存,把创建好的StringBuffer对象放进去。其次,StringBuffer str声明了一个指针。这个指针本身是存储在栈上的(因为语句写在函数中),可以用来指向某个StringBuffer类型的对象。或者换一种说法,这个指针可以用来保存某个StringBuffer对象的地址。最后,当中这个等于号(赋值符号)把两者关联起来,也就是把刚申请的那一坨内存的地址保存成str的值,完成引用。

  ②final常量的问题

  针对引用类型变量的final修饰符也是很多人搞混淆的地方。实际上final只是修饰指针的值(也就是限定指针保存的地址不能变)。至于该指针指向的对象,内容是否能变,那就管不着了。所以,对于如下语句:

  final StringBuffer strConst = new StringBuffer();

  你可以修改它指向的对象的内容,比如:

  strConst.append(" ");

  但是不能修改它的值,比如:

  strConst = null;

  ③传参的问题:

  例如:System.out.println(str);这个语句又是什么意思捏?这时候就两说了。

  第一种理解:可以认为传进函数的是str这个指针,指针说白了就是一个地址的值,说得再白一点,就是个整数。按照这种理解,就是传值的方式。也就是说,参数传递的是指针本身,所以是传值的。

  第二种理解:可以认为传进去的是StringBuffer对象,按照这种理解,就是传引用方式了。因为我们确实是把对象的地址(也就是引用)给传了进去。

  20、 线程、线程池:

  ①创建线程有两种方式:继承Thread或实现Runnable。Thread实现了Runnable接口,提供了一个空的run()方法,所以不论是继承Thread还是实现Runnable,都要有自己的run()方法。一个线程创建后就存在,调用start()方法就开始运行(执行run()方法),调用wait进入等待或调用sleep进入休眠期,顺利运行完毕或休眠被中断或运行过程中出现异常而退出。

  ②wait和sleep比较:sleep方法有:sleep(long millis),sleep(long millis, long nanos),调用sleep方法后,当前线程进入休眠期,暂停执行,但该线程继续拥有监视资源的所有权。到达休眠时间后线程将继续执行,直到完成。若在休眠期另一线程中断该线程,则该线程退出。等待有其它的线程调用notify()或notifyAll()进入调度状态,与其它线程共同争夺监视。

  ③线程池:多线程技术主要解决处理器单元内多个线程执行的'问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。一个线程池包括以下四个基本组成部分:

  A、线程池管理器(ThreadPool):用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;

  B、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;

  C、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;

  D、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

  ④线程池分类:

  A、newFixedThreadPool 创建一个指定工作线程数量的线程池。

  每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。

  B、newCachedThreadPool创建一个可缓存的线程池。

  这种类型的线程池特点是:

  1).工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger.MAX_VALUE), 这样可灵活的往线程池中添加线程。

  2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。

  C、newSingleThreadExecutor创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,如果这个线程异常结束,会有另一个取代它,保证顺序执行(我觉得这点是它的特色)。

  单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。

  D、newScheduleThreadPool 创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。

  ⑤Executors类,提供了一系列静态工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。

  ⑥线程池参数:

  A、corePoolSize(线程池的基本大小)

  B、runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。

  1)LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。

  2)SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。

  3)PriorityBlockingQueue:一个具有优先级的无限阻塞队列。

  C、maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。

  D、ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字。

  E、RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略:

  1)AbortPolicy:直接抛出异常。

  2)CallerRunsPolicy:只用调用者所在线程来运行任务。

  3)DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。

  4)DiscardPolicy:不处理,丢弃掉。

  5)当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。

  F、keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。

  G、TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

  21、J2EE的13种规范

  (1)、JDBC(java Database Connectivity):

  JDBC API为访问不同的数据库提供了一种统一的途径,就像ODBC一样,JDBC对开发者屏蔽了一些细节问题,同时,JDBC对数据库的访问也具有平台无关性。

  (2)、JNDI(Java Name and Directory Interface):

  JNDI API 被用于执行名字和目录服务。它提供了一致的模型用来存取和操作企业级的资源如DNS和LDAP,本地文件系统,或应用服务器中的对象。

  (3)、EJB(Enterprise JavaBean):

  J2ee技术之所以赢得全体广泛重视的原因之一就是EJB,他们提供了一个框架开发和实施分布式商务逻辑,由此很显著简化了具有可伸缩性和高度复杂的企业级应用开发。EJB规范定义了EJB组件何时如何与他们的容器继续拧交互作用。容器负责提供公用的服务,例如目录服务、事务管理、安全性、资源缓冲池以及容错性。但是注意的是,EJB并不是J2EE的唯一途径。正是由于EJB的开放性,使得有的厂商能够以一种和EJB平行的方式来达到同样的目的。

  (4)、RMI(RemoteMethod Invoke):remote(遥远的) invoke(调用):

  正如其名字所表示的那样,RMI协议调用远程对象上方法。它使用了序列化方式在客户端和服务器端传递数据。RMI是一种被EJB使用的更底层的协议。

  (5)、Java IDL(接口定义语言)/CORBA:公共对象请求代理结构(Common Object Request Breaker Architecture):

  在java IDL的支持下,开发人员可以将Java和CORBA集成在一起。他们可以创建Java对象并使之可以在CORBA ORB中展开,或者他们还可以创建Java类并做为和其他ORB一起展开的CORBA对象客户。后一种方法提供了另外一种途径,通过它可以被用于你的新的应用和旧系统相集成。

  (6)、JSP(Java Server Pages):

  Jsp页面由html代码和嵌入其中的Java新代码所组成。服务器在页面被客户端所请求以后对这些java代码进行处理,然后将生成的html页面返回给客户端的浏览器。

  (7)、Java Servlet:

  servlet是一种小型的java程序,它扩展了web服务器的功能。作为一种服务器端的应用,当被请求时开始执行,这和CGI Perl脚本很相似。Servlet提供的功能大多和jsp类似,不过实现方式不同。JSP通过大多数的html代码中嵌入少量的java代码,而servlet全部由java写成并生成相应的html。

  (8)、XML(Extensible Markup Language):

  XML是一种可以用来定义其他标记语言的语言。它被用来在不同的商务过程中共享数据。XML的发展和Java是互相独立的,但是,它和java具有相同目标正是平台立。通过java和xml的组合,我们可以得到一个完美的具有平台立性的解决方案。

  (9)、JMS(Java Message Service):

  Ms是用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域,有支持发布/订阅类型的域,并且提供对下列类型的支持:经认可的消息传递,事务性消息传递,一致性消息和具有持久性的订阅者的支持。JMS还提供了另一种方式对您的应用与旧的后台系统相集成。

  (10)、JTA(Java Transaction Architecture):

  JTA定义了一种标准API,应用系统由此可以访问各种事务监控。

  (11)、JTS(Java Transaction Service):

  JTS是CORBA OTS事务监控的基本实现。JTS规定了事务管理器的实现方式。该事务管理器是在高层支持Java Transaction API(JTA)规范,并且在较底层实现OMG OTS specification 的java映像。JTS事务管理器为应用服务器、资源管理器、独立的应用以及通信资源管理器提供了事务服务。

  (12)、JavaMail:

  JavaMail是用于存取邮件服务的API,它提供了一套邮件服务器的抽象类。不仅支持SMTP服务器,也支持IMAP服务器。

  (13)、JAF(JavaBeans Activation Framework):

  JavaMail利用JAF来处理MIME编码的邮件附件。MIME的字节流可以被转换成java对象,或者转换自Java对象。大多数应用都可以不需要直接使用JAF。

  22、try/catch/finally/return 作用顺序

  不管有木有出现异常,finally块中代码都会执行;

  当try和catch中有return时,finally仍然会执行;

  finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;

  finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

  (二)服务器

  1、web服务器nginx和apache的对比分析

  ①nginx相对于apache的优点:

  轻量级,同样起web 服务,比apache 占用更少的内存及资源 ,抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能,高度模块化的设计,编写模块相对简单。

  apache相对于nginx 的优点:A.rewrite ,比nginx 的rewrite 强大;B.动态页面,模块超多,基本想到的都可以找到;C.少bug ,nginx 的bug 相对较多;D.超稳定.

  一般来说,需要性能的web 服务,用nginx 。如果不需要性能只求稳定,那就apache.

  ②作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率。Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多.

  ③Nginx 配置简洁,Apache 复杂。Nginx 静态处理性能比 Apache 高 3倍以上,Apache 对 PHP 支持比较简单,Nginx 需要配合其他后端用。Apache 的组件比 Nginx 多,现在 Nginx 才是Web 服务器的首选。

  ④最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程。

  ⑤nginx处理静态文件好,耗费内存少.但无疑apache仍然是目前的主流,有很多丰富的特性.所以还需要搭配着来.当然如果能确定nginx就适合需求,那么使用nginx会是更经济的方式。

  ⑥nginx处理动态请求是鸡肋,一般动态请求要apache去做,nginx只适合静态和反向。

  ⑦Nginx优于apache的主要两点:A.Nginx本身就是一个反向代理服务器 B.Nginx支持7层负载均衡;其他的当然,Nginx可能会比 apache支持更高的并发。

【Java中级开发工程师知识点】相关文章:

1.Java中级开发工程师知识点归纳

2.Java中级开发工程师笔试题及答案2016

3.JAVA开发工程师岗位介绍

4.java开发工程师模拟试题2017

5.Java开发工程师试卷及答案解析

6.java中级工程师面试题

7.Java 开发环境配置

8.Java编程开发简介