Java开发面试总结(未完待续)

Java开发面试总结

mybatis基础面试
SQL基本面试
Linux基本面试
spring框架基本面试

1. Java基础面试

1.1 Java的特性(三大特性/ps无脑):

封装,继承,多态
	封装:指隐藏对象的属性和细节,仅对外提供公共访问方式
		好处:
			将变化隔离 || 便于使用 || 提高重用性 || 提高安全性
		原则:1.将不需要对外提供的内容都隐藏起来
				 2.把属性都隐藏,提供公共方法对其访问

	继承:是面向对象最显著的一个特性。继承从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力
		执行顺序:
			new一个类的对象 ||类里面的静态代码块 || 非静态代码块|| 无参构造方法 ||有参构造方法 ||类的一般方法等部分
		方法重写:
			方法重写是在继承关系下,子类拥有父类方法名,参数(个数,顺序,类型),返回值类型完全相同,
			访问修饰符只能扩大或相等,不可缩小,但实现过程与父类不同的方法。方法重写也是多态的一种变现方式。
		重写的必要条件:
			1.在子类中可以根据需要对从基类中继承来的方法进行重写;
			2.重写的方法和被重写的方法必须具有相同方法名称,参数列表和返回类型;
			3.重写方法不能使用比被重写的方法更严格的访问权限
		
	多态:在面向对象语言中,多态性是指一个方法可以有多种实现版本,即“一种定义,多种实现”。利用多态可以设计和实现可扩展的系统,
		只要新类也在继承层次中。新的类对程序的通用部分只需进行很少的修改,或不做修改。
		类的多态性表现为方法的多态性,方法的多态性主要有方法重载和方法覆盖。
		方法重载:
			方法重载(overload)是指在同一个类中的多个方法可以同名但参数表必须不同。重载主要表现为同一个类中方法的多态性		

1.2 接口和类的区别

实现:接口必须使用implements来实现接口;类的子类使用extends来继承;
构造函数:类可以有多个构造函数;接口不能有
实现数量:类可以实现多个接口;但只能继承一个类

1.3 Java的基本数据类型

整数类型:byte,short,int,long
浮点类型:float,double
布尔类型:boolean
字符类型:char

1.4 你常用的封装类型主要有哪些

定义:基本类型的封装类的好处是可以在对象中定义更多的功能方法操作该数据
类型:Byte,Short,Integer,Long,Character,Float,Double,Boolean
特殊:String封装类和String类型之间的转换:
		1.String类型转换为封装类型,需要用封装类型的valueOf()方法;
		2.封装转换String类型需要用toString()方法

1.5 String,StringBuffer和StringBuilder的区别

String:String声明的是不可变对象,每次操作都会生成新的String对象,然后将指针指向新的String对象
而StringBuilder和StringBuffer可以在原有对象的基础上进行操作,
所以在经常改变字符串内容的情况下最好不要使用String

StringBuffer和StringBuilder最大的区别在于:StringBuffer是线程安全的,
而StringBuilder是非线程安全的,
但StringBuilder性能高于StringBuffer,所以在单线程的环境下推荐使用StringBuilder,
多线程的情况下推荐使用StringBuffer 

1.6 final的用法

1.final修饰类:
	被final修饰的类将不能被继承,因此该类中的方法斗将不能被覆盖
	在开发此类时,如果确认该类中的所有方法都不会被覆盖,那么就可以将该类用final进行修饰(这种方式采用不多)
		`public final class TestFinal`
2.final修饰方法:
	被final修饰的成员方法将不能被重写,
	(主要作用就是如果该方法不想被其子类对其修改重写,那么就可以对该方法进行final修饰)
	`public final void test(){
		system.out.println("test2");
		}`
3.final修饰变量:
	变量分为三种:静态变量,成员变量,局部变量
	一旦变量被final修饰并且赋予初始值之后,那么该值不能发生改变,被称为常量
4.final修饰参数
	被final修饰的方法参数,可以正常使用,但是不能改变它的值
		`public void test(final int y){
			system.out.println(y);
			}`

2. 集合类

2.1 集合线程安全和线程不安安全的有哪些

线程安全:TreeMap,HashTree,ConcurrentHashMap
非线程安全:ArrayList,LinkedList,set,HashMap
线程安全的集合类比较少的原因是,安全线程非常消耗内存

2.2 Map中HashMap,LinkedMap和TreeMap的区别

HashMap原理:HashMap是基于hash算法实现的,通过put(k,v)存值,get(k)来获取。
当传入k时,HashMap会根据k.hashCode()计算出hash值,根据hash值将v保存在bucket里。
当计算出hash值相同时,我们称之为hash冲突,HashMap的做法是用链表和红黑树存储相同的hash值v。当hash冲突较少时,使用链表,否则使用红黑树。

HashMap最多只允许一条记录的键为null;允许多条记录的值为null。
HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致;
如果需要同步,可以使用Collections的synchronizedMap方法使HashMap具有同步的能力。
LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序。
TreeMap可以用来排序.

LinkedHashMap在于存储数据,若想保持进入的顺序与被取出的数据一致的话,优先考虑LinkedHashMap;
HashMap键只能允许为一条为空,value可以允许为多条为空,键唯一,但只可以多个。

3. 框架

3.1 springMVC的工作流程

1.用户发送请求给DispatcherServlet
2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller
3.DispatcherServlet把请求提交到对应的Controller
4.Controller进行业务逻辑处理后,会返回一个ModelAndView
5.Dispatcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
6.视图对象负责渲染返回给客户端

3.2 SpringMVC和Structs2有什么区别

1.拦截方式:
	Structs2是类级别拦截:
		一个类对应一个request上下文
	SpringMVC是方法级别拦截:
		一个方法对应一个request上下文,而方法同时又跟一个url对应,所以从架构本身上SpringMVC就容易实现restful url,而Structs的架构实现起来比较困难
		因为Structs2中的Action的一个方法对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了
2.数据形式不同:
		SpringMVC的方法之间基本是独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架,方法之间不共享变量
	而Structs2虽然方法之间也是独立的,但其所有Action变量是共享的,每次来一个请求就创建一个Action,一个Action对象对应一个request上下文
3.拦截机制不同:
	SpringMVC是独立的AOP方式,Structs2是自带的Interceptor机制,这样导致Structs2的配置文件量比SpringMVC大
4.在ajax上
	SpringMVC集成了Ajax,使用非常方便,只要一个注解@ResponseBody就可以实现,然后直接返回文本即可
	Structs2拦截器集成了Ajax,在Action中处理一般必须安装插件或者自己手写代码集成进去,使用起来也非常不便
5.在配置上SpringMVC基本100%零配置

3.3 对spring的理解

spring提供ioc技术,容器会帮你管理依赖对象,从而不要自己创建和管理依赖对象了,更轻松的实现了程序的解耦
spring提供了事务的支持,使得事务的操作变的更加方便
spring提供了面向切面编程(aop)这样可以更方便的处理某一类问题

3.4 mybatis中#{}和${}的区别

"#{}是预编译处理,${}是字符替换"
"在使用#{}时,mybatis会将SQL中的#{}替换成"?",配合preparedStatement的set赋值,这样可以有效防止SQL注入,保证程序运行的安全"

3.5 mybtis有几种分页方式

两种:物理分页和逻辑分页
	逻辑分页:使用mybatis自带的RowRounds进行分页,它是一次性查询很多数据,然后在数据中再进行检索
	物理分页:自己手写SQL或者使用分页插件PageHelper,去数据库查询指定条数的分页数据形式

3.6 Spring核心的重要配置
3.7 spring的核心类有哪些,各有什么作用?

BeanFactory:产生一个新的实例,可以实现单例模式
BeanWrapper:提供统一的get及set方法
ApplicationContext:提供框架的实现,包括BeanFactory的所有功能

3.8 spring 常用的注入方式有哪些?

属性注入(Setter注入)
构造方法注入
注解方式注入

4. 异常类

4.1 try-catch-finally中哪些部分可以省略

try-catch-finally其中,catch和finally都可以省略,但是不能同时省略,
也就是说有try的时候,必须后面跟一个catch或者finally。
finally,是try-catch-finally中最后一部分,表示不论发生什么都会执行。
如果finally部分存在,则一定会执行finally里面的代码

4.2 有哪些常见的异常类

classNotFoundException:指定文类不存在
NullPointerException:空指针异常
NumberFormatException:字符串转换为数字异常
IndexOutOfBoundsException:数组下标越界异常
ClassCastException:数据类型转换异常
FileNotFoundException:文件未找到异常
NoSuchMethodException:方法不存在异常
IOException:IO异常
SocketException:Socket异常
SQKException:SQL异常

4.3 throw和throws的区别

throw:是真实抛出一个异常
throws:是声明可能会抛出一个异常

5. 数据库

5.1 oracle的存储过程和存储函数的区别

1.返回值的区别:
	函数有一个返回值,而存储过程是通过参数返回的,可以有多个或者没有
2.调用的区别
	函数可以在查询语句中直接调用,而存储过程必须单独调用
	函数一般情况下是用来计算并返回一个计算结果,
	而存储过程一般是用来完成特定的数据操作,比如修改、插入数据表或者执行返回某些DDL语句等)

5.2 oracle常用哪些函数
Oracle常用的函数命令

概要:
	oracle数据表主要使用两种类型的函数:
		单行函数:操作一行数据,返回一个结果
		聚合函数(多行函数,分组函数,组函数):操作多行函数,返回一个结果
单行函数:		
	1.字符串函数
		CONCAT(X,Y):连接字符串x和y
		LENGTH(X): 返回x的长度
		LOWER(X):x转换成小写
		UPPER(x):x转换成大写
		REPLACE(X,old,new):在x中查找old并替换成new
		LTRIM(X[,TRIM_STR]):把x的左边截去trim_str字符串,省略截去空格
		RTRIM(X[,TRIM_STR]):把x的右边截去trim_str字符串,省略截去空格
		TRIM([TRIM_STR FROM]X):把x的两边截去trim_str字符串,省略截去空格
		SUBSTR(X,start[,length]):返回x的字符串,从start处开始,截取length个字符串,缺省length,默认到结尾
	2.数字函数
		ABS(x):x的绝对值
		CEIL(x):大于或等于x的最小值
		FLOOR(x):小于或大于x的最大值
		MOD(x,y):x除以y的余数
		ROUND(x[,y]):x在y位四舍五入
		TRUNC(x[,y]):x在第y位截断
	3.日期函数
		ADD_MONTHS(d,n):在某一个日期d上,加上指定的月数n,返回计算更新日期
			其中d表示日期,n表示要加的月数
		LAST_DAY(d):返回指定日期当月的最后一天
	4.转换函数
		TO_CHAR(d[n[,fmt]):把日期和数字转换成制定格式的字符串。fmt是格式字符串
		TO_DATE(x[,fmt]):把字符串以fmt格式转换为一个日期
		TO_NUMBER(x[,fmt]):把字符串以fmt格式转换为一个数字
	5.其他函数
		NVL(x,value):如果x为空,返回value,否则返回x
		NVL2(x,value1,value2):如果x非空,返回value1,否则返回value2
聚合函数
	聚合函数同时对一组数据进行操作,返回一行结果。
	AVG(表达式):平均值
	SUM(表达式):求和
	MIN/MAX(表达式):最小值、最大值
	COUNT(表达式):数据统计

5.3 你用过哪些SQL优化
SQL优化的几种方式

1.对查询进行优化,应尽量避免全表扫描,首先应该考虑在where及order by涉及的列上建立索引
2.应尽量避免在where子句中对使用字段进行null判断,否则将导致引擎放弃使用索引而进行全表扫描
3.应尽量避免在where子句中使用!=<>操作符,否则将引擎放弃使用索引而进行全表扫描
4.应尽量避免在where子句中使用or来连接条件,否则将引擎放弃使用索引而进行全表扫描
5.in和not in也要慎用,否则会导致全表扫描
6.下面的查询也将导致全表扫描(like里面的%)
		%放在前面会失效
		`select id from t where name like"%abc%"`
7.应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
8.应尽量避免在where子句中进行函数操作
9.不要再where子句中的“=”左边进行函数、算术运算或者其他表达式运算,否则系统将可能无法正确使用索引
10.很多时候用exists代替in是一个好的选择
11.避免频繁创建和删除临时表,以减少系统表资源的消耗
12.如果使用到临时表,在存储过程的最后务必将所有的临时表显示删除,先truncate 
table,然后drop table,这样避免系统表较长时间的锁定
13.尽量避免使用游标,因为游标效率差,如果游标操作的数据超过1万行,那么就要考虑改写
14.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效
15.尽量避免大事务的操作,提高系统并发能力
16.尽量避免向客户端返回大量数据,若数据量过大,应该考虑相应的需求是否合理

5.4 数据库长时间未响应
可考虑Oracle锁表
Oracle未响应故障
5.5 SQL问题的排查

1.使用show processlist命令查看当前所有连接信息
2.开启慢查询日志,查看慢查询日志
	"查看是否开启慢查询:show variable like'slow_query%';"
3.使用explain命令查询SQL语句执行计划

慢查询日志详情

5.6 乐观锁和悲观锁的区别

乐观锁:每次获取数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下,在此期间别人有没有去更新这条数据
悲观锁:每次获取数据的时候都认为别人会修改,所以每次在获取数据的时候都会上锁,这样别人拿这条数据就会上锁,直到这个锁被释放

数据库乐观锁需要自己实现,在表里面添加一个version字段,每次修改成功值加1,这样每次修改的时候先比对一下,
自己拥有的version和数据库现在的version是否一致,如果不一致就不修改,这样就实现了乐观锁

面试必问:乐观锁和悲观锁

5.7 inner join ,left join和right join的区别

inner join:理解为"有效连接":两张表中都有的数据才会显示
left join:理解为"最左显示"
	如:on a.id=b.id,则显示a表中存在的全部数据及a//b都有的数据,
a中有,b没有的数据以null显示

right join:理解为"最右显示"
	如:on a.id=b.id,则显示b表中存在的全部数据及a//b都有的数据,
b中有,a没有的数据以null显示

一般使用数据库应遵循以下原则:
	1.在做表与表的连接查询时,大表在前,小表在后
	2.不使用表别名,通过字段前缀区分不同的表字段
	3.查询条件的限制条件要写在表连接条件前
	4.尽量使用索引的字段作为查询条件

5.8 你对索引的理解

概念:在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,
它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。

"索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。"
数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。

作用:
	1.快速取数据;
	2.保证数据记录的唯一性;
	3.实现表与表之间的唯一参照;
	4.在使用order by,group by子句进行数据检索时,利用索引可以减少排序和分组的时间
	
优点:
	1.大大加快数据的检索速度
	2.创建唯一索引,保证数据表中每一行数据的唯一性
	3.加速表和表之间的连接
	4.在使用分组和排序子句进行数据检索时,可以有效减少查询中分组和排序的时间
	
缺点:
	1.索引需要占用物理空间
	2.当对表中的数据进行增加,删除和修改的时候,索引也需要动态的进行维护,降低了数据的维护速度
	
索引类型:
	普通索引:最基本的索引类型,没有唯一性之类的限制
		1.创建索引;例如:
	"CREATE INDEX <索引的名字> ON tablename (列的列表);"
		2.修改表,例如:
	"ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);"
		3.创建表的时候指定索引,例如:
	"CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );"
	
	唯一索引:不允许其中任何两行具有相同索引值的索引
		1.创建索引,例如:
	"CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);"
		2.修改表,例如:
	"ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表); "
		3.创建表的时候指定索引,例如:
	"CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );"
	
	主键索引:简称主索引,数据表中一列或列组合(字段)的唯一标识表中的每一行。该列成为主键
	
	聚簇索引:也称为"聚集索引",表中行的物理顺序与键值的逻辑(索引)顺序相同。
	一个表只能包含一个聚簇索引,即如果存在聚簇索引,就不能再指定"CLUSTERED"关键字
	聚簇索引更适合用于对很少对基表进行增删改操作的情况。

	非聚簇索引:也称为"非簇索引",数据表中记录的物理顺序和索引顺序可以不相同。
	一个表只能有一个聚簇索引,但表中的每一列都可以有自己的非聚簇索引。
	
索引的操作:
	1.创建索引:
	"CREATE [UNIQUE] [CLUSTERED| NONCLUSTERED] INDEX <索引名>ON <表名>(<列名>[ASC|DESC] [, <列名>[ASC|DESC]...])"
	2.修改索引:
	"ALTER INDEX <旧引索名字> RENAME TO<新引索名>"
	3.删除索引:
	"DROP INDEX<索引名>",值得注意的是:
	删除索引时,DBMS不仅在物理删除相关的索引数据,也会从数据字典删除有关该索引的描述。
	

你可能感兴趣的:(个人,基础面试,java,sql,mysql)