java面试题

1.java基础

java的跨平台原理

由于各操作系统(windows,liunx等)支持的指令集,不是完全一致的。就会让我们的程序在不同的操作系统上要执行不同程序代码。Java开发了适用于不同操作系统及位数的java虚拟机来屏蔽个系统之间的差异,提供统一的接口。对于我们java开发者而言,你只需要在不同的系统上安装对应的不同java虚拟机、这时你的java程序只要遵循java规范,就可以在所有的操作系统上面运行java程序了。

面向对象的特性

封装:对特定代码块或变量进行归类

继承:extends,让子类具有父类的某些属性和方法(产生关系)。单继承。

多态:父类引用变量指向子类对象,提高代码的扩展性。(大范围可接受小范围)

int与Integer的区别

int是基本数据类型,integer是引用数据类型,是对int的包装;

int的默认值是0,integer的默认值是null;

int类型的变量可以直接使用,integer变量需要实例化之后才能使用;

int直接存放数据值,integer是对象的引用,创建一个实例之后就产生了一个指针指针指向这个对象。

有了基本数据类型,为什么还需要包装类型?

基本数据类型:java中提供了8中基本的数据类型。boolean int float等

包装类型:每一个基本的数据类型都会一一对应一个包装类型。

boolean ----->Boolean,Int -------->Integer

装箱:把基本的数据类型转换成对应的包装类型.

拆箱:就是把包装类型转换为基本数据类型.基本数据类型

Java是一个面向对象的语言,而基本的数据类型,不具备面向对象的特性。如null的表示 Integer--->null, int---->0 用Integer和int分别表示Person这个类的ID

Array与Arraylist的区别

Array的长度是固定的,ArrayList的长度是可变的;

效率:Array>ArrayList。原因是ArrayList动态扩容造成了效率消耗。

ArrayList list = new ArrayList(20);中的list扩充 0 次。

集合

HashMap底层实现原理?

Jdk1.7与jdk1.8中HashMap的区别:在1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。而1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

HashMap的工作原理:实现了Map接口,采用key-value的形式存储数据,使用put()方法保存数据,使用get()方法获取数据。每一个键值对组成了一个Entry实体,Entry类是一个单向的链表结构,它具有Next指针,用来连接下一个Entry实体。当发生碰撞时,对象会储存在链表的下一个节点。

HashMap和HashTable的区别

相同点:HashMap和HasheTalbe都可以使用来存储key--value的数据。

区别:HashMap是可以把null作为key或者value的,而HashTable是不可以的;

    HashMap是线程不安全的,效率较高。而HashTalbe是线程安全的,效率较低

HashMap与HashSet的区别?

HashSet实现了Set接口,不允许集合中出现重复的元素,而HashMap实现了Map接口,不允许出现重复的键;

HashSet存储对象,HashMap存储键值对;

HashSet通过add()方法向集合添加元素,HashMap通过put()方法向集合添加元素;

HashSet使用成员对象计算hashcode值,若值相等,则用equals判断对象的相等性,HashMap使用键计算hashcode值;

HashMap相对于HashSet较快,因为根据唯一的键获取对象。

java中代码块的介绍?

static{ 静态代码块,做初始化}

构造代码块{ },在类中的代码块

局部代码块 { },在方法中的代码块

三个的执行顺序:静态  ->  构造  ->  局部代码块。

执行顺序:父类静态代码块->子类静态代码块->父类的构造代码块->父类构造方法->子类构造代码块->子类构造方法。

heap与stack的区别

Stack(栈)是JVM的内存指令区

Heap(堆)是JVM的内存数据区

同步与异步的区别

同步:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。

异步:将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。

同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在响应用户,用户体验不好。

异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好。

什么是内存泄漏?

内存泄漏是指程序中已经动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行缓慢甚至系统奔溃等严重后果。

什么是死锁?解决办法?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

可以通过预防和避免死锁来阻止死锁的发生。

"=="和equals方法究竟有什么区别? 

==用来判断两个变量之间的的值是否相等。变量就可以分为基本数据类型变量,引用类型。如果是基本数据类型的变量直接比较值,而引用类型要比较对应的引用的内存的首地址。

equals 用来比较两个对象长得是否一样,也就是内容是否一致。

权限修饰符

public:公有的,任何地方可用

protected:受保护的,同包以及子类(包括同包子类和不同包子类)可用

默认的:不写就是默认的,同包以及同包子类可用

private:私有的,只在本类可用

什么是设计模式?常用的设计模式有哪些?

设计模式就是经过前人无数次的实践总结出的,设计过程中可以反复使用的、可以解决特定问题的设计方法。

常用的设计模式:单例模式:一个类仅有一个对象

工厂模式:Spring IOC就是使用了工厂模式。对象的创建交给一个工厂去创建。

代理模式:Spring AOP就是使用的动态代理

单例模式

单例模式是为了保证一个类仅有一个实例,并且自行实例化向整个系统提供。
方法:创建一个类,设置私有构造,然后使用以下一种模式。
懒汉式:需要的时候再去创建

饿汉式:先创建,可直接使用

Java中的异常处理机制的简单原理

java中使用面向对象的方式来处理异常,它把程序中发生的每一个异常分别封装到一个对象中。所有异常的根类是Throwable,Throwable又派生了两个子类Error和Exception。

Exception是程序需要捕捉和处理的异常,Error是系统级别的错误和程序不需要处理的。

Exception分为两类:Java标准定义的异常和程序员自定义异常。

Java标准定义的异常:当程序违反了Java规则时java虚拟机会把发生的错误表示为一个异常。如除数为0的异常。

程序员自定义异常:Java允许程序员扩展这种语义检查,程序员定义自己的异常处理,自由选择在何时使用throw关键字引发异常。

例如 Exception ex = new Exception("这是我自定义的异常信息");throw ex;

所有的异常都是Thowable的子类,异常处理与程序执行是并行的。

final,finally,finalize的区别?

final是来修饰属性,方法和类的,修饰属性时值不能被修改,修饰方法时不能被重写,修饰类时不能被继承。

finally用在异常处理中,try/catch/finally的格式,不论走try还是catch都会走finally(这句话有误,原因见下代码)。

finalize()是java.lang.Object中定义的,用在垃圾回收中,一个对象的finalize()方法只会被调用一次。

abstract不能与哪些关键字共用?

抽象类只定义方法名,无方法体,可以使用匿名内部类来创建对象,子类必须被重写。

1)static:被static修饰的方法是通过类名.方法名来调用的,若这个方法是抽象的,就没有方法体,毫无意义。

2)private:被private修饰的方法只能在当前类调用,抽象的方法必须被子类重写,有冲突。

3)final:被final修饰的方法不能被重写,抽象的方法必须被子类重写,有冲突。

aop与oop的区别?

aop是面向切面编程,原理是动态代理,是业务逻辑处理过程中进行切面的提取,处理某个业务逻辑,在方法调用之前做什么,在之后做什么。

oop是面向对象编程,是对实体的属性和行为的抽象与封装。

方法重载与重写的区别?

方法重载:方法名相同,参数列表不同,与返回值无关。发生在同一个类中,...表示参变参数

方法重写:子类对父类的方法进行重写编写。

this,supper与static的用法

this:表示当前类对象,谁调用就是谁。

supper:表示父类对象,使用它可以调用父类的方法,提高代码的复用性。

static:静态的,会优先加载,使用时不需要创建对象。静态的东西放在静态区,只初始化一次,没有this。

加载顺序:优先加载静态的,然后加载非静态的。因此,静态的只能使用静态的,非静态的可以使用静态和非静态的。

线程的状态

第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。

第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。

第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。

第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。

第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

多线程的实现方式

1)继承Thread类,重写run()方法

2)实现Runnable接口,重写run()方法

3)实现Callable接口,重写call()方法,可提供返回值

java创建对象有哪些方法?

1)new 方式创建

2)使用反射机制创建:使用Class类的newInstance方法

3)使用clone()克隆方式创建:clone时,需要已经有一个分配了内存的源对象,要调用clone方法需要实现Cloneable接口,clone方法是protected的。

4)采用序列化机制创建

什么是不可变对象?

不可变对象:对象一旦被创建,对象的所有状态和属性在生命周期内不会发生变化。

创建:Collections.unmodifiableList(List<? extends T> list),这个是jdk提供的;

   ImmutableList.copyOf(list),这个是Google的Guava包中的方法

不可变对象虽然具备不可变性,但是不是"完全不可变"的,这里打上引号是因为通过反射的手段是可以改变不可变对象的状态的。

反射是在运行状态时,对于任意一个类,都能够直到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。通过类名.class来获取Class对象。

String和StringBuilder的区别(final)?StringBuffer和StringBuilder的区别?

在java中提供三个类String StringBuillder StringBuffer来表示和操作字符串:

String是内容不可变的字符串。String底层使用了一个不可变的字符数组(final char[]);

StringBuillder StringBuffer,是内容可以改变的字符串。StringBuillder StringBuffer底层使用的可变的字符数组(没有使用final来修饰);

拼接字符串不能使用String进行拼接,要使用StringBuilder或者StringBuffer;

StringBuilder是线程不安全的,效率较高,而StringBuffer是线程安全的,效率较低。

字符串的拼接有哪些方法?

+:其实现原理是使用StringBuilder.append。

concat():这个是String类中的方法。其实是new了一个新的String。

append():是StringBuffer或StringBuilder类中的方法。append会直接拷贝字符到内部的字符数组中,如果字符数组长度不够,会进行扩展。

StringUtils.join :apache.commons中提供的StringUtils类,其中的join方法可以拼接字符串。是通过StringBuilder.append来实现的。

效率:用时从短到长的对比是:StringBuilder < StringBuffer < concat < + < StringUtils.join

如果不是在循环体中进行字符串拼接的话,直接使用+就好了。如果在并发场景中进行字符串拼接的话,要使用StringBuffer来代替StringBuilder。

字符串的反转怎么实现?

1)使用数组循环方式

2)使用StringBuffer的reverse()方法

3)使用StringBuffer循环方式

4)利用栈的先进后出原则

5)递归方式

常见的运行时异常

NullpointerException空指针异常

FileNotFoundException文件找不到异常

ClassCastException类型转换异常

ArrayIndexOutOfBoundsException数组下标越界异常

NumberFormartException数字格式异常

ClassNotFoundException类找不到异常

ArithmeticException算术异常

ConcurrentModificationException并发修改异常

Java的垃圾回收机制

垃圾收集GC(Garbage Collection)是Java语言的核心技术之一, 在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理。对于Java对象来讲,如果说这个对象没有被其他对象所引用,那么该对象就是无用的,此对象就被称为垃圾,其占用的内存也就要被销毁。

回收算法:

标记-清除法:把需要回收的垃圾先进行标记,然后直接清除,会产生大量不连续的碎片。

标记-整理法:把需要回收的垃圾先进行标记,然后把存活对象向一端移动,再把标记的对象清理掉,提高了内存使用率。

复制法:把内存分为大小相同的块,每次使用其中的一块,当这块被使用完后,就把还存活的对象复制到另一块中,然后把该块的空间一次清理掉。

分代收集法:当前虚拟机的垃圾收集都采用分代收集算法,这种算法就是根据具体的情况选择具体的垃圾回收算法。一般将 java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。比如在新生代中,每次收集都会有大量对象死去,所以可以选择复制算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。

说一下Spring中的两大核心?

spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架。

IOC控制权反转(把对象的控制权交给spring管理):就是配置文件+反射(工厂也可以)+容器(map)

AOP(面向切面编程):使用动态代理的设计模式在执行方法前后或出现异常做加入相关逻辑

在这里也简单介绍一下DI。DI是依赖注入,@Value:简单属性值注入,@Automated:复杂类型的注入,@Reference:远程注入

什么是ORM?

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的方案是采用硬编码方式(jdbc操作sql方式),为每一种可能的数据库访问操作提供单独的方法。

接口与抽象类的区别?

1)抽象类作为父类存在,抽取公有的属性和方法,而接口是抽取特有的属性和方法;

2)抽象类中可以有抽象方法和非抽象方法,接口中只能有抽象方法;

3)抽象类中的抽象方法必须被子类重写,只能是单继承、多层继承,而接口中的抽象方法可以多继承、多实现;

4)接口中的方法和属性有默认的修饰符(方法public abstract,属性public static final),而抽象类中没有;

5)抽象类中可以有构造方法,而接口中没有。

接口是否可以继承接口?接口是否可以实现接口?抽象类是否可以继承实体类?

接口可以继承接口:实现关系的传递(接口不是抽象类);

接口不能实现接口:实现接口必须重写接方法,接口中不能有方法体;

抽象类可以继承实体类:抽象类中可以有非抽象方法。

2.数据库

事务隔离级别及其四大特征

事务是数据库操作的最小工作单元,如果一个包含多个步骤的业务操作,被事务管理,要么同时成功,要么同时失败。

问题:

1)脏读:一个事务,读取到另一个事务中没有提交的数据

2)幻读:一个事务操作数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改

3)不可重复读:在同一个事务中,两次读取到的数据不一样。

隔离级别:

read uncommitted:读未提交。产生的问题:脏读、不可重复读、幻读

read committed:读已提交 (Oracle)。产生的问题:不可重复读、幻读

repeatable read:可重复读 (MySQL默认。 产生的问题:幻读

serializable:串行化。可以解决所有的问题

隔离级别从小到大安全性越来越高,但是效率越来越低 

特征:

1)原子性(Atomicity):事务是不可分割的最小操作单位,要么同时成功,要么同时失败

2)一致性(Consistemcy):事务操作前后,数据总量保持不变

3)持久性(Isolation):当事务提交或回滚后,数据库持久化的保存数据

4)隔离性(Durability):多个事务之间相互独立,互不影响 

数据库的分类及常用的数据库?

数据库分为:关系型数据库和非关系型数据库

关系型:mysql oracle sqlserver等

非关系型:redis,memcache,mogodb,hadoop等

mysql复制表到新表

方式一:

复制表结构及数据到新表 

create table 新表  select * from 旧表

只复制表结构(让where条件不成立即可)

create table 新表  select * from 旧表 where 1=2

方式二:

复制表结构

create table 新表 like 旧表

复制表数据(两个表结构一样)

insert into 新表 select * from 旧表

复制表数据(两个表结构不一样)

insert into 新表(字段1,字段2,…….) select 字段1,字段2,…… from 旧表

数据库的三大范式

第一范式(1NF):每一列都是不可分割的原子数据项。

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码。(在1NF基础上消除非主属性对主码的部分函数依赖)

1)函数依赖:A-->B,如果通过A的属性或属性组的值,可以唯一确定B属性的值,则称B依赖于A。

例如:学号-->姓名

2)完全函数依赖:A-->B,如果A是一个属性组,则B属性值的确定要依赖于A属性组的所有属性值。

例如:(学号,课程名)-->成绩

3)部分函数依赖:A-->B,如果A是一个属性组,则B属性值的确定要依赖于A属性组的部分属性值即可。

例如:(学号,课程名)-->姓名

4)传递函数依赖:A-->B,B-->C。如果通过A的属性或属性组的值,可以唯一确定B属性的值,通过B属性或属性组的值,又可以唯一确定C属性的值,则称C传递函数依赖于A.

例如:学号-->系名,系名-->系主任

5)码:在一张表中,如果一个属性或属性组,被其他所有的属性完全依赖,则称这个属性是这个表的码。

例如:该表的码为(学号,课程名称)

主属性:码属性组中的所有属性

非主属性:除了码属性组以外的属性  

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

jdbc连接数据库的步骤?

注册驱动  --》获取连接  --》获取操作对象  --》操作数据库  --》释放资源

Jdbc与mybatis的优缺点?

jdbc的缺点:不仅需要频繁的创建数据库连接,而且涉及到的增删改查等功能需要在各个java文件中编写大量代码。

mybatis优点:封装了jdbc对数据库的各种操作,减少代码增加了连接池、缓存。

Mysql与Oracle的优缺点?

在类型方面,Oracle是大型数据库而Mysql是中小型数据库,Mysql是开源的而Oracle价格非常高Oracle。

在主键方面,Mysql一般使用自动增长类型,在创建表时只要指定表的主键为auto_increment,Oracle没有自动增长类型,主键一般使用的序列。

在分页方面,mysql采用limit方式,而Oracle采用结果集的ROWNUM来指定位置进行分页。

在单引号处理方面,MYSQL里可以用双引号包起字符串,ORACLE里只可以用单引号包起字符串。

SQL基础知识梳理

select * from table where 条件 
group by 字段   #分组
having 条件      #聚合函数中使用,相当于where
order by 字段    #排序
limit index,size  #分页,起始索引,每页条数

组函数:去重 distinct()  统计总数sum()   计算个数count()  平均数avg()  最大值max() 最小数min() 

多表连接:内连接join on,左连接left join on,右连接right join on

模糊查询:like '%'

常见的面试sql语句

数据的创建请直接下载:https://pan.baidu.com/s/1TyMmujfnqyFANFi0DORHMg 提取码:b8ht

1)查询学生基本信息

查询姓“猴”的学生信息

select * from student where 姓名 like '猴%' 

查询姓名最后一个字是“猴”的学生信息

select * from student where 姓名 like '%猴' 

查询姓名中包含“猴”的学生信息

select * from student where 姓名 like '%猴%'

查询姓“孟”的老师的个数 

select count(教师号) from teacher where 教师姓名 like '孟%'

2)汇总查询

查询课程编号为0002的课程总成绩

select sum(成绩) from score where 课程号='0002'

查询选了课程的学生人数

select count(distinct 学号) from score

3)分组与排序查询

查询各科成绩最高和最低的分, 以如下的形式显示:课程号,最高分,最低分

select 课程号,max(成绩) 最高分,min(成绩) 最低分 from score group by 课程号

查询每门课程被选修的学生数

select 课程号,count(学号) from  score group by 课程号 

查询男生、女生各有多少人

select 性别,count(*)  from student group by 性别

查询平均成绩大于60分学生的学号和平均成绩

select 学号,avg(成绩) from score group by 学号 having avg(成绩)>60

查询至少选修两门课程的学生学号

select 学号,count(课程号) from score group by 学号 having count(课程号)>=2  

查询同名学生名单并统计同名人数

select 姓名,count(*) from student group by 姓名,性别 having count(*)>=2  

查询不及格的课程并按课程号从大到小排列

select 课程号,成绩 from score where 成绩<60  order by 课程号 desc

查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列

select 课程号,avg(成绩) from score group by 课程号 order by avg(成绩),课程号 desc 

检索课程编号为“0002”且分数小于60的学生学号,结果按按分数降序排列

select 学号,成绩 from score where 课程号='0002' and 成绩<60 order by 成绩 desc

统计每门课程的学生选修人数(超过2人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排序,若人数相同,按课程号升序排序

select 课程号,count(学号) from score group by 课程号 having count(学号)>2 
order by count(学号) desc,课程号 

查询两门以上不及格课程的同学的学号及其平均成绩

select 学号,avg(成绩) from score where 成绩<60  
group by 学号 having count(课程号)>=2

4)复杂查询

查询所有课程成绩小于60分学生的学号、姓名

select 学号,姓名 from student where 学号 in (
    select 学号 from score where 成绩<60
)

查询没有学全所有课的学生的学号、姓名

select 学号,姓名 from student where 学号 in (
	select 学号 from score group by 学号 having count(课程号)<(
		select count(课程号) from course )
) 

查找1990年出生的学生信息

select * from student where year(出生日期)=1990

 5)多表查询 

查询所有学生的学号、姓名、选课数、总成绩

select a.学号,a.姓名,count(b.课程号) 课程数,sum(b.成绩) 总成绩 
from student a left join score b on a.学号=b.学号 group by a.学号

查询平均成绩大于85的所有学生的学号、姓名和平均成绩

select a.学号,a.姓名,avg(b.成绩)
from student a left join score b on a.学号=b.学号 group by a.学号 having avg(b.成绩)>85

查询学生的选课情况:学号,姓名,课程号,课程名称

select a.学号,a.姓名,b.课程号,b.课程名称
from student a left join score c on a.学号=c.学号 
left join course b on b.课程号=c.课程号

查询出每门课程的及格人数和不及格人数

select 课程号,sum(
	case when 成绩>=60 then 1
		else 0 end
) 及格人数,sum(
	case when 成绩<60 then 1
		else 0 end
) 不及格人数 from score
group by 课程号

使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称

select a.课程号,b.课程名称,sum(
	case when 成绩 between 85 and 100 
	then 1 else 0 end
) '[100-85]',sum(
	case when 成绩 between 70 and 85
	then 1 else 0 end
) '[85-70]',sum(
	case when 成绩 between 60 and 70
	then 1 else 0 end
) '[70-60]',
sum(
	case when 成绩<60
	then 1 else 0 end
) '[<60]'
from score a left join course b on a.课程号=b.课程号
group by a.课程号

内连接与外连接的区别

内连接是取出两张表中匹配到的数据,匹配不到的不保留。

外连接是取出连接表中匹配到的数据,匹配不到的会保留,其值为NULL。左外连接是以左表为主,查询左表所有数据以及其与右表的交集部分;右外连接是以左表为主,查询右表所有数据以及其与左表的交集部分。

索引的优缺点

索引相当于书的目录,是一种数据结构,能够帮助我们快速的检索数据库中的数据。我们使用的是InnoDB引擎,默认的是B+树。

获取它本身及子孙节点

select * from att_dept start with id= 12 connect by PRIOR id = parentid
mybatis批量执行sql,可以使用begin/end。最语句前面加begin,在最后面加end;,语句之间用;分割

3.数据结构

算法排序

1)冒泡排序:相邻两个进行比较,大的放在后面

2)选择排序:每次选择其中最小的与前面的数字换位置。

3)快速排序:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

4.javaEE

对servlet的理解?或者servlet是什么?

Servlet全称Java Servlet, 是用Java编写的服务器端程序,而这些Sevlet都要实现Servlet这个接口。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。

JSP和Servlet有哪些相同点和不同点?

JSP是Servlet技术的扩展,所有的jsp文件都会被翻译为一个继承HttpServlet的类。也就是jsp最终也是一个Servlet,这个Servlet对外提供服务。

Servlet和JSP最主要的不同点在于JSP侧重于视图,Servlet主要用于控制逻辑。

servlet、监听器、过滤器、拦截器的区别和执行顺序?

定义上:

1)Servlet是运行服务器端的java应用程序,可以动态的生成web页面。

2)监听器listener可以监听服务器执行某一动作,并根据需求做出相应的响应。

3)过滤器filter是对资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理

生命周期上:

Servlet

1)装入:启动服务器时加载servlet的实例

2)初始化:web服务器接收到请求时调用init()方法;

3)调用:从第一次到以后的多次访问,调用doget()或dopost()方法

4)销毁:关闭服务器时调用destory()方法

Filter

1) 加载:启动服务器时加载过滤器的实例,并调用init()方法;

2) 调用:每次请求时只调用dofilter()方法

3) 销毁:服务器关闭前调用destory()方法

web.xml执行顺序:listener->filter->servlet

执行顺序

服务器启动:listener的init()-->filter的init(),有请求后调用servlet的init()方法

服务器关闭:servlet的destory()-->filter的destory()-->lister的destory()

拦截器Interceptor与过滤器的区别 

过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西;拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇。

1.拦截器是基于java反射机制的,而过滤器是基于函数回调的。

2.拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。

3.拦截器只对action起作用,而过滤器几乎可以对所有请求起作用。

4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能。

5.在action的生命周期里,拦截器可以多起调用,而过滤器只能在容器初始化时调用一次。

TCP与UDP的区别

tcp是面向连接的,udp是无连接的;

tcp提供可靠的服务,即通过tcp传输的数据不会丢失,没有重复,按顺序到达。udp无可靠性;

tcp是面向字节流的,udp是面向报文的;

tcp是全双工的可靠信道,udp是不可靠信道。

tcp的长连接与短链接的区别

长连接:建立连接——数据传输...(保持连接)...数据传输——关闭连接

短连接:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接

优缺点:长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。

 TCP长/短连接的应用场景:数据库的连接用长连接,WEB网站的http服务一般都用短链接。

在浏览器输入一个url回车后直到浏览器显示页面的过程中发生了什么?

域名解析  ->  建立tcp连接  ->  向服务器发送http请求  ->  服务器处理HTTP请求返回响应  ->  浏览器接受数据  ->  显示html页面

get请求与post请求的区别?

get请求把数据拼接在地址栏中,post请求把数据封装在请求体中;

get请求是不安全的,post请求是安全的;

get请求只能携带少量的数据,post请求数据大小无限制。

请求转发(forward)与重定向(Redirect)的区别?

请求转发地址栏不发生变化,重定向地址栏发生改变;

请求转发是一次请求(请求前后是同一个对象,转发之后会对转发之前的对象进行转换,变成ApplicationHttpRequest,但内容完全一致),重定向是两次请求;

请求转发可以共享数据,重定向不能共享数据。

浏览器的状态码?

200 - 确定。客户端请求已成功

302 - 对象已移动

400 - 错误的请求

404 - 没有找到文件或目录

500 - 内部服务器错误

cookie,session,application的区别?

cookie存放在用户浏览器,默认存活时间是一次会话(打开浏览器到关闭浏览器),数据又大小限制,大小为4k,最多有20个cookie。

session存放在服务器端,默认存活时间是30分组,数据没有大小限制,session是基于cookie的,sessionID存在cookie中。

application存放在服务器端,默认存活时间是整个应用的生命周期内。

session钝化:当服务器正常关闭时会把session对象全部保存在文件中。

session活化:当服务器启动时会把文件中的session加载到内存中。

jsp有哪些内置对象?四大作用域?

9个内置的对象:

  request   用户端请求,此请求会包含来自GET/POST请求的参数

  response   网页传回用户端的回应

  pageContext   网页的属性是在这里管理

  session   与请求有关的会话期

  application   servlet正在执行的内

  out   用来传送回应的输出

  config   servlet的构架部件

  page   JSP网页本身

  exception   针对错误网页,未捕捉的例外

四大作用域:pageContext:只在本jsp页面有效,

      request:一次请求有效,

      session:一次会话有效,

      application:整个应用有效。

简单介绍一下Ajax?

ajax是异步的javascript和xml的组合,

在不重新加载整个网页的情况下,通过AJAX与服务器进行数据交换,对网页的某部分进行更新

简单讲一下webservice使用的场景?

webservice是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互。

天气预报:可以通过实现webservice客户端调用远程天气服务实现的。

单点登录:一个服务是所有系统的登录。

什么是MyBatis?

MyBatis的前身是iBatis,是对jdbc的封装。

#{ }是占位符,可以防止sql注入

${ }字符串拼接,简单类型必须是value.

MyBatis与Hibernate的区别?

MyBatis注重的是sql的封装,是轻量级的半自动框架,原理是反射,适用于敏捷开发;

Hibernate注重映射,是重量级的全自动框架。

MyBatis动态代理开发方式?

namespace与mapper接口的全路径名相同;

mapper.xml中的id与接口中的方法名要相同;

输入参数相同,输出参数相同。

MyBatis的延迟加载与缓存是什么?

延迟加载:一条sql的查询结果作为另一条sql查询的条件。先执行一条查询语句,然后再去查询另一条语句。

一级缓存:执行两条相同的查询语句时,只会查询一次,结果存在map中,是session级别的缓存,增删改会清除缓存,是默认的缓存级别。

二级缓存:是mapper级别的缓存,默认是开启的,提交或关闭session时提交结果到二级缓存中,增删改会清空缓存。必须让实体类实现serializable接口。

springmvc的执行原理?

1、 用户发送请求至前端控制器DispatcherServlet

2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3、 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet

4、 DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

5、 执行处理器(Controller,也叫后端控制器)

6、 Controller执行完成返回ModelAndView

7、 HandlerAdaptercontroller执行结果ModelAndView返回给DispatcherServlet

8、 DispatcherServletModelAndView传给ViewReslover视图解析器

9、 ViewReslover解析后返回具体View

10、 DispatcherServletView进行渲染视图(即将模型数据填充至视图中)。

11、 DispatcherServlet响应用户

@RequestParam:取别名

@RequestBody:将请求体中的json格式的数据封装到对象中

@ResponseBody:将返回的java对象转换成json输出

springboot自动配置原理

在主启动类上一个注解@SpringBoootApplication,这个注解是一个复合注解。在这个注解中有一个注解是@SpringBootConfiguration,指明这个类是配置类;另一注解是@EnableAutoConfiguration表示开启自动配置。

@EnableAutoConfiguration中有一个注解是@Import,其导入的AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包。另一注解是@AutoConfigurationPackage,自动配置包扫描的路径,扫描的是启动类所在的包。

spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件。这个spring.factories文件是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔。  

@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在启动类执行run方法时会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

webSocket的场景应用

webSocket是一种在单个TCP连接上进行全双工通信的协议,它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。服务器与客户端只需要一次握手就可建立永久性的连接,进行双向数据传输。

应用场景:服务器更新,前端页面也进行局部刷新,更新服务器端返回的信息。

MVC的各个部分都有那些技术来实现?

M(Model) 模型:javabean

V(View) 视图:html, jsp, freemaker

C(Control) 控制器:Servlet,Action

就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
原文地址:https://www.cnblogs.com/zys2019/p/11650207.html