补漏知识点
前言:补充了数据结构和算法、设计模式、spring MVC等内容并对很多知识点进行了深入的剖析,例如hashCode方法的设计、垃圾收集、并发编程、数据库事务等。
1
数据类型:Java中的基本数据类型只有8个:byte(8)、short(16)、int(32)、long(64)、float(32)、double(64)、
char(16,2字节,可放一个中文汉字)、boolean(64);除了基本类型(primitive type)和枚举类型
(enumeration type),剩下的都是引用类型(reference type)。
注:eg1: float f=3.4,错误。双精度转单精度,下转型,需强转。float f =(float)3.4; 或者写成float f =3.4F;
eg2: short s1 = 1; s1 = s1 + 1。错误,理由同上。short s1 = 1; s1 += 1。正确,因为s1+= 1;
相当于s1 = (short)(s1 + 1),其中有隐含的强制类型转换。
eg3: long w=12345678901。错误。超出了int类型的取值范围。
eg4: Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);
System.out.println(f3 == f4);
注意上面的变量都是Integer引用,查阅Integer的内部类IntegerCache可知,如果整型字面量的值在-128
到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中
f1==f2的结果是true,而f3==f4的结果是false。
2
goto和const都是保留字
3
Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后
进行下取整。
4
用最有效率的方法计算2乘以8:2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)
5
(x.equals(y) == true),但却可有不同的hash code? 错误。如果两个对象相同,hashcode值一定要相同。
6
String 类是final类,不可以被继承。所有的包装类都是final修饰的类,都不能被继承。
7
Java中非静态内部类对象的创建要依赖其外部类对象(this.new 内部类 ; new 外部类.new 内部类).
8
Java 中会存在内存泄漏吗?
理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题。开发中,可能会存在无用但可达的对象,这些
对象不能被GC回收,因此也会导致内存泄露的发生。例如hibernate的Session(一级缓存)中的对象属于持久
态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)
或清空(flush)一级缓存就可能导致内存泄露。
9
EJB:包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI(远程方法调用,详解:http://blog.csdn.net/a19881029/article/details/946566)、JAT(Java基础框架)等技术实现。
SessionBean和EntityBean的区别:对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上
运行的业务逻辑,可细分为Stateful Session Bean 与 Stateless Session Bean ; EntityBean是一种持久性对象,
它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。
StatefulBean和StatelessBean的区别:Stateful Session Bean 可以记录呼叫者的状态,每个使用者对应一个
实体,消耗 J2EE Server 较多的内存,可以维持使用者的状态;Stateless Session Bean不负责记录使用者状
态,可能数个使用者对应一个 Bean 的 Instance 在执行。
EJB与JAVA BEAN的区别:Java Bean 是可复用的组件,被容器所创建,Java Bean应具有一个无参的
构造器,还要实现Serializable接口用于实现Bean的持久性,不能被跨进程访问的;Enterprise Java Bean相当
于分布式组件。基于Java的远程方法调用(RMI)技术的,EJB容器是EJB组件的代理, EJB组件由容器所
创建和管理。客户通过容器来访问真正的EJB组件。
10
HashMap和Hashtable的区别:两者皆采用哈希算法。HashMap允许空键值,非线程安全。HashMap把
Hashtable的contains方法去掉了,改成containsvalue和containsKey;Hashtable不允许空键值,线程安全。
11
sleep() 和 wait() 有什么区别:sleep()是Thread的方法,导致线程暂停执行指定时间,给执行机会给其他线程,
监控状态依然保持。调用sleep不会释放对象锁。
wait()是Object的方法,线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法
(或notifyAll)后本线程才进入对象锁定池,准备获得对象锁进入运行状态。
12
Heap [堆]和stack [栈]有什么区别:堆是栈的一个组成元素。栈是一种线形集合,其添加和删除元素的操作应
在同一段完成。栈按照后进先出的方式进行处理。
13.
forward 和redirect的区别:forward是服务器请求资源,服务器直接访问目标地址的URL。浏览器不知道发送
内容从哪来,地址栏不变 ;
redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址。地址栏改变。
14
JSP中动态INCLUDE与静态INCLUDE的区别:动态INCLUDE用jsp:include动作实现 它总是会检查所含文件中
的变化,适合用于包含动态页面,并且可以带参数;
静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面
15
什么时候用assert (断言):常用的调试方式。对程序的一条语句进行检查,保证其为true。若为false,说明程序
处于不正确状态,系统将给出警告或退出。assertion检查通常在开发和测试时开启。为了提高性能, 在软件
发布后,assertion检查通常是关闭的。
16
GC是什么? 为什么要有GC? GC可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言
没有提供释放已分配内存的显示操作方法。对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。
调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。
17
数据连接池的工作机制:J2EE 服务器启动时会建立一定数量的连接置于连接池中,需要时直接从连接池获取,
使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销。浪费了空间存储连接,
但节省了创建和释放连接的时间
为什么需要连接池: 由于创建连接和释放连接都有很大的开销(尤其是数据库服务器不在本地时,每次建立
连接都需要进行TCP的三次握手,释放连接需要进行TCP四次握手,造成的开销是不可忽视的)
18
SpringMVC执行原理:
1.用户向前端控制器(DispatherServlet)发起请求
2.前端控制器(DispatherServlet)解析URL,请求处理映射器(HandlerMapping)。
3.处理映射器(HandlerMapping)返回Handler配置的所有相关对象。
4.前端控制器(DispatherServlet)根据获得的Handler,选择一个合适的HandlerAdapter。
(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)。
5.开始执行Handler(Controller),业务逻辑处理。
6.Handler处理完业务逻辑,返回ModelAndView对象给前端控制器(DispatherServlet)。
7.视图解析器(ViewResolver)返回真正的视图对象(View),前端控制器根据模型数据和视图对象,进行
视图渲染。
8.最后将渲染的试图以(html/json/xml)的形式响应用户。
19
Struts2执行原理:
1.客户端初始化一个指向Servlet容器的请求(HttpServletRequest请求)
2.请求经过一系列过滤器(最先执行ActionContextCleanUp、最后执行FilterDispatcher)
3.FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServlet Request)请求,如果
ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy。
4.ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类。
5.ActionProxy创建一个ActionInvocation实例。ActionInvocation会根据配置加载相关的拦截器(Interceptor),并
通过代理模式调用Action。
6.Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result。
20
日期和时间:
1.获得年月日、小时分钟秒
Calendar cal = Calendar.getInstance();
System.out.println(cal.get(Calendar.YEAR));
System.out.println(cal.get(Calendar.MONTH)); // 0 - 11
System.out.println(cal.get(Calendar.DATE));
System.out.println(cal.get(Calendar.HOUR_OF_DAY));
System.out.println(cal.get(Calendar.MINUTE));
System.out.println(cal.get(Calendar.SECOND));
2.获得该毫秒数
一下三种方式均可获得毫秒数 :
Calendar.getInstance().getTimeInMillis();
System.currentTimeMillis();
Clock.systemDefaultZone().millis();
3.打印昨天的当前时刻
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
System.out.println(cal.getTime());
21
递归排序 及 实现字符串的反转:
分治法排序(二分法排序):
static void quick_sort(int s[], int l, int r){
if (l < r){
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j){
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
字符串反转(反转的字符串不能包含特殊字符):
public static String result(String originStr){
for (int i = 0; i < originStr.length()-1; i++) {
originStr=reverse(originStr.substring(1)) + originStr.charAt(0);
}
return originStr;
}
22
怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
String s1 = "你好";
String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");
23
如何实现对象的克隆?
有两种方式: 1)实现Cloneable接口,并重写Object类中的clone()函数;
2) 实现Serializable接口,通过对象序列化和反序列化事实现深度克隆。代码如下:
public static <T> T clone(T obj) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
return (T) ois.readObject();
// 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
// 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
}
24 对ajax的理解:Ajax为异步请求,即局部刷新技术。不需要点击就可以触发事件,可以大量发送ajax请求,
提高前后端交互效率
25
什么是进程,什么是线程?为什么需要多线程编程?
进程: 具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的
一个独立单位;
线程: 进程的一个实体,是CPU调度和分 派的基本单位,是比进程更小的能独立运行的基本单位。
多线程优缺点:
1.线程的划分尺度小于进程,这使得多线程程序的并发性高;
2.进程在执行时通常拥有独立的内存单元,而线程之间可以共享内存。
3.高性能和用户体验
4.多线程的程序对于其他程序是不友好的,因为它占用了更多的CPU资源
多线程:a)一个进程是一个独立的运行环境,线程是进程的最小单位
b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会
把资源让给其他的线程。
c)用户线程:开发程序是创建的线程;守护线程:系统线程,如JVM虚拟中的GC
e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的
地方加锁和避免无限等待
synchronized 和java.util.concurrent.locks.Lock的异同:
相同点:Lock 能完成synchronized所实现的所有功能
不同点:Lock有更精确的线程语义和更好的性能,且不强制性的要求一定要获得锁。
synchronized会自动释放锁;Lock需要手动释放,并且最好在finally 块中释放(这是释放外部资源的
最好的地方)。
26
单例模式:
饿汉式单例
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance(){ return instance; }
}
懒汉式单例
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static synchronized Singleton getInstance(){
if (instance == null)
instance = new Singleton();
return instance;
}
}
27
Http的通信机制: 在1.1版本后一次连接中,可处理多个请求,并且多个请求可以重叠进行,不需要等待一个
请求结束后再发送下一个请求。
HTTP连接是一种“短连接”。在请求时需要先建立连接,客户端向服务器发出请求后,服务器端才能回复数据。
若服务器端与客户端建立的是Socket连接,则服务器可以直接将数据传送给客户端;
若建立的是Http连接,服务器需要等客户端发送一次请求后才能将数据传回给客户端。
28
Socket(套接字)的通信机制:Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,是网络
通信过程中端点的抽象表示。
网络通信必须包含五种信息:连接使用的协议、本地主机IP地址、本地进程的协议端口、远地主机的IP地址、
远地进程的协议端口。
建立Socket连接至少需要一对套接字,分别运行于客户端(ClientSocket)、服务器端(ServerSocket)
套接字之间连接过程分三步:服务器监听、客户端请求、连接确认
29
Hibernate核心: ROM对象关系映射机制。将表之间的操作映射为对象之间的操作。即从数据库中提取的信息会
自动按照你设置的映射要求封装成特定的对象。使得对对象的修改对应数据行的修改。
Hibernate的延迟加载机制:使用虚拟基代理机制实现延迟加载,在数据使用是加载出来。返回的是实体对象的代理。
用户调用getter()s时,就会去数据库加载数据。
Hibernate中Session的load和get方法的区别:
对比条件 get() load()
没有找到符合条件的数据时 返回null 抛出异常
返回的数据 实体类对象 实体类对象的代理
Hibernate 3之前 只在一级缓存中进行数据查找。如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取
Hibernate 3及后续版本 不再是对二级缓存只写不读,也可访问二级缓存
Hibernate优化策略:制定合理的缓存策略及Session管理机制、尽量使用延迟加载、
使用基于version的乐观锁代替悲观锁、开启hibernate.show_sql选项查看生成的SQL,完成时关闭。
乐观锁:在不锁定表的情况下,利用业务的控制来解决并发问题。即保证数据的可读性,又保证保存数据的排他性,
保证性能的同时解决了并发带来的脏读数据问题。
30
数据库优化策略:
1)选择存储范围较小的字段,尽可能的设为notnull.
2) 使用关联查询(eg:left join on)代替子查询
3)使用union联合查询时,手动创建临时表
4) 开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性
5) 使用外键保证数据的关联性
6)使用索引索引是提高数据库性能的常用方法。对于max,min,order by查询时,效果更明显
7)sql优化,简练
31
使用流实现文件拷贝:代码如下,两种方案供您参考。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public final class MyUtil {
private MyUtil() {}
public static void fileCopy(String source, String target) throws IOException {
try (InputStream in = new FileInputStream(source)) {
try (OutputStream out = new FileOutputStream(target)) {
byte[] buffer = new byte[4096];
int bytesToRead;
while((bytesToRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
}
}
}
public static void fileCopyNIO(String source, String target) throws IOException {
try (FileInputStream in = new FileInputStream(source)) {
try (FileOutputStream out = new FileOutputStream(target)) {
FileChannel inChannel = in.getChannel();
FileChannel outChannel = out.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(4096);
while(inChannel.read(buffer) != -1) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
}
}
}
32
Webservice与RPC的区别:
RPC: 1)RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数
或方法(可以统称为服务)并得到返回的结果。
2)RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
3)RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
4)RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)
WebService: http传输信道、XML的数据格式、SOAP封装格式、WSDL的描述方式、
UDDI,是一种目录服务,企业可以使用它对WebService进行注册和搜索
RMI与RPC 的区别:
1)RPC 不支持对象,采用http协议
2)RMI支持传输对象,采用tcp/ip协议
3)RMI只限于Java语言,RPC跨语言
Webservice与RMI:
RMI是在tcp协议上传递可序列化的java对象,只能用在java虚拟机上,绑定语言,客户端和服务端都必须是java
webservice没有这个限制,webservice是在http协议上传递xml文本文件,与语言和平台无关
33
从一张有500万数据的表中,的第400万条数据,取后面10条数据进行分页:
可以先倒叙取前100万条,再倒叙取前十条数据。
Select (Select * from 表名 where 条件 order by 字段 desc limit 0,1000000) from 表名 where 条件 order by 字段 desc limit 0,10;
34
MySQL 的基本数据类型:
整形:TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)、BIGINT
浮点型与定点数据类型:FLOAT、DOUBLE、DECIMAL
日期时间:DATETIME、DATE、TIMESTAMP、TIME、YEAR
字符串类型:CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM、SET
35
HashMap的初始长度为16,长度必须是 2的幂
因为: index = HashCode(Key) & (length - 1), 如果 length是 2的 幂的话,则 length - 1就是 全是 1的二进制数,比如
16 - 1 = 1111,这样相当于是 坐落在长度为 length的hashMap上的位置只和 HashCode的后四位有关,这只要给出的
HashCode算法本身分布均匀,算出的index就是分布均匀的。。
36
SpringMvc的核心入口类:DispatchServlet;
Struts1的核心入口类:ActionServlet;
Struts2的核心入口类:StrutsPrepareAndExecuteFilter
---------------------
作者:Carneybott
来源:CSDN
原文:https://blog.csdn.net/Carneybott/article/details/79507210
版权声明:本文为博主原创文章,转载请附上博文链接!