1,方法覆盖是说子类重新定义父类的方法。方法覆盖必须有相同的方法名,参数列表和返回值类型。
2,servlet在多线程下其本身并不是线程安全的。如果在类中定义成员变量,而在service中,根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。
最好的方法是定义在局部变量中,由于方法中的局部变量是在栈中,彼此拥有独立的空间,不会互相干扰,因此才线程安全。
3,ServerSocket(int port);
4,实例代码块在执行构造方法之前执行。所以优先级高于构造方法。
5,类中声明的变量有默认初始值;方法中声明的变量没有默认初始值,必须在定义的时候初始化,否则在访问该变量的时候会出错。
6,局部变量,没有像成员变量那样加载的时候会有初始化赋值,所以要使用局部变量时,一定要显示的给它赋值,也就是定义的时候给它赋值
7,\D表示非数字(大写表示非)
8,java调试器jdb.exe
9, final修饰变量的时候会把它变成常量(不会改变的值)
10,equals默认比较的是地址,因为最初这个方法是定义在object上的,也就是比较地址的。
11,String是final类型,每次声明的都是不可改变的对象。所以每次操作都会产生新的String对象,然后将指针指向新的String对象。
StringBuffer,StringBuilder都是在原有的对象进行操作,所以如果需要经常改变字符串的内容,则采用这两者。
StringBuffer是线程安全的,StringBuilder是线程不安全的,StringBuilder性能更高,所以优先使用StringBuilder
但是在实际开发的过程中,安全方面也是很重要的,为什么要优先使用StringBuilder?多个线程访问同一个资源,才会造成安全问题,如果在每一线程都创建一个StringBuilder对象,那么就不会有多个线程访问一个资源。
12,抽象类:方法可以是抽象的,也可以是非抽象的,有构造方法
接口:方法都是抽象的,属性都是常量,默认使用public static final修饰
jdk1.8之后:接口里面可以有实现的方法,注意要在方法的声明上加上default或者static
13,Integer a = 10;
int b = 10;
system.out.println(a == b); true
因为Integer与int进行比较的时候会发生自动拆箱,只进行数值的比较。
14,ArrayList,数组,连续一块内存空间
LinkedList,双向链表,不是连续的内存空间
ArrayList,查找快,因为是连续的内存空间,方便寻址,但是删除,插入慢,因为要发生数据的迁移
LinkedList,查找慢,因为需要通过指针一个个寻址,但是删除,插入快,因为只改变前后节点的指针指向即可。
ArrayList是如何进行扩容的:1,创建一个新数组,新数组的长度是原数组的1.5倍(通过位运算),2,将原数组的数据再迁移到新数组里。
遍历LinkedList必须使用iterator不能使用for循环,因为每次for循环体内通过get(i) 取得某一元素都需要对list重新进行遍历,性能消耗极大。
另外不要试图使用indexOf等返回元素索引,并利用其进行遍历,使用indexOf对list进行遍历,当结果为空的时候会遍历整个链表。
15,HashSet底层采用的是HashMap来实现存储,其值作为HashMap的key
public boolean add(E e){
return map.put(e,PRESENT)==null;
}
为什么采用hash算法?采用hash算法,通过计算存储对象的hashcode,然后再跟数组长度-1做位运算,得到我们要存储在数组的那个下标下,如果此时计算的位置没有其他元素,直接存储,不用比较。此处我们只用到hashcode,但是随着元素的不断增加,就可能出现哈希冲突,不同的对象计算出来的hash值是相同的,这个时候我们就需要比较,如果equals相同,则不插入,不相同,则形成链表。
16 hashtable线程安全(内置了 synchronized关键字)
HashMap线程不安全,但是效率高
concurrentHashMap,既兼顾了安全方面,又兼顾了性能方面,(内置分段锁机制,将锁的粒度变小)。
17,当进行文件上传的时候,用字节流进行传输;将表中的数据导入到数据库的时候,用字符流进行传输的。
18,Error(JVM的错误):栈内存异常 StackOverError
递归(1,规律,2,出口)
堆内存异常
runtimeexception:运行时异常:LogicException 逻辑异常。代码写的不严谨 数组越界 空指针异常,这是程序员出的错。
罗列常见的5个运行时异常:此类异常又代表逻辑异常
1算数异常
2空指针
3类型转换异常
4数组越界
5NumberFormateException(数字格式异常,转换失败,比如“a12” 就会转换失败)
19,本质上来说创建线程的方式就是继承Thread,就是线程池,内部也是创建好线程对象来执行任务。
20, 什么时候需要考虑线程安全?
1,多个线程访问同一个资源
2,资源是有状态的,比如我们上述讲的字符串拼接,这个时候数据是会有变化的。
21,sleep和wait的区别:
1,sleep方法定义在Thread上
wait方法定义在object上
2,sleep不会释放锁
wait会释放锁
3,sleep可以使用在任何代码块中
wait必须在同步方法或是同步代码块中
yield()执行后线程直接进入就绪状态,马上释放CPU的执行权,但是依然保留了CPU的执行资格,所以有可能CPU下次进行线程调度还会让这个线程获取到执行权继续执行。
22,每个线程都会有对应的map,map来保存键值对
map<key,value>:
key:存放的是threadlocal
value:存放的是具体的内容
23,Ajax的工作原理
谈这个问题的关键三要素,异步交互,XMLHttpRequest对象,回调函数。
24,谈谈Servlet的生命周期:
首先,要明确一点,Servlet是单例的,这个很重要
生命周期的流程:
创建对象–>初始化–>service()–>doXXX()–>销毁
25,Session和Cookie的区别
1存储位置不同
Session:服务器端
Cookie: 客户端
2存储的数据格式不同
Session:value为对象,Object类型
Cookie:value为字符串,如果我们存储一个对象,这个时候就需要转换成json格式
3存储的数据大小
Session:受服务器内存控制
CookieL一般来说,最大为4k
cookie跟session之间的联系
http协议是一种无状态协议,服务器为了记住用户的状态,我们采用的是Session的机制,而session机制的背后原理是,服务器会自动生成会话级的cookie来保存session的标识。
26,jsp的9大内置对象:
request(HttpServletRequest)
response(HttpServletResponse)
config(ServletConfig)
application(ServletContext)
session(HttpSession)
exception(Throwable)
page(Object(this))
out(JspWriter)
pageContext(PageContext)
27,jsp的4大域对象
ServletContext context域:只能在同一个web应用中使用(全局的)
HttpSession session域:只能在同一个会话(session对象)中使用(私有的,多个请求和响应之间)
HttpServletRequest request域:只能在同一个请求中使用(转发才有效,重定向无效)
PageContext page域:只能在当前jsp页面使用(当前页面)
28,并发:同一个CPU执行多个任务,按细节的时间片交替执行
并行:再多个CPU上同时处理多个任务
29,左连接:以左表为主
select a.,b. from a left join b on a.b_id = b.id;
右连接:以右表为主
select a.,b. from a right join b on a.b_id = b.id
内连接:只列出两张表的公共内容
select a.,b. from a inner join b on a.b_id = b.id
30,TCP和UDP的区别
tcp提供可靠的传输协议,传输前需要建立连接,面向字节流传输
udp无法保证传输的可靠性,无需创建连接,以报文的方式进行传输
31,如何预防死锁
尽量采用tryLock(timeout)的方法,可以设置超时时间,这样超时之后们就可以主动退出,防止死锁
减少同步代码块嵌套操作
降低锁的使用粒度,不要几个功能共用一把锁
32,spring的bean是线程安全的吗
线程不安全构成的三要素
1,多线程环境
2,访问同一个资源
3,资源具有状态性
那么spring的bean是单例的,而且是后端程序,天然是多线程环境。那么是安全的吗?
关键看第三点,我们的bean是无状态的,所以是线程安全的
所谓无状态就是没有存储数据,即没有通过数据的状态作为下一步操作的判断条件。
33,缓存,主要的作用是提高了查询性能,减少了跟数据库交互的次数,从而也减轻了数据库承受的压力。适合于读多写少,如果数据变化频率非常高,则不适用。
任何更新操作,都会清空一级缓存
要使用二级缓存,需要经历两个步骤
1,开启二级缓存(默认处于开启状态)
<setting name=“cacheEnabled” value="true’/>
2,在Mapper.xml中,配置二级缓存(也支持在接口配置)在标签下面添加标签即可,
默认的二级缓存配置有如下特点:
所有的select语句将会被缓存
所有的更新语句(insert,update,delete)将会刷新缓存
缓存将采用LRU(Least Recently Used 最近最少使用)算法来回收
缓存会存储1024个对象引用
二级缓存的关键说明:
当关闭了SQLSession之后,才会将查询数据保存到二级缓存中(SqlSessionFactory)中,所以才有了上述的缓存命中率。MyBatis的二级缓存默认采用的是Map的实现。
34,synchronized和volatile的区别
1,作用位置不同
synchronized是修饰方法,代码块
volatile是修饰变量的
2,作用不同
synchronized,可以保证变量修饰的可见性及原子性,可能会造成线程的阻塞
volatile仅能实现变量修饰的可见性,但无法保证原子性,不会造成线程的阻塞
35,如何实现一个IOC容器
1,配置文件配置包扫描路径
2,递归包扫描获取.class文件
3,反射、确定需要交给IOC管理的类
4,对需要注入的类进行依赖注入
36,final修饰引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象,但是引用的值是可以改变的。局部内部类和匿名内部类只能访问局部final变量