一、谈谈对面向对象的理解
含义:
首先面向对象不是面向过程,我们可以从组织者的方向去理解面向对象,面向对象从广义上可以理解为自己是一个组织着,比如一个项目需要做一个数据库或者做一个连接池,
面向对象的角度看的话,是找一个网络上流行的东西直接使用或者找人帮我完成这个步骤;
面向过程的角度看的话,是写一个数据库或者连接池,或者是自己把这件事完成。
同样都是完成这件事,面向过程是执行者,但是面向对象是组织者,它更多关心的是我应该找谁帮我做这件事,这样我们就可以把更多的精力放在组织架构上。
三大特性:
封装:
狭义上的封装是一个类上的所有属性全部私有化,然后对外提供get、set方法
广义上的封装可以是比如使用一个连接池,我们封装连接池内部的实现,使用连接池的人只需要知道如何使用,不用了解这个连接池如何运行的。这也是一种封装
继承:
复用,共性的东西向上提取,父类把共性的东西处理好了,到子类只需要写一些特性的东西,不需要重复劳动。
多态:父类引用指向不同的子类对象 eg:接口的出现,接口就是我们的父类,接口背后是不同的实现,这会有一个解耦,和其他程序对接的话也是接口对接的。
二、JDK,JRE,JVM的联系
jdk 全称java development kit是java开发工具,是给java开发人员使用的
jre 全称java runtime environment 是java运行时环境
jvm全称java Virtual machine 是java虚拟机
jre包下的文件夹核心文件夹,bin文件夹就是jvm,lib文件夹就是类库,而可以认为bin+lib其实就是jre,而jdk可以认为就是jre+Java工具。
三、==和equals
equals在其他情况和==没有区别,但是要看equals是否会重写,重写可能比较的是引用后的值(eq:string),而且这类问题要深入了解jvm内存分配(堆栈)。
四、String创建对象个数讨论
- 1
五、string、stringbuffer以及stringbuild的区别和使用场景
string是被final修饰的,本身不可变的,每次操作都会产生新的对象
stringbuffer是线程安全的(很少使用)
stringbuild是线程不安全的,但是性能最强,经常使用。
面试回答直接回答stringbuild即可,不要回答不考虑性能时用stringbuffer,不考虑安全时用stringbuild,因为真正开发不可能不考虑性能也不可能不考虑安全的,肯定都需要考虑的,所以现在用的最多的解决方案是用stringbuild自己根据业务代码考虑安全性
六、重载和重写的区别
注意:重载和返回值没有关系,下面方法会在编译期间就会报错
七、接口和抽象类
基础:
1,接口可以被多实现,而抽象类只能被单继承
2,接口的方法都是public abstract,抽象类的话可以是任何方法(jdk8以后接口也可以写普通方法)
3,接口的成员变量只能是public static final类型的,抽象类的成员变量可以是任何类型的
深入:
1,接口的设计目的,是对类的行为进行约束的
2,抽象类的设计目的,是代码的复用。抽象类的存在是先有子类后有父类,父类是抽调子类的共性,不能实例化。
3,使用场景:当你关注事情本身的时候,用抽象类;当我们关心的是事务的方法的时候,用接口。
八、List和Set
注意:会问到底层的问题,还有set取出元素需要用iterator迭代器取出,而list可以直接get下标。
九、HashCode和equals
equals不重写的话就是==;重写equals重写对比规则;
HashCode()的方法返回一个int整数——是哈希码,用于找到在堆中的位置。hashCode()定义在Object中,所以任何类都有这个函数。
hashCode可以让equals的次数减少,提高执行效率!!
十、ArrayList和LinkedList的区别
ArrayList:基于数组存储,在申请内存中是连续存储的,它适合下标访问(这个和数组有关,因为数组中存储的元素的类型是一致的,又是连续的,直接元素的长度乘以查询的节点就可以得到),导致它的查询十分迅速,扩容机制:因为ArrayList又称为动态数组,它创建的时候就会定义一个大小来存储数据,如果超出数组大小新增一条数据时,会新建一个新的数组,把原来的值放入数组中,同时采用尾插法,把新的数据接在后面。如果牺牲空间获取时间,数组设置偏大,同时采用尾插法,插入性能甚至超过LinkedList(新增时会创建大量的Node对象)。
LinkedList:基于链表存储,可以分配到没有连接的内存地址中去,适合做数据的插入和删除操作,但是遍历linkedList十分麻烦,它必须要用iterator遍历,不能用for(for遍历,内部获取元素用的是get(i)的下标获取,而且链表用下标获取的话会从头遍历,很浪费性能),同时最好不要用IndexOf返回元素索引,因为当结果为空时会遍历整个列表,性能极低。
十一、Java常见的数据结构
Connection -> Connections
Connection -> Set(HashSet、LinkedHashSet)
Connection -> List(LinkedList、ArrayList)
基于Array的List(Vector,ArrayList)适合查询,而LinkedList 适合添加,删除操作
Set同List都实现了Collection接口,但是他们的实现方式却大不一样。
List基本上都是以Array为基础。
但是Set则是在 HashMap的基础上来实现的,这个就是Set和List的根本区别。
HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。
看看 HashSet的add(Object obj)方法的实现就可以一目了然了。
Map ->TreeMap
Map ->HashMap
线性表(ArrayList)
链表(LinkedList)
栈(Stack)
队列(Queue)
图(Map)
树(Tree)
十二、Char类型能不能转成int类型?能不能转化成string类型,能不能转成double类型
Char在java中也是比较特殊的类型,它的int值从1开始,一共有2的16次方个数据;Char<int<long<float<double;Char类型可以隐式转成int,double类型,但是不能隐式转换成string;如果char类型转成byte,short类型的时候,需要强转。
十四、针对浮点型数据运算出现的误差的问题,你怎么解决?
使用Bigdecimal类进行浮点型数据的运算
十五、final的作用以及为什么局部内部类和匿名内部类只能访问局部的final对象
- 2
十六、单例设计模式–懒汉式
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (instance==null){
instance= new Singleton;
}
return instance;
}
}
十七、&和&&的区别
&是位运算符。&&是布尔逻辑运算符,在进行逻辑判断时用&处理的前面为false后面的内容仍需处理,用&&处理的前面为false不再处理后面的内容。
十八、关于数据库连接池或者JDBC相关连问
JDBC操作的步骤
加载数据库驱动类
打开数据库连接
执行sql语句
处理返回结果
关闭资源
在使用jdbc的时候,如何防止出现sql注入的问题
使用PreparedStatement类,而不是使用Statement类
怎么在JDBC内调用一个存储过程
使用CallableStatement
使用 Statement 对象执行语句:
> 创建statement:
> Statement 接口提供了三种执行 SQL 语句的方法:
> executeQuery、executeUpdate 和execute。
> 使用哪一个方法由 SQL 语句所产生的内容决定。
方法 executeQuery:
用于产生单个结果集的语句,例如 SELECT 语句。
方法 executeUpdate :
用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQLDDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。
方法 execute:
用于执行返回多个结果集、多个更新计数或二者组合的语句。因为多数程序员不会需要该高级功能,所以本概述后面将在单独一节中对其进行介绍。
Statement 对象用于将 SQL 语句发送到数据库中。
statement-相关概述
实际上有三种 Statement 对象,它们都作为在给定连接上执行 SQL语句的包容器:
Statement、PreparedStatement(它从 Statement 继承而来)
和CallableStatement(它从 PreparedStatement 继承而来)。
它们都专用于发送特定类型的 SQL 语句:
Statement 对象用于执行不带参数的简单 SQL 语句;
PreparedStatement 对象用于执行带或不带 IN参数的预编译 SQL 语句;
CallableStatement 对象用于执行对数据库已存储过程的调用。
Statement 接口提供了执行语句和获取结果的基本方法。
PreparedStatement 接口添加了处理 IN 参数的方法;而CallableStatement 添加了处理 OUT 参数的方法。
有些 DBMS将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用commit 方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。
4、关闭 Statement 对象:
Statement 对象将由 Java 垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要 Statement对象时显式地关闭它们。这将立即释放 DBMS 资源,有助于避免潜在的内存问题。
是否了解连接池,使用连接池有什么好处?
数据库连接是非常消耗资源的,影响到程序的性能指标。连接池是用来分配、管理、释放数据库连接的,可以使应用程序重复使用同一个数据库连接,而不是每次都创建一个新的数据库连接。通过释放空闲时间较长的数据库连接避免数据库因为创建太多的连接而造成的连接遗漏问题,提高了程序性能。
你所了解的数据源技术有那些?使用数据源有什么好处?
Dbcp,c3p0等,用的最多还是c3p0,因为c3p0比dbcp更加稳定,安全;通过配置文件的形式来维护数据库信息,而不是通过硬编码。当连接的数据库信息发生改变时,不需要再更改程序代码就实现了数据库信息的更新。
十九、HashMap,HashTable,ConcurrentHashmap的区别
首先确定一个点就是代码中尽量使用ConcurrentHashMap。
1. HashMap与HashTable的区别:
HashMap是非线程安全的,HashTable是线程安全的,HashTable中的很多方法都是加了sysnchronized关键字的,确保了方法的同步;
2. HashTable和ConcurrentHashMap的区别:
在进行迭代时,HashTable会锁住整个Map,而ConcurrentHashMap只锁住Map的一部分,所以ConcurrentHashMap在多线程环境下的性能更好。
二十、如何实现一个IOC容器
可参考spring ,spring的核心就是IOC。
二十一、线程的生命周期,线程有那些状态
新建,就绪,运行,阻塞,死亡
新建就是创建一个线程,就绪就是创建后其线程调用start的方法,线程到可运行线程池中,等待CPU的调用,然后线程等到CPU调用就是运行状态,运行时CPU被其他线程占用,我这个线程就变为阻塞状态了,等到线程再进入就绪状态,再到运行状态然后运行完成就到死亡状态。(还有一种死亡状态就是线程异常后调用close方法也是直接进入死亡状态)
二十二、什么是锁池,什么是等待池
二十三、sleep(),wait(),join(),yield()的区别
sleep和wait的区别:
sleep在线程中使用,时间结束后自动唤醒;wait不带参数只能用在synchronized内;
yield()和join()用法:
yield(),A.yield()时,会释放A线程调用的CPU,重新判断CPU执行哪个线程,A线程进入的时就绪状态;
join(),当A线程内有B.join()时,会立刻调用B线程,然后等B结束后调用A;
二十四、并发,并行,串行;
并发:两个或多个任务,交替执行。同一时间只要一个任务运行;
并行:两个任务同时执行,同一时间有多个任务正在执行,多个任务之间相互无关且不干扰;
串行:相当于队列,同一时间只有一个任务正在执行,其他任务等待该任务执行完然后执行;
二十五、并发的三大特性:
原子性
可见性
有序性
二十六、Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?
Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,
执行原理是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。
Mybatis 提供了 9 种动态 sql 标签:
trim | where | set | foreach | if
| choose| when | otherwise | bind。
二十七、private default protected public的级别是递增的。
private:本类可见(只能 在本类中调用)。子类继承后也不可见。
default:同包内所有类可见,跨包不可见。在同一个包中所有类都能调用。跨包后所有类都不可见,子类也不可见。
protected:同包内所有类可见,跨包时只有在子类内部可见,外部不可见。相当于这种情况,method在父类中是proteocted的,跨包被子类继承后,子类的method方法的修饰符变为了private。
public:所有类都可见,不管跨不跨包。没有限制。
总结: - private----本类可见。
-
default----本包可见。
-
protected-跨包时子类内部可见。
-
public-----所有包可见。