数组与集合的区别:
- 数组声明了它容纳的元素类型,而集合不声明
- 数组是具有固定的大小,一旦创建了就无法改变容量了,而集合可以动态的改变扩展容量,可以根据需要动态的改变大小(一句话形同:数组是固定长度的,集合是可变长度的)
- 数组可以存储基本类型数据,也可以存储引用类型的数据,集合只能存储引用类型的数据。
- 数组存储的数据必须是同一类型的数据,集合存储的对象可以是不同的数据类型
集合的特点:
- 对象封装数据,对象多了也需要存储。集合就是用来存储对象的。
- 对象的个数已经确定了可以使用数组,对象的个数不确定可以使用集合,因为集合是可变长度的
List Set和Map之间的区别:
List:是一个有序的容器,元素可以重复,可以插入多条NULL元素
Set:是一个无序的容器,不可以存储重复的元素,只允许存入一个NULL元素,必须保证元素的唯一性
Map:是一个键值对集合,存储键,值和之间的映射,key无序,value
不要求有序,允许重复。Map没有继承Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回值对象。
常用集合底层结构:
ArrayList:Object数组
LinkedList:双向循环链表
HashSet:(无序,唯一)基于HashMap实现的底层采用HashMap来保存元素
HashMap:有数组+链表组成JDK1.8之前,链表主要是为了解决哈希冲突而存在,JDK1.8之后当链表长度大于阈值(8)时,将链表转化为红黑树,以减少搜索时间。
什么是哈希冲突:
当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,我们就把他叫做哈希碰撞。
线程安全:
就是多线程环境中对全局变量的变动时,需要对执行的代码块采用锁机制,当一个线程访问到某个数据时,其他线程需要等待当前线程执行完,该代码块才可以执行,不会出现数据不一致的情况或者数据被污染。
线程不安全:
就是不提供数据访问保护,在多线程环境中对数据修改,会出现数据不一致的情况
悲观锁乐观锁:
悲观锁:总是假设最坏的情况,就是每次去拿数据的时候都认为别人会修改,所以在拿数据的时候都会上锁,这样别人想拿这个数据时就会阻塞直到他拿到锁为止(共享资源每次只给一个线程使用,其他线程阻塞,用完再把资源转让给其他线程)传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁,读锁,写锁等,都是在做操作之前就上锁。
乐观锁:总是假设最好的情况,每次拿数据都的时候都认为不会修改,所以不会上锁,但是在更新的时候会判断一下,在此期间有没有人去更新这个数据,可以使用版本号机制和CAS算法实现,乐观锁适用于多读的应用类型,这样可以提高吞吐量。
Java的锁机制一般可以分为七大类:
1.偏向锁/轻量级锁/重量级锁
2.可重入锁/非可重入锁
3.共享锁/独占锁
4.公平锁/非公平锁
5.悲观锁/乐观锁
6.自旋锁/非自旋锁
7.可中断锁/不可中断锁
SpringMVC:
M:model(模型)V:view(视图)C:controller(控制)
Model:处理业务逻辑模块
View:负责页面显示,显示model的处理结果给用户,主要实现数据到页面的转换过程。
Controller:负责每个请求的分发,发From数据传递给model进行处理,处理完成后,把处理结果返回给相应的View显示给用户
Spring MVC工作流程:
- 用户发起请求到前端控制器(Dispatcherservlet),该控制器会过滤出那些请求可以访问,那些不能访问
- 前端控制器会找到处理器映射器(HandlerMapping),通过处理器映射器完成url到Controller映射的组件(也就是说在springmvc.xml中配置的或者注解的url与对应的处理类找到并进行存储,用map<url,handler>集合来存储)
- 处理器映射器有了映射关系,并且找到了url对应的处理器(Handler),处理器映射器就会将处理器返回,在返回前会加上很多拦截器
- 前端控制器拿到处理器后,找到处理器适配器(HandlerAdapter)通过他来访问处理器,并执行处理器
- 执行处理器
- 处理器会返回一个ModeAndView对象给处理器适配器
- 通过处理器适配器将ModeAndView对象返回给前端控制器
- 前端控制器在请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图解析成一个真正的视图(.jsp),其实就是将ModeAndView对象中存放的视图名进行查找,找到对应的页面形成视图对象
- 返回视图对象给前端控制器
- 视图渲染,就是将ModeAndView对象中的数据放到request域中(用来让页面加载数据的)
- 通过视图解析名找到了对应的页面,通过视图渲染让request域中有了所需要的数据,那么就能视图渲染返回响应给用户
面向对象:
面向对象就像是把一件事情拆分成多个对象,而我们不需要去管这个对象内部去做什么,我们只需要知道这个对象的作用就可以了。这样的话更加易于复用 扩展和维护。
封装:类的封装性为类成员提供公有,缺省,保护和私有等访问权限,目的是隐藏类中的私有变量和类中方法的实现细节
继承:允许通过继承原有类的某些特性或全部而产生全新的类,原有的类称为父类,产生的新类被称为子类。子类不仅可以直接继承父类的共性,而且也可以创建他特有的个性
多态:多态有三个前提1.继承2.方法重写3.父类引用指向子类对象
是指在基类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同行为,多态有两种表现方式:重载与覆盖
==与equals之间的区别:
==操作符专门用来比较两个变量的值是否相等,也就是比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
super与this的区别:
1.super()主要是对父类构造函数的调用,this()是对重载构造函数的调用
2.super()主要是在继承了父类的子类的构造函数中使用,是在不同类中使用的,this()主要是在同一个类的不同构造函数中的使用
Request生命周期:
request对象的生命周期是针对一个客户端的一次请求,当请求完毕之后,request里边的内容也将被释放,一个请求开始时创建,请求结束后销毁。
cookie与session的区别:
cookie数据存放在客户的浏览器上,session数据放在服务器上
cookie不是很安全,别人可以分析存放在本地的cookie进行cookie欺骗,考虑到安全应当使用session。
session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
Ajax原理:
Ajax的工作原理相当于在用户和服务器之间加了一个中间层,使用户操作与服务器响应异步化,并不是所有的用户请求都提交给服务器,像一些数据验证和数据处理等都交给Ajax引擎自己来做,只有确定需要从服务器读取数据时再由Ajax引擎代为向服务器提交请求
SQL优化:
1.select语句中避免使用*号
2.SQL用大写的
3.尽量减少子查询,使用关联查询(left join,right join,inner join)代替
4.减少使用in 或者not in ,使用exists和not exists 或者关联查询语句代替
Mybatis的好处:
把SQL语句从Java中独立出来
封装了底层的JDBC,API的调用,并且能够将结果集自动转换成JavaBean对象,简化了Java数据库编程的重复的工作
#{}与${}:
#{}是预编译处理
${}是字符串替换
mybatis在处理#{}时,会将sql中的#{}替换成?,调用PreparedStatement的set方法来赋值
mybatis在处理${}时,就是把${}替换成变量的值,相当于字符串拼接
使用#{}${}可以有效的防止sql注入,提高系统的安全性
Spring:
Spring ioc:
IOC是spring中提供的一种控制反转机制,目的是将我们项目中对象的依赖管理交给spring实现,这样可以更好实现对象关系的解耦合,提高程序的可扩展性。
Spring di:
DI是spring中的依赖注入机制,ioc的实现需要借助这种机制,我们通常会这样理解,SpringBean容器中的ioc思想一种目标,DI是实现这种思想的目标的手段
SpringAOP:
AOP底层是采用动态代理机制实现的:接口+实现类
在软件开发过程中,跨越应用程序多个点的功能称为交叉问题,这些交叉问题与应用程序的主要业务逻辑不同,因此,将这些横切关注与业务逻辑分开是面向切面编程(AOP)的地方。
JDBC连接数据库的流程:
1.注册驱动
2.获取链接
3.创建一个Statement语句对象
4.执行SQL语句
5.处理结果集
6.关闭资源
final、finally、finalize的区别:
final是修饰符,可以用来修饰类、方法、变量
使用final修饰的类表示该类不能被继承,使用final修饰的方法不能重写,使用final修饰的变量,表示该变量是常量,不能被重新赋值
finally是try-cath中的一环,无论代码是否有异常抛出,finally中的代码一定会执行,通常是放置一些释放资源的代码
finalize是Object类中的一个方法,在垃圾收集器执行的时候会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其他资源的回收,例如关闭文件等。
重写与重载的区别:
重写:发生在子父类类中,方法名、参数列表必须相同。如果父类的修饰符为私有的则子类不能重写该方法。
重载:发生在同一个类中,方法名相同,参数列表不同
super和this的区别:
super指向父类,this指向自己本身
抽象类和接口的区别:
1.抽象类中有构造方法,接口中没有构造方法
2.接口和接口之间支持多继承,类和类之间只能单继承
3.一个类可以实现多个接口,但只能有一个抽象类
多线程:
进程:正在进行的程序
线程:就是进程中一个负责程序执行的控制单元
一个进程中可以有多个执行路径,称为多线程。
一个进程至少有一个线程
开启多个线程是为了同时运行多部分代码
利弊:
利:解决了多部份同时运行的问题
弊:使用不当会降低效率,消耗性能
break和contiue的区别:
用break语句可以使流程跳出switch语句,也可以用break语句在循环结构中终止本层循环体,从而提前结束循环。
contiue语句的作用是跳过本次循环体中尚未执行的语句,立即进行下一次的循环条件判断,可以理解为仅结束本次循环
session、cookie、token的区别:
Session 数据在服务器内存中
Cookie 数据在客户端
Token 数据在客户端,加解密,客户端不能篡改,时间换空间