J2EE复习

2014年10月14日

JAVA知识体系

JAVA 学习路线图

1.基础知识   

ArrayList与LinkedList区别:  

ArrayList数据结构是数组
LinkedList底层数据结构是链表(双向链表)
TreeMap是红黑树实现的 HashMap和HashTable的区别:   两者都实现了Map接口,是将唯一键映射到特定的值上,主要区别在于:   

1.HashMap没有排序,允许一个NULL键和多个NULL值,而Hashtable不允许
2.HashMap把HashTable的contains方法去掉了,改成containsvalue和containskey,因为contains方法容易让人引起误解;
3.Hashtable继承自Dictionary类,HashMap是Java 1.2引进的Map接口的实现; 
4.Hashtable的方法是synchronized的,而HashMap不是,在多个县城访问HashTable时,不需要自己为
它的方法实现同步,而HashMap就必须为之提供同步.HashTable和HashMap采用的hash/rehash算法一致,所以性能不会有很大的差异.

HashMap和HashTable的底层实现都是数组+链表结构实现的,当向容器添加元素的时候,HashMap会判断当前容器的元素个数,如果大于等于阈值--即当前数组的长度
乘以加载因子的值的时候,就要自动扩容  

扩容的算法:扩容(resize)就是重新计算容量,想HashMap对象里不停的添加元素,而HashMap对象内部的数组无法装载更多的元素时,对象就需要扩大数组的长度,以便能装入更多的元素.当然Java里的数组是无法
自动扩容的,方法是使用一个新的数组代替已有的容量小得数组.

ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,

它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,

Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上比ArrayList查,因此已经是Java中的
遗留容器。

LinkedList使用双向链表实现存储,非线程安全

collections中的synchronizedList方法将其转换成线程安全的容器后再使用,装饰模式,增强实现。

JVM的两个内存:      运行时数据区 程序计数器
Java虚拟机栈
本地方法栈
Java堆 方法区
运行时常量池
本机直接内存

栈内存:在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配.当在一段代码块定义一个
变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的
内存空间,该内存空间可以立即被另作他用.

堆内存:堆内存用来存放由new创建的对象和数组.在堆中分配的内存,由Java虚拟机的自动垃圾
回收器来管理.

除了程序计数器外,虚拟机内存的其他几个运行时区域都会发生OutofMemoryError异常的可能,本节将通过若干实例来验证异常发生的场景
OOM: 
    Java堆溢出
    虚拟机栈和本地方法栈溢出
    运行时常量池溢出
    方法区溢出
    本机直接内存溢出 Java自动内存管理:
  
内存模型
    共享内存:
        堆内存区
        方法区
    线程独占内存:
        程序计数器
        虚拟机栈
        本地方法栈
垃圾收集:
    对象引用强度:
        强引用  
        软引用  
        弱引用  
        虚引用  
    对象已死:
        引用计数法
            优点:简单,直接,不需要暂停整个应用
            缺点:1.需要编译器的配合,编译器要生成特殊的指令来进行引用计数的操作,比如每次将对象赋值给新的引用,或者对象的引用超出了作用域等。
            2.不能处理循环引用的问题
        根搜索算法
垃圾收集器:
    Hostspot JVM收集器
    Serial(串行GC)收集器
    ParNew(并行GC)收集器
    Parallel Scavenge(并行回收GC)收集器
    Serial Old(串行GC)收集器
    Parallel Old(并行GC)收集器
    CMS(并发GC)收集器
    G1收集器

JAVA异常整体分类:

1)Java异常结构中定义有Throwable类,Exception和Error为其子类
2)其中Exception表示由于网络故障,文件损坏,设备错误,用户输入非法情况导致的异常.
3)Error标识Java运行时环境出现的错误,例如:JAVA内存耗尽

Java的线程池:

  1)newCachedThreadPool

  2)newFixedThreadPool

  3)newScheduledThreadPool

  4)newSingleThreadExecutor volatile和synchronized的区别:

Java中,为了保证多线程读写数据时保证数据的一致性,可以采用两种方式:

1)使用synchronized关键字
2)使用volatile关键字:用一句话概括volatile,他能够使变量在值发生改变时能
  尽快地让其他线程知道
3)volatile本质实在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
4)volatile仅能使用在变量级别,synchronized则可以使用在变量,方法
5)volatile仅能实现变量的修改可见性,而synchronized则可以保证变量的修改可见性和原子性
6)volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.

线程局部变量:

线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享.Java 提供ThreadLocal类来支持线程局部变量,是一种实现县城安全的方式.但是在管理环境下(如Web服务器)使用 线程局部变量的时候要小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期药厂.任何线程局部变量一旦 在工作完成后没有释放,Java应用就存在内存泄漏的风险.

Java中Sleep方法和wait方法的区别:

虽然两者都是用来暂停当前运行的线程,但是sleep实际上只是短暂停顿,因为它不会释放锁,而wait意味着
条件等待,这就是为什么该方法要释放锁,因为只有这样,其他等待的线程才能在满足条件时获取到该锁.

首先equals方法必须满足自反性(x.equals(x)必须返回true)、对称性(x.equals(y)返回true时, y.equals(x)也必须返回true)、传递性(x.equals(y)和y.equals(z)都返回true时, x.equals(z)也必须返回true)和一致性(当x和y引用的对象信息没有被修改时, 多次调用x.equals(y)应该得到同样的返回值), 而且对于任何非null值的引用x,x.equals(null)必须返回false。 实现高质量的equals方法的诀窍包括:

1. 使用==操作符检查"参数是否为这个对象的引用";
2. 使用instanceof操作符检查"参数是否为正确的类型";
3. 对于类中的关键属性,检查参数传入对象的属性是否与之相匹配;
4. 编写完equals方法后,问自己它是否满足对称性、传递性、一致性;
5. 重写equals时总是要重写hashCode;
6. 不要将equals方法参数中的Object对象替换为其他的类型,在重写时不要忘掉@Override注解。

垃圾收集器: 吞吐量收集器使用并行版本的新生代垃圾收集器,他用于中等规模和大规模数据的应用程序.而串行收集器对 大多数的小应用(在现代处理器上需要大概100M左右的内存)就足够了.  

同步容器类:使用了synchronized:

1.vector
2.HashTable 并发容器

3.ConcurrentHashMap
4.CopyOnWriteArrayList:写时复制
5.CopyOnWriteArraySet:写时复制 Queue:

6.ConcurrentLinkedQueue:使用非阻塞的方式实现的基于连接节点的无界的线程安全队列,性能非常好。
7.ArrayBlockingQueue:基于数组的有界阻塞队列
8.LinkedBlockingQueue:基于链表的有界阻塞队列
9.PriorityBlockingQueue:支持优先级的无界阻塞队列,即该阻塞队列中的元素
  可自动排序。默认情况下,元素采取自然升序排列
10.DelayQueue:一种延时获取元素的无界阻塞队列
11.SynchronousQueue:不存储元素的阻塞队列, Deque:

12.ArrayDeque:基于数组的双向非阻塞队列
13.LinkedBlockingDeque:基于链表的双向阻塞队列 Sorted容器:

14.ConcurrentSkipListMap:是TreeMap的线程安全版本
15.ConcurrentSkipListSet:是TreeSet的线程安全版本

String学习  

String类是final类,不可以被继承。  

string和StringBuilder、StringBuffer的区别  

stringbuilder是java5中引入的,没有被synchronized修饰,单线程环境使用  

Java中的Char类型可以存储一个中文汉字,Java使用的编码是Unicode,

Thread类的方法:start() run() getPriority()

数据结构与算法: 二叉树: 确定一棵二叉数的是给定后序和中序或者给定先序和中序

使用分治法的前提条件:

1.该问题具有最有子结构性质
2.原问题和子问题求解方法相同
3.子问题之间不包含公共的子问题

实现多线程程序主要有两种方式:Thread类,Runnable接口、Java5后新增Callable接口

接口,抽象类,类,引用区别 语法层面上抽象类和接口的区别:

1.抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract方法;
2.抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3.接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4.一个类只能继承一个抽象类,而一个类却可以实现多个接口
5.实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。抽象类中可以有非抽象方法。接口中则不能有实现方法。
6.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以在子类中重新赋值。
7.接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的。
8.abstract关键字只能修饰类和方法,不能修饰字段
9.抽象类不能被实例化(无法使用new关键字创建对象实例),只能被继承
10.抽象类可以包含属性,方法,构造方法,初始化块,内部类,枚举类,和普通类一样
11.含有抽象方法的类必须定义成抽象类.

抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。
一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,
否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,
可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。
抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。
抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。
有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。

final与abstract是反义词

使用parseXXX(String)或ValueOf刻印返回基本数据类型

构造函数的执行顺序继承情况下?

2.编程格式

设计模式: 结构性模式:    适配器模式    桥接模式    组合模式    装饰模式

3.面向对象

面向对象的特征:

抽象
继承
封装
多态性:方法重载(overload)实现的是编译时的多态性(前绑定),方法重写(override)实现的是运行时的多态性 运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:

1方法重写(子类继承父类并重写父类中已有的或抽象的方法)
2对象造型(用父类型引用引用子类型对象,这样同样的应用调用同样的方法就会根据子类对象的不同而表现    出不同的行为)

4.常用类

5.集合与IO

Set集合从原理上如何保证不重复

1)在往set中添加元素时,如果指定元素不存在,则添加成功.
2)当向HashSet中添加元素的时候,首先计算元素的hashcode值,然后用这个(元素的hashcode)%(HashMap集合的大小)+1计算出这个元素的存储位置,如果这个位置为空,就将元素添加进去.如果不为空,则用equals方法比较元素是否相等

6.J2EE

J2EE的N层体系结构
spring的注入方式:

1.属性注入(setter方法注入)
2.构造器注入
3.工厂方法注入
接口注入方式是不支持的

Spring中Bean的作用域有singleton和prototype,singleton表示Bean以单例的方式存在;prototype表示每次 从容器中调用Bean时,都会返回一个新的实例。 Spring中自动装配的方式有:

no:不进行自动装配,手动设置bean的依赖关系
byName:根据Bean的名字进行自动装配
byType:根据Bean的类型进行自动装配
constuctor:类似于byType,不过是应用于构造器的参数,如果正好有一个Bean与构造器的参数类型相同则可以自动装配,否则会导致错误。
autodetect:如果有默认的构造器,则通过constructor的方式进行自动装配,否在使用byType的方式进行自动装配。

Spring配置文件中新增如下配置:

<context:component-scan base-package="org.example"/>就可以使用注解来配置Bean

Web项目中配置IOC容器:

context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>
    org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

Web项目中配置SpringMVC:

<web-app>
<servlet>
    <servlet-name>example</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>example</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>

</web-app>

选择Spring的原因:

- 非侵入式:支持基于POJO的编程模式,不强制性的要求实现Spring框架中的接口或继承Spring框架中的类。
- IoC容器:IoC容器帮助应用程序管理对象以及对象之间的依赖关系,对象之间的依赖关系如果发生了改变只需要修改配置文件而不是修改代码,因为代码的修改可能意味着项目的重新构建和完整的回归测试。有了IoC容器,程序员再也不需要自己编写工厂、单例,这一点特别符合Spring的精神"不要重复的发明轮子"。
- AOP(面向切面编程):将所有的横切关注功能封装到切面(aspect)中,通过配置的方式将横切关注功能动态添加到目标代码上,进一步实现了业务逻辑和系统服务之间的分离。另一方面,有了AOP程序员可以省去很多自己写代理类的工作。
- MVC:Spring的MVC框架是非常优秀的,从各个方面都可以甩Struts 2几条街,为Web表示层提供了更好的解决方案。
- 事务管理:Spring以宽广的胸怀接纳多种持久层技术,并且为其提供了声明式的事务管理,在不需要任何一行代码的情况下就能够完成事务管理。
- 其他:选择Spring框架的原因还远不止于此,Spring为Java企业级开发提供了一站式选择,你可以在需要的时候使用它的部分和全部,更重要的是,你甚至可以在感觉不到Spring存在的情况下,在你的项目中使用Spring提供的各种优秀的功能。 Spring三大核心组件:

1.Bean
2.context
3.core Mybatis中#和$区别:

1.${}是properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文件替换,比如${driver}会被静态替换为com.mysql.jdbc.driver
2.#{}是sql的参数占位符,mybatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatements的参数设置方法,按序给sql的?号占位符设置参数值,比如ps.setInt(0,parameterValue),#{item.name}的取值方式为
使用反射从参数对象中获取item对象的name属性之,相当与param.getItem().getName();
3.#将传入的数据都当成一个字符串,会对传入的数据自动加上引号,$将传入的数据直接显示生成在SQL中。
注意:使用$占位符可能会导致SQL注射攻击,能用#的地方就不要使用$,写order by子句的时候应该用$而不是# servlet执行流程:

客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相应的servlet,并将
request,response对象传递给找到的servlet,servlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理玩业务逻辑后
会将信息放入到response并响应到客户端 SpringMVC的执行流程:

SpringMVC是由dispatchservlet为核心的分层控制框架.首先客户端发出一个请求web服务器解析
请求url并去匹配dispatchservlet的映射url,如果匹配上就将这个请求放入到dispatchservlet,dispatchservlet根据mapping
映射配置去寻找相应的handle,然后把处理权交给找到的handle,handle封装了处理业务逻辑的代码,当handle处理完成后会
返回一个逻辑试图modelandview给dispatchservlet,此时的modelandview是
一个逻辑试图不是一个正式试图,所以dispatchservlet会通过viewresource试图资源去解析modelandview,然后
将解析后的参数放到view中返回客户端并展现.

Servlet的生命周期可以分为初始阶段,运行阶段,销毁阶段

初始阶段:
加载Servlet类以及.class对应的数据
创建ServletConfig对象
创建Servlet对象

Hibernate中DetachedCriteria类和Criteria的用法基本一致,但Criteria是由Session的CreateCriteria()方法创建的,, 也就意味着离开创建它的Session,Criteria就无法使用了。DetachedCriteria不需要Session就可以创建(使用DEtachedCriteria.forClass() 方法创建 ),所以通常也称其为离线的Criteria,在需要进行查询操作的时候再和Session绑定(调用其 getExecutableCriteria(Session)方法),这也就意味着DetachedCriteria可以在需要的时候和不同的Session绑定。

7.框架

8.工具

领域模型:领域内的概念类或显示世界中对象的可视化表示,又称为概念模型或分析对象模型,专注于分析问题领域本身, 发掘重要的业务领域概念,并建立业务领域概念之间的关系。 贫血模型:使用的领域对象中只有setter和getter方法(POJO),所有的业务逻辑都不包含在领域对象中二十放在业务逻辑层 失血模型:领域对象完全没有业务逻辑 充血模型:业务

常用的对称加密算法有:DES,3DES,RC2,RC4,AES 常用的非对称加密算法有:RSA,DSA,ECC 使用的单项散列函数的加密算法:MD5,SHA

软件工程: UML定义的关系主要有六中:依赖,类属,关联,实现,聚合和组合 组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也成为强聚合; 它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束; 比如你和你的大脑;表现在代码曾买你,和关联关系是一致的,只能从语义级别来区分.

TCP三次握手: ACK和SYN放在一个报文理发送给客户端,为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误 TCP四次挥手: 全双工模式下,关闭连接时,收到对方的FIN报文时,仅仅表示对方不在发送数据但是还能接受数据,发送ACK给回应,己方也 未必数据都发送给对方了,所以己方可以立即close,再次发送一个FIN报文,表示进入到LAST_ACK状态,收到对方的ACK保温室,进入CLOSED状态。

参考  

http://wesmckinney.com/blog/announcing-ursalabs/  

https://blog.csdn.net/jackfrued/article/details/44921941  

https://zhuanlan.zhihu.com/p/21551758  

https://zhuanlan.zhihu.com/p/29222077  

https://www.cnblogs.com/pureEve/p/6546280.html  

J2EE  

Image-r3

APDPlat


期待您的分享与讨论: