2015.03.09--------文章发布html
2015.03.11--------添加了Java IO机制中的种类和应用场景的解释,添加了Java内存模型的相关知识点java
2015.03.13--------文章按技术划分,增长J2EE规范的解释mysql
2015.04.25--------增长对LRU缓存设计的描述nginx
2015.04.26--------增长对比较流行的开源技术和开源框架的介绍,对于这些技术的理解或使用能够增长本身的竞争优点,同时扩展本身的眼界web
2015.04.27--------增长对数据库事务的描述redis
1.接口和抽象类的区别算法
①抽象类里能够有构造方法,而接口内不能有构造方法。spring
②抽象类中能够有普通成员变量,而接口中不能有普通成员变量。sql
③抽象类中能够包含非抽象的普通方法,而接口中全部的方法必须是抽象的,不能有非抽象的普通方法。mongodb
④抽象类中的抽象方法的访问类型能够是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重写来代替.
九、面向对象和面向过程的区别:
面向过程就是分析出解决问题所须要的步骤,而后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就能够了。
面向对象是把构成问题事务分解成各个对象,创建对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
十、Java内存模型
①Java内存模型分为主内存和工做内存两个部分,其中主内存存放变量,工做内存由每一个线程建立和管理,保存被该线程使用到的变量的主内存的副本拷贝。变量从主内存复制到工做内存,顺序执行read和load操做,变量从工做内存同步到主内存的时候,顺序执行store和write操做。
对于volatile变量在各个线程的一致性:在各个线程的工做内存中,volatile存在不一致的状况,但在每次使用前都会刷新,执行引擎看不到不一致的状况,所以能够认为不存在一致性问题。
②原子性、可见性和有序性
③先行发生原则
十一、Java垃圾回收机制
Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。
System.gc();
Runtime.getRuntime().gc();
上面的方法调用时用于显式通知JVM能够进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动做这一样是不可预料的,这和抢占式的线程在发生做用时的原理同样。
十二、类加载器,类加载时机
类初始化的时机,有且仅有四个:
A、遇到new、getstatic、putstatic、invokestatic这四条字节码指令的时候。
B、使用java.lang.reflect进行反射调用的时候。
C、当初始化一个类的时候,发现其父类尚未初始化,那么先去初始化它的父类。
D、当虚拟机启动的时候,须要初始化main函数所在的类。
1三、 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操做完全完成。
1四、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原语,阻塞的,竞争锁机制;新锁更加面向对象,而且支持中断和支持公平锁。
1五、Java基本数据类型
boolean(1)、byte(8)、char(16)、short(16)、int(32)、float(32)、long(64)、double(64)
1六、Java内存模型
①特色:原子性、可见性、有序性。
A、原子性:read、load、use、store、write,synchronized关键字保证原子性
B、可见性:synchronized、volatile、final保证可见性
C、有序性:synchronized保证有序性
1七、设计模式
①分类:
建立型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
②设计模式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)
原则是尽可能使用合成/聚合的方式,而不是使用继承。
1八、Java反射
反射机制指的是程序在运行时可以获取自身的信息。
为何要用反射机制?直接建立对象不就能够了吗,这就涉及到了动态与静态的概念,
静态编译:在编译时肯定类型,绑定对象,即经过。
动态编译:运行时肯定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以下降类之间的藕合性。
一句话,反射机制的优势就是能够实现动态建立对象和编译,体现出很大的灵活性,特别是在J2EE的开发中
它的灵活性就表现的十分明显。
做用:①首先得根据传入的类的全名来建立Class对象。 ②得到类方法的方法。③ 得到类中属性的方法。
缺点:①性能第一:反射包括了一些动态类型,因此JVM没法对这些代码进行优化。所以,反射操做的效率要比那些非反射操做低得多。咱们应该避免在常常被 执行的代码或对性能要求很高的程序中使用反射。②安全限制:使用反射技术要求程序必须在一个没有安全限制的环境中运行。若是一个程序必须在有安全限制的环境中运行,如Applet。③内部暴露:因为反射容许代码执行一些在正常状况下不被容许的操做(好比访问私有的属性和方法),因此使用反射可能会致使意料以外的反作用--代码有功能上的错误,下降可移植性。反射代码破坏了抽象性,所以当平台发生改变的时候,代码的行为就有可能也随着变化。
1九、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, 千分之一微秒)。
2一、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。
一、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支持更高的并发。
一、数据库优化:
①方法:MySQL能够建分表,读写分离,建索引,通常常常更新的字段不适合建索引,建索引会下降数据非查询操做的效率。主键是一种特殊的索引。
②致使索引失效的状况:
A、若是条件中有or,即便其中有条件带索引也不会使用到。
B、对于多列索引,不是使用的第一部分,则不会使用索引。
C、like查询是以%开头,而不是以%结尾的。
D、若是索引列类型是字符串,必定要在条件中将数据使用引号引用起来,不然不使用索引。
E、若是mysql估计使用全表扫描要比使用索引快,则不使用索引。
二、MySQL引擎的种类和区别
①种类:MyISAM、InnoDB、MEMORY、MERGE、Archive、Blackhole、CSV、Federate、Merge、NDB集群引擎,第三方引擎:OLTP类引擎、面向列的存储引擎、社区存储引擎。
②区别:
A、MyISAM是MySQL5.1及以前的默认存储引擎。MyISAM不支持事务、也不支持外键,但其访问速度快,对事务完整性没有要求。MyISAM表还支持3中不一样的存储格式:
1 静态表
2 动态表
3 压缩表
B、InnoDB存储引擎提供了具备提交、回滚和崩溃恢复能力的事务安全。可是比起MyISAM存储引擎,InnoDB写的处理效率差一些而且会占用更多的磁盘空间以保留数据和索引。 InnoDB存储方式为两种:1 使用共享表空间存储 2 使用多表空间
C、MEMORY存储引擎使用存在内存中的内容来建立表。每一个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问很是得快,由于它的数据是放在内存中的,而且默认使用HASH索引。可是一旦服务关闭,表中的数据就会丢失掉。
D、MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构彻底相同。MERGE表自己没有数据,对MERGE类型的表进行查询、更新、删除的操做,就是对内部的MyISAM表进行的。
三、数据库事务
(1)四个特性:ACID,原子性,一致性,隔离性,持久性。
(2)四个隔离级别:
√: 可能出现 ×: 不会出现
脏读 | 不可重复读 | 幻读 | |
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable read | × | × | √ |
Serializable | × | × | × |
Read Uncommitted(读取未提交内容)
在该隔离级别,全部事务均可以看到其余未提交事务的执行结果。本隔离级别不多用于实际应用,由于它的性能也不比其余级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)
这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它知足了隔离的简单定义:一个事务只能看见已经提交事务所作的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),由于同一事务的其余实例在该实例处理其间可能会有新的commit,因此同一select可能返回不一样结果。
Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到一样的数据行。不过理论上,这会致使另外一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另外一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎经过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
Serializable(可串行化)
这是最高的隔离级别,它经过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每一个读的数据行上加上共享锁。在这个级别,可能致使大量的超时现象和锁竞争。
这四种隔离级别采起不一样的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:
i. 脏读(Drity Read):某个事务已更新一份数据,另外一个事务在此时读取了同一份数据,因为某些缘由,前一个RollBack了操做,则后一个事务所读取的数据就会是不正确的。
ii. 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这多是两次查询过程当中间插入了一个事务更新的原有的数据。
iii. 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例若有一个事务查询了几列(Row)数据,而另外一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
(3)一致性处理:
A、开启事务。B、申请写权限,也就是给对象(表或记录)加锁。C、假如失败,则结束事务,过一会重试。D、假如成功,也就是给对象加锁成功,防止其余用户再用一样的方式打开。E、进行编辑操做。F、写入所进行的编辑结果。G、假如写入成功,则提交事务,完成操做。 H、假如写入失败,则回滚事务,取消提交。I、(G、H)两步操做已释放了锁定的对象,恢复到操做前的状态。
(4)基于事务的数据库引擎的选型:若是考虑到事务,推荐选用MySQL INNODB引擎;若是考虑速度,建议考虑MySQL MyISAM引擎,而且须要在代码层面作比较复杂的处理,如经过多线程、异步、非阻塞等方式对数据库进行清理,同时须要信号量、栏栅、数据库标志位等工具保证数据一致性。
四、海量数据处理
(1)数据库扩展:
①纵向扩展:基于业务的高度隔离性和数据的安全性,对业务和数据进行合理的切分,进行主-备机分离,主-主同步,主-从同步(对于MySQL数据库是单向异步同步机制),主-从热备等操做。
②横向扩展:对数据表进行横向切分,按必定的规则(hash取模分、user_id尾数、自定义算法等)对数据表进行横向切分。
关于数据库架构和扩展方面的文章请见:Mysql在大型网站的应用架构演变。
(2)分布式数据方案:
①提供分库规则和路由规则(RouteRule简称RR),将上面的说明中提到的三中切分规则直接内嵌入本系统,具体的嵌入方式在接下来的内容中进行详细的说明和论述;
②引入集群(Group)的概念,保证数据的高可用性;
③引入负载均衡策略(LoadBalancePolicy简称LB);
④引入集群节点可用性探测机制,对单点机器的可用性进行定时的侦测,以保证LB策略的正确实施,以确保系统的高度稳定性;
⑤引入读/写分离,提升数据的查询速度。
具体描述请参见博文:MySQL 海量数据的存储和访问解决方案。
(3)数据库切分策略介绍,请见博文:数据库Sharding的基本思想和切分策略。
(4)随着数据量随着业务的发展不断增大,传统的关系型数据库RDB已经没法知足须要,这时须要引入新的海量数据处理解决方案:Apache HBase。
一、Struts2
①工做原理
A、在Struts2框架中的处理大概分为如下几个步骤:
1)客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2)这个请求通过一系列的过滤器(Filter)(这些过滤器中有一个叫作ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其余框架的集成颇有帮助,例如:SiteMesh Plugin)
3)接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否须要调用某个Action
4)若是ActionMapper决定须要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5)ActionProxy经过Configuration Manager询问框架的配置文件,找到须要调用的Action类
6)ActionProxy建立一个ActionInvocation的实例。
7)ActionInvocation实例使用命名模式来调用,在调用Action的过程先后,涉及到相关拦截器(Intercepter)的调用。
8)一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果一般是(但不老是,也可 能是另外的一个Action链)一个须要被表示的JSP或者FreeMarker的模版。在表示的过程当中能够使用Struts2 框架中继承的标签。在这个过程当中须要涉及到ActionMapper。
②工做流程:
1)客户端在浏览器中输入一个url地址。
2)这个url请求经过http协议发送给tomcat。
3)tomcat根据url找到对应项目里面的web.xml文件。
4)在web.xml里面会发现有struts2的配置。
5)而后会找到struts2对应的struts.xml配置文件。
6)根据url解析struts.xml配置文件就会找到对应的class。
7)调用完class返回一个字String,根据struts.xml返回到对应的jsp。
二、spring原理
①IoC(Inversion of control): 控制反转,依赖注入
1)IoC:
概念:控制权由对象自己转向容器;由容器根据配置文件去建立实例并建立各个实例之间的依赖关系
2)依赖IoC容器负责管理bean,有两种,一种是BeanFactory,另外一种是ApplicationContext,可是ApplicationContext继承与BeanFactory。
核心:bean工厂;在Spring中,bean工厂建立的各个实例称做bean
②AOP(Aspect-Oriented Programming): 面向方面编程
1)代理的两种方式:
静态代理:
针对每一个具体类分别编写代理类;
针对一个接口编写一个代理类;
动态代理:
针对一个方面编写一个InvocationHandler,而后借用JDK反射包中的Proxy类为各类接口动态生成相应的代理类
2) AOP的主要原理:动态代理
实现:有两种:JDK Proxy和Cglib,Spring规定对于有接口的类用JDK Proxy,对于无接口和抽象类用Cglib,虽然Cglib都可以代理,可是Cglib复杂,效率低。可是Cglib有例外,就是代理的类中不能是final修饰的类或者类中有final方法。
三、Spring、Struts二、Servlet对比
①Servlet原理:Tomcat 的容器等级中,Context 容器是直接管理 Servlet 在容器中的包装类 Wrapper,因此 Context 容器如何运行将直接影响 Servlet 的工做方式。
A、Servlet生命周期详解
Servlet的生命周期能够分为四个阶段,即装载类及建立实例阶段、初始化阶段、服务阶段和实例销毁阶段。下面针对每一个阶段的编程任务及注意事项进行详细的说明。
B、Servlet建立过程
在默认状况下Servlet实例是在第一个请求到来的时候建立,之后复用。一旦Servlet实例被建立,Web服务器会自动调用init(ServletConfig config)方法来初始化该Servlet。其中方法参数config中包含了Servlet的配置信息,好比初始化参数,该对象由服务器建立。init方法在Servlet生命周期中只执行一次,并且该方法执行在单线程的环境下,所以开发者不用考虑线程安全的问题。
C、服务
一旦Servlet实例成功建立及初始化,该Servlet实例就能够被服务器用来服务于客户端的请求并生成响应。在服务阶段Web服务器会调用该实例的service(ServletRequest request,ServletResponse response)方法,request对象和response对象有服务器建立并传给Servlet实例。request对象封装了客户端发往服务器端的信息,response对象封装了服务器发往客户端的信息。
为了提升效率,Servlet规范要求一个Servlet实例必须可以同时服务于多个客户端请求,即service()方法运行在多线程的环境下,Servlet开发者必须保证该方法的线程安全性。
Serlvet接口只定义了一个服务方法就是service,而HttpServlet类实现了该方法而且要求调用下列的方法之一:
doGet:处理GET请求
doPost:处理POST请求
当发出客户端请求的时候,调用service 方法并传递一个请求和响应对象。Servlet首先判断该请求是GET 操做仍是POST 操做。而后它调用下面的一个方法:doGet 或 doPost。若是请求是GET就调用doGet方法,若是请求是POST就调用doPost方法。
②对比:Spring主要有IoC和AOP,Spring中IoC管理的bean为单例模式的,能够配置成原型模式。若是用Spring管理struts2的bean,必需要设置成原型模式,由于struts2封装来了servlet,隔离了servlet的特性,Action不一样于Spring,已是原型模式了。
四、memcached和redis区别
①Memcached出现于2003年,key支持250bytes,value支持1MB;redis出现于2009年,key和value都是支持512MB的。
持久化方面,memcached过时失效,redis能够缓存回收(6种回收机制),有存储,可算为NOSQL,有优化,支持190多种命令。
集群方面,memcached不支持集群,基于两次哈希,第一次哈希找到服务器节点,第二次哈希找到存储的值。
1)Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
2)Redis支持数据的备份,即master-slave模式的数据备份。
3)Redis支持数据的持久化,能够将内存中的数据保持在磁盘中,重启的时候能够再次加载进行使用。
Redis只会缓存全部的key的信息,若是Redis发现内存的使用量超过了某一个阀值,将触发swap的操做,Redis根据“swappability= age*log(size_in_memory)”计算出哪些key对应的value须要swap到磁盘。而后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis能够保持超过其机器自己内存大小的数据。固然,机器自己的内存必需要可以保持全部的key,毕竟这些数据是不会进行swap操做的。
②memcached、redis和mongoDB三者之间的对比:
1)性能
都比较高,性能对咱们来讲应该都不是瓶颈
整体来说,TPS(每秒事务处理量)方面redis和memcache差很少,要大于mongodb
2)操做的便利性
memcache数据结构单一
redis丰富一些,数据操做方面,redis更好一些,较少的网络IO次数
mongodb支持丰富的数据表达,索引,最相似关系型数据库,支持的查询语言很是丰富
3)内存空间的大小和数据量的大小
redis在2.0版本后增长了本身的VM特性,突破物理内存的限制;能够对key value设置过时时间(相似memcache)
memcache能够修改最大可用内存,采用LRU算法
mongoDB适合大数据量的存储,依赖操做系统VM作内存管理,吃内存也比较厉害,服务不要和别的服务在一块儿
4)可用性(单点问题)
对于单点问题,
redis,依赖客户端来实现分布式读写;主从复制时,每次从节点从新链接主节点都要依赖整个快照,无增量复制,因性能和效率问题,
因此单点问题比较复杂;不支持自动sharding,须要依赖程序设定一致hash 机制。
一种替代方案是,不用redis自己的复制机制,采用本身作主动复制(多份存储),或者改为增量复制的方式(须要本身实现),一致性问题和性能的权衡
Memcache自己没有数据冗余机制,也不必;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引发的抖动问题。
mongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制。
5)可靠性(持久化)
对于数据持久化和数据恢复,
redis支持(快照、AOF):依赖快照进行持久化,aof加强了可靠性的同时,对性能有所影响;memcache不支持,一般用在作缓存,提高性能;MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性。
6)数据一致性(事务支持)
Memcache 在并发场景下,用cas保证一致性。
redis事务支持比较弱,只能保证事务中的每一个操做连续执行。
mongoDB不支持事务
7)数据分析
mongoDB内置了数据分析的功能(mapreduce),其余不支持。
8)应用场景
redis:数据量较小的更性能操做和运算上。
memcache:用于在动态系统中减小数据库负载,提高性能;作缓存,提升性能(适合读多写少,对于数据量比较大,能够采用sharding)。
MongoDB:主要解决海量数据的访问效率问题。
五、设计一个缓存
A、过时时间
B、多态实现访问量
C、弱引用、软引用。
D、WeakHashMap的使用。
缓存技术的实现原理:LRU(Least Recently Used)缓存技术
能够使用两个标准的数据结构来实现,Map和Queue。由于须要支持多线程,须要使用实现了java.util.concurrent.*的Map和Queue。主要思路是使用一个Queue来维护FIFO和Map来对数据进行排序,当向缓存添加新的元素时,共有如下三种可能:
①若是该元素已经在Cache中存在(Map),咱们会从Queue中删除元素并将其添加到Queue的第一个位置;
②若是缓存已经没法知足新增新的元素,咱们会从Queue和Map中删除最后面的那个元素并把新元素添加进来;
③同时在Map和Queue中增长新的元素。
参考代码:
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; public class LRUCache<K, V> { // LRU 缓存的最大容量. private final int capacity; // 用来保持最近使用的元素的 Queue. private ConcurrentLinkedQueue<K> queue; private ConcurrentHashMap<K, V> map; /** * 初始化 LRU 缓存 * * @param capacity */ public LRUCache(final int capacity) { this.capacity = capacity; this.queue = new ConcurrentLinkedQueue<K>(); this.map = new ConcurrentHashMap<K, V>(capacity); } /** * 检查该元素释放在缓存中存在,若是不存在则返回 null * * @param key * @return */ public V get(final K key) { return map.get(key); } /** * 将元素添加到 LRU 缓存。若是 Key 已存在,则将其放到缓存的第一位置 * * @param key * @param value * @throws NullPointerException */ public synchronized void put(final K key, final V value) { if (key == null || value == null) { throw new NullPointerException(); } if (map.containsKey(key)) { queue.remove(key); } while (queue.size() >= capacity) { K expiredKey = queue.poll(); if (expiredKey != null) { map.remove(expiredKey); } } queue.add(key); map.put(key, value); } }
六、RPC
七、序列化
八、新技术
(1)Netty:
Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 能够确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty至关简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。 “快速”和“简单”并不意味着会让你的最终应用产生维护性或性能上的问题。Netty 是一个吸取了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各类二进制,文本协议,并通过至关精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
(2)MongoDB:
Mongo DB 是目前在IT行业很是流行的一种非关系型数据库(NoSql),其灵活的数据存储方式备受当前IT从业人员的青睐。Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB中 每一条记录都是一个Document对象。Mongo DB最大的优点在于全部的数据持久操做都无需开发人员手动编写SQL语句,直接调用方法就能够轻松的实现CRUD操做。
(3)Hadoop:
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。 用户能够在不了解分布式底层细节的状况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特色,而且设计用来部署在低廉的(low-cost)硬件上;并且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,能够以流的形式访问(streaming access)文件系统中的数据。 Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
(4)Solr:
Solr是一个高性能,采用Java5开发,SolrSolr基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,而且提供了一个完善的功能管理界面,是一款很是优秀的全文搜索引擎。
(5)ActiveMQ:
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个彻底支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已是好久的事情了,可是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
(6)Velocity:Velocity是一个基于java的模板引擎(template engine)。它容许任何人仅仅使用简单的模板语言(template language)来引用由java代码定义的对象。
(7)Openfire :Openfire 采用Java开发,开源的实时协做(RTC)服务器基于XMPP(Jabber)协议。Openfire安装和使用都很是简单,并利用Web进行管理。单台服务器可支持上万并发用户。
(8)Node.js:
Node.js是一个基于Chrome JavaScript运行时创建的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,很是适合在分布式设备上运行的数据密集型的实时应用。 V8引擎执行Javascript的速度很是快,性能很是好。 Node是一个Javascript运行环境(runtime)。实际上它是对Google V8引擎进行了封装。V8引 擎执行Javascript的速度很是快,性能很是好。Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好。
(9)Ruby on Rails:
Ruby on Rails 是一个能够使你开发,部署,维护 web 应用程序变得简单的框架。ruby on rails使用的实时映射技术和元编程技术,免去了开发人员在开发过程当中编写大量样板文件代码的烦恼。在少数须要使用样板文件代码的时候,开发人员能够经过ruby on rails内建的生成器脚本实时建立,而再也不是经过手工编写。rails的这个特色能够使开发人员更专一于系统的逻辑结构,而没必要为一些琐碎的细节所烦扰。
(10)Docker:
Docker 是一个开源的应用容器引擎,让开发者能够打包他们的应用以及依赖包到一个可移植的容器中,而后发布到任何流行的 Linux 机器上,也能够实现虚拟化。容器是彻底使用沙箱机制,相互之间不会有任何接口(相似 iPhone 的 app)。几乎没有性能开销,能够很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包括系统。
(11)ElasticSearch:
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并做为Apache许可条款下的开放源码发布,是第二最流行的企业搜索引擎。设计用于云计算中,可以达到实时搜索,稳定,可靠,快速,安装使用方便。
(12)RESTful WebService:
RESTful WebService是比基于SOAP消息的WebService简单的多的一种轻量级Web服务,RESTful WebService是没有状态的,发布和调用都很是的轻松容易。
(13)Hessian:
Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,由于采用的是二进制协议,因此它很适合于发送二进制数据。
(14)WebLogic:
WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中。
(15)OSGi:
OSGi(Open Service Gateway Initiative)技术是面向Java的动态模型系统。OSGi服务平台向Java提供服务,这些服务使Java成为软件集成和软件开发的首选环境。Java提供在多个平台支持产品的可移植性。OSGi技术提供容许应用程序使用精炼、可重用和可协做的组件构建的标准化原语。这些组件可以组装进一个应用和部署中。