1. 什么是向上转型,向下转型?
向上转型:父类引用指向子类对象。
向下转型:子类对象指向父类引用(强转),先向上转型,在向下转型,没有经过向上转型,会提示编译错误。
2.什么是数组,有什么特点?
数组是一种容器,可以同时存放多个类型相同的数据。
数组是一种引用数据类型,当有多个数据类型必须统一,数组长度在运行期间不可改变长度在创建时给定。
3.什么是集合,和数组的区别?
是Java中提供的一种容器,用来存储多个数据。
数组的长度是固定的,集合的长度是可变的;数组中存储的是同一类型的元素,集合存储的类型可以不一致;
4.你所知道的List有哪些,特点分别是什么?
ArrayList:底层的数据结构是数组,所以查询快,增删慢,线程不安全
LinkedList:底层的数据结构是链表,所以查询慢,增删快,线程不安全
Vector:底层的数据结构是数组,查询快,增删慢,线程安全
5.TreeSet是如何排序的?
实现Comparable接口,覆写compareTo()方法,只能对该类的对象进行比较
匿名内部类比较器,Comparator重写compare方法,相当于一个外部比较器
6.Queue有哪些,各有什么特点?
高性能队列ConcurrentLinkedQueue:使用于高并发场景的队列,基于链接结点的无界线程安全队列,先进先出,不允许有null元素
阻塞队列BlockingQueue分为以下五种:
-
ArrayBlockingQueue:基于数组的阻塞队列,也叫有界队列
-
LinkedBlockingQueue:基于链表的阻塞队列,无界队列
-
PriorityBlockingQueue:基于优先级的阻塞队列,优先级的判断通过构造器传入的比较器来决定,是一个无界队列
-
DelayQueue:带有延迟时间的队列,是一个没有大小的队列
-
SynchronousQueue:一种没有缓冲的队列
7.Hashtable和HashMap的区别?
HashTable继承自Dirctionary(一个抽象类,用来存储键值对,作用和map类相似,字典类),HashMap继承自AbstractMap,两者均实现了Map接口;
HashTable线程安全,key和value都不能为空;,HashMap线程不安全,key和value都可以为空;
遍历:HashTable和HashMap两者都实现了Iterator,但是HashTable还是用了Enumeration;
哈希值:HashTable是直接使用对象的hashCode,HashMap是重新计算hash值
8.Vector和ArrayList的区别?
Vector是线程安全的,ArrayList是线程不安全的;
ArrayList在底层数组不够用时在原来的基础上扩展0.5倍,Vector是扩展1倍;
9.说出几个IO流对象,各有什么特点?
File:文件类
InputStream:抽象类,字节输入流
OutputStream:抽象类,字节输出流
Reader:抽象类,字符输入流
Writer:抽象类,字符输出流
文件字节输入输出流:FileInputStream,FileOutputStream
文件字符输入输出流:FileReader,File
字节输入输出缓冲流:BufferedInputStream,BufferedOutputStream
字符输入输出缓冲流:BufferedReader,BufferedWriter
10.线程和进程的关系和区别?
线程是进程的基本执行单元,一个进程的所有任务都在线程中执行,进程如果想要执行任务,必须要有线程,进程至少要有一条线程,进程是指在系统中正在运行的一个应用程序,每个进程之间是独立的,同一进程的线程共享本进程的地址空间、资源。
11.线程池有哪些,各有什么特点?
newCachedThreadPool:可缓存线程池,线程数量不定
newFixedThreadPool:定长线程池,线程数量固定,当处于闲置状态也不会被回收
newScheduledThreadPool:周期性执行任务的线程池,核心线程数是固定的,非核心线程数是没有限制的,非核心线程闲置时会被立即回收
newSingleThreadExecutor:单线程化的线程池,只有一个核心线程,以无界队列方式来执行该线程,这使得这些任务之间不需要处理线程同步的问题,它确保所有的任务都在同一个线程中按顺序中执行,并且可以在任意给定的时间不会有多个线程是活动的。
12.为什么要使用数据库连接池?
如果没有用连接池,每次发起SQL查询时首先通过TCP协议的三次握手和数据库服务建立连接,然后发送账号密码,验证过后才提交SQL语句执行,执行完毕后再TCP四次挥手最后完成关闭。如果执行多个SQL就会频繁的建立连接然后关闭,如果用连接池就是用空间换时间思想,系统启动预先创建多个数据库连接对象,虽然会占用一定的内存空间,但是可以省去每次SQL查询时创建连接和关闭连接所消耗的时间。
常用的数据库连接池:DBCP,C3P0,阿里的DRUID
13.Socket用的是什么协议,四层协议分别是什么?
TCP/IP协议,Socket用于通信,因此需要可靠的网络协议,UDP是不可靠协议,
应用层:HTTP应用程序间沟通的层
传输层:TCP、UDP这一层负责数据格式化,数据确认和丢失重传(传送数据,并且确定数据已经被送达并接收)
互联网络层:IP负责提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(邮件的地址)
网络接口层:接收IP数据包并进行传输(送邮件的车)
14.详细说一下三次握手和四次挥手的过程?
所谓的“三次握手”:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。
为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。
第一次握手:客户端向服务端发起建立连接请求,客户端会随机生成一个起始序列号x,客户端向服务端发送的字段中包含标志位SYN=1,序列号seq=x。第一次握手前客户端的状态为CLOSE,第一次握手后客户端的状态为SYN-SENT。此时服务端的状态为LISTEN
第二次握手:服务端在收到客户端发来的报文后,会随机生成一个服务端的起始序列号y,然后给客户端回复一段报文,其中包括标志位SYN=1,ACK=1,序列号seq=y,确认号ack=x+1。第二次握手前服务端的状态为LISTEN,第二次握手后服务端的状态为SYN-RCVD,此时客户端的状态为SYN-SENT。(其中SYN=1表示要和客户端建立一个连接,ACK=1表示确认序号有效)
第三次握手:客户端收到服务端发来的报文后,会再向服务端发送报文,其中包含标志位ACK=1,序列号seq=x+1,确认号ack=y+1。第三次握手前客户端的状态为SYN-SENT,第三次握手后客户端和服务端的状态都为ESTABLISHED。
四次挥手:
第一次挥手:客户端向服务端发送的数据完成后,向服务端发起释放连接报文,报文包含标志位FIN=1,序列号seq=u。此时客户端只能接收数据,不能向服务端发送数据。
第二次挥手:服务端收到客户端的释放连接报文后,向客户端发送确认报文,包含标志位ACK=1,序列号seq=v,确认号ack=u+1。此时客户端到服务端的连接已经释放掉,客户端不能像服务端发送数据,服务端也不能向客户端发送数据。但服务端到客户端的单向连接还能正常传输数据。
第三次挥手:服务端发送完数据后向客户端发出连接释放报文,报文包含标志位FIN=1,标志位ACK=1,序列号seq=w,确认号ack=u+1。
第四次挥手:客户端收到服务端发送的释放连接请求,向服务端发送确认报文,包含标志位ACK=1,序列号seq=u+1,确认号ack=w+1。
为什么TCP连接的时候是3次,两次是否可以:
-
假设建立TCP连接仅需要两次握手,那么如果第二次握手时,服务端返回给客户端的确认报文丢失了,客户端这边认为服务端没有和他建立连接,而服务端却以为已经和客户端建立了连接,并且可能向服务端已经开始向客户端发送数据,但客户端并不会接收这些数据,浪费了资源。如果是三次握手,不会出现双方连接还未完全建立成功就开始发送数据的情况。
-
如果服务端接收到了一个早已失效的来自客户端的连接请求报文,会向客户端发送确认报文同意建立TCP连接。但因为客户端并不需要向服务端发送数据,所以此次TCP连接没有意义并且浪费了资源。
为什么TCP连接的时候是3次,关闭的时候是4次
因为需要确保通信双方都能通知对方释放连接,假设客服端发送完数据向服务端发送释放连接请求,当客服端并不知道,服务端是否已经发送完数据,所以此次断开的是客服端到服务端的单向连接,服务端返回给客户端确认报文后,服务端还能继续单向给客户端发送数据。当服务端发送完数据后还需要向客户端发送释放连接请求,客户端返回确认报文,TCP连接彻底关闭。所以断开TCP连接需要客户端和服务端分别通知对方并分别收到确认报文,一共需要四次。
15.想要让SQL查询效率高,可以做哪些工作?
explain的用法:explain+sql语句,例如:explain select * from securityprice order by index
可以模拟MySQL优化器执行SQL语句,可以很好的分析SQL语句的性能
-
应尽量避免全表扫描,首先考虑在where及order by涉及的列上建立索引
-
应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描
-
应尽量避免在where子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描
-
应尽量避免在where子句中使用or来连接条件,否则引擎将放弃使用索引而进行全表扫描
-
in和not in也要慎用
-
用exists代替in
-
模糊查询不要使用%查询数据%的格式,最前面最好直接是查询数据
-
避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描
-
不要在where子句中的=左边进行函数、算数运算或其他表达式,否则系统将可能无法正确使用索引
-
索引不是越多越好,索引固然可以提高select的效率,但是同时也降低了insert及update的效率
-
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。因为引擎在处理查询和连接对象时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了
-
用varchar代替char,因为变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些
-
任何地方都不要使用select * from t,用具体字段列表代替*
-
尽量避免大事务操作,提高系统并发能力
-
避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理
16.什么是游标,有哪些分类?
用来存储多条查询数据的一种数据结构(数据集),它有一个指针,从上往下移动,从而能够遍历每条记录。游标就是位于内存中的数据集,加快对数据的操作。牺牲内存,提高sql执行效率
系统游标(隐式游标):系统定义好的游标,一般在做DML操作时自动触发,一般用于看影响行数
用户游标(显式游标):
- 静态游标:创建游标的SQL语句是固定的
- 动态游标:创建游标的SQL语句是动态的,带有参数或变量
17.GET方式和POST方式有哪些区别?
-
GET在浏览器回退时是无害的,POST会在次提交请求
-
GET请求产生的URL地址可以被看到,而POST不可以
-
GET请求会被浏览器主动缓存,而POST不会,除非主动设置
-
GET请求只能进行url编码,而POST支持多种编码方式
-
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
-
GET请求在URL中传送的参数是有长度限制的,而POST没有
-
对参数的数据类型,GET只接受ASCII字符,而POST没有限制
-
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
-
GET参数通过URL传递,POST放在Request body中
-
GEt和POST请求是HTTP协议中的两种请求的方法,底层是TCP/IP。GET产生一个TCP数据包,POST产生两个TCP数据包。对于GET请求浏览器会把http header和data一并发送出去;POST请求会先发送header,服务器响应100 continue,浏览器在发送data;注:据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
18.CSS选择器有哪些?
标签选择器
ID选择器
类选择器
组选择器
通配符选择器
后代选择器
子元素选择器
兄弟选择器
相邻选择器
属性选择器
伪类选择器
19.什么是盒子模型的坍塌?
父子坍塌:父亲没有设置padding border内容时,子元素垂直方向的margin会赋给父亲,父亲最终垂直方向的margin为父子中最大的margin值,并非相加
解决方法:把儿子的margin装换成父亲的padding;或给父元素增加position:absolute
并列元素坍塌:垂直方向相遇的盒子模型,会发生margin坍塌,现象就是元素两者之间的距离并非之和,而是二者之间最大的
解决方法:给第一个元素只设置margin
20.去掉元素的浮动怎么做?
-
为父元素添加overflow:hidden
-
clear:both
-
floatfix类
21.接口和抽象类的区别?
-
都不能被实例化,但是抽象类里可以有构造方法,接口里不能有构造方法
-
接口只有定义,不能有方法的实现,java1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可以在抽象类中实现
-
接口强调特定功能的实现,而抽象类强调所属关系
-
接口成员变量默认为public static final,必须赋值,不能被修改,其所有的成员方法都是public abstract的,抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值,
抽象方法被abstract修饰,不能被private、static、synchrornized和native等修饰。
22.什么是DI和IoC?什么是AOP?
23.什么是本地线程,有什么好处?
线程类Thread有个变量叫做threadLocals,它的类型就是ThreadLocal.ThreadLocalMap类型,key是当前线程的ThreadLocal对象,值就是要保存的数据。每个线程自己的本地变量,在每个线程里面对变量单独记录保存。
在多线程并发执行时,有时需要进行数据共享,所以有了volatile变量解决多线程间的数据可见性,也有了锁的同步机制,使变量或代码在某一时刻,只能被一个线程访问,确保数据共享的正确性。有时不需要数据共享,让每个线程都有自己独立的变量,ThreadLocal就是用于线程间的数据隔离的。
24.数据库事务有哪些特点?
-
原子性:指事务包含的所有操作要么全部成功,要么全部失败回滚
-
一致性:事务必须使数据库从一个一致性状态变换到另一个一致性状态
-
隔离性:当多个用户并发访问数据库时,不能被其他事务的操作所干扰
-
持久性:一个事务一旦被提交了,对数据库中的数据的改变就是永久性的
-
脏读:一个事务处理过程中,读取了另一个未提交的事务中的数据
-
不可重复读:对于数据库中的某一条数据在一个事务范围内,多次查询却返回了不同的数据值
-
幻读:事务非独立执行时发生的一种现象,例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
25.数据库有哪些锁?
为了保证数据的一致性,MySQL各存储引擎使用了三种类型的锁机制:表级锁定,行级锁定和页级锁定
-
表级锁:一次会将整个表锁定,可以避免死锁问题,锁定力度大,锁冲突概率高,并发度底,开销小,获取锁和释放锁的速度很快,适用于查询为主,少量更新
-
行级锁:锁定对象的力度小,发生锁冲突概率低,并发度高,但是开销大,加锁慢,行级锁容易发生死锁。适用于对事务完整性要求较高的系统。
InnoDB行级锁类型
- 共享锁:读锁,多个事务对同一数据进行共享一把锁,都能访问到数据,但是只能读不能修改
- 排它锁:写锁,排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制。
- 意向锁是InnoDB自动加的,不需用户干预,意向锁不会与行级的共享/排它锁互斥
- 页面锁:介于行级锁和表级锁之间,会发生死锁,锁定的数据资源比行锁要多,因为一个业种可以有多个行记录,我们使用页锁的时候,会出现数据浪费的现象。
26.什么是视图,视图有什么作用?
存储的查询语句,当调用的时候,产生结果集,视图充当的是虚拟表的角色。
简单:使用视图的用户完全不需要关心后面对应的表的结构,关联条件和筛选条件对用户来说已经是过滤好的复合条件的结果集
安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行,某个列,但是通过视图就可以简单的实现。
数据独立:一旦视图的结构确认了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响,源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响
综上,使用视图的大部分情况是为了保障数据安全性,提高查询效率
27.Servlet是单例还是多例,是否线程安全?如何解决安全问题?
servlet是单例的,严格地说是一个ServletMapping对应一个单例实例(如果一个Servlet被映射了两个URL地址,会生成两个实例)。线程不安全。维护Servlet线程安全通常是使用同步块(或方法)来保护共享数据,其次可以是volatile、Lock一些锁机制,还可以使用ThreadLocal来打通安全通道,另外还有原子操作也是用来保护数据安全
28.Spring是单例还是多例?如何配置?
spring生成的对象默认是单例的,通过scope="prototype"可以更改为多例
29. 常见的Linux命令
30. 闭包
读取其他函数内部变量的函数,只有函数内部的子函数才能读取局部变量,可以理解为:定义在一个函数内部的函数。本质上,闭包是将函数内部和函数外部连接起来的桥梁。
31. 分布式
计算机的一种算法,一个大型的系统往往被分为几个子系统来做,一个子系统可以部署在一台机器的多个JVM上,也可以部署在多台机器上,但是每一个系统不是独立的,不是完全独立的。需要相互通信,共同实现业务功能。一句话来说:分布式就是通过计算机网络将后端工作分布到多台主机上,多个主机一起协同完成工作。
32. 过滤器(Filter)和拦截器(Interceptor)的区别
实现原理不同:过滤器是基于函数回调的,拦截器是基于Java的反射机制(动态代理)实现的。
适用范围不同:过滤器实现的是java.servlet.Filter接口,这个接口是在Servlet规范中定义的,也就是说过滤器Filter的使用要依赖于Tomcat等容器,导致只能在web程序中使用;拦截器是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用。
触发时机不同:过滤器是在请求进入容器后,但是在进入servlet之前进行预处理,请求结果是在servlet处理完成以后;拦截器是在请求进入servlet后,在进入Controller之前进行预处理,Controller中渲染了对应的视图之后请求结束。
拦截的请求范围不同:过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用
33. 创建对象的五种方式
使用new关键字创建对象(调用了构造函数)
使用Class类的newInstance方法(调用了构造函数)
使用Constructor类的newInstance方法(调用的构造函数)
使用了clone方法(没有调用构造函数)
使用了反序列化(没有调用构造函数)