自己整理的面试题

1、==和equals()的区别
  1. ==是判断两个变量或实例是否指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是否相同;
  2. ==是指对内存地址进行比较,equals()是指对字符串的内容进行比较;
  3. ==指引用是否相同,equals()指的是值是否相同

img

hashCode()作用:**

它返回的是根据对象的内存地址算出的一个值。当集合在添加新的元素时,先调用这个元素的hashcode()方法,就能一下子定位到它应该放在的那个物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用进行比较。如果这个位置上已经有元素了,就调用它的equals()与新元素进行比较,相同就不存了,不相同就散列在其他地址上。这样可以降低使用equals()次数。

ArrayList和LinkedList区别?

两者都是线程不安全的。

ArrayList可以看做是能够自动增长容量的数组;查询速度快,增删元素慢;

LinkedList是一个双链表,在添加和删除元素时具有比ArrayList更好的性能,但在get和set方面弱于ArrayList;所以查询速度慢, 增删元素快;

HashMap和HashTable的区别?

HashTable:key和value都不能为null;

HashMap:key可以为null,但只能有一个这样的key,因为要保证key的唯一性;可以有多个key对应的value为null;

HashMap是线程不安全的,在多线程并发的情况下可能会产生死锁问题。但是它的效率远远高于HashTable,当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。

HashTable是线程安全的,它的每个方法上都有synchronized 关键字,因此可直接用于多线程中。

HashTable默认的初始容量大小为11,之后每次扩容容量为原来的2n+1;

HashMap默认的初始容量大小为16,之后每次扩容容量为原来的2倍。

HashMap解决哈希冲突有较大的变化,当链表长度大于阈值(默认8),将链表转化为红黑树,减少搜索时间。

Collection包结构,与Collections的区别:

Collection是集合类的上级接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;

Collections是集合类的一个帮助类,包含有各种有关集合操作的静态多态方法,用于实现对各种集合的搜索、排序、线程安全化等操作。它不能被实例化。

Java创建对象有几种方式?
  1. new创建新对象
  2. 通过反射机制
  3. 采用clone机制
  4. 通过序列化机制(把Java对象储存在某一地方(硬盘、网络),也就是将对象的内容进行流化)
什么是java反射机制?

java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的所有属性和方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制;

反射实现中主要用到几个对象:Class,Constructor,Field,Method

  1. Class:对于想操作的类对象,首先必须要将转化为一个Class对象然后通过JDK的API进行下一步操作。
  2. Constructor:用来获取及操作对象的构造方法。
  3. Field:用于对目标对象的属性操作。
  4. Method:用于获取目标类的方法及相关操作。
浅拷贝?

就是两个对象引用的是同一个的内存空间,一个改变全部改变。

深拷贝?

就是两个对象,旧对象还是用原来的储存空间。但是新对象就不同了,新对象自己开辟了一个新的空间,自己对自己控制,不再受原来空间的限制。

多线程创建方式:
  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口通过FutureTask包装器来创建Thread线程
  4. 创建线程池(这种方式使用最多)

notify()和notifyAll()有什么区别?

notify()可能会导致线程死锁,notifyAll()则不会;

什么是线程安全?

线程安全就是多个线程访问同一代码,不会产生不确定的结果。

线程安全一般都涉及到synchronized, 就是一段代码同时只能有一个线程来操作 不然中间过程可能会产生不可预制的结果。

synchronized 关键字的了解?

synchronized 解决多个线程之间访问资源的同步性,可以保证被它修饰的方法或代码块在任意时刻只能有一个线程执行。

sleep()和wait()有什么区别?

两者都可以使线程进入阻塞状态;sleep()属于Thread类中的,而wait()属于Object类中的;sleep()会导致线程进入暂时的指定时间,时间到了又会恢复运行状态,sleep()不会释放锁;调用wait(),线程会释放锁,会进入阻塞状态,只有当另一个线程调用notify()或notifyAll()唤醒了才能又恢复运行状态;

线程池的理解:
  1. 可以降低资源消耗。通过重复利用已创建的线程降低创建线程和销毁造成的消耗。
  2. 提高响应效率。当任务到达时,任务可以不需要等到线程创建就能立即执行。
  3. 提高线程的可管理性。
spring IOC和AOP的理解

spring IOC:控制反转,简单来说就是new对象的控制权,被反转到spring框架上。

​ 以前我们实例化一个对象时,都是使用类的构造方法来new一个对象,这个过程是我们自己来控制,而控制反转就是把new对象的工作交给了spring容器。

IOC容器:具有依赖注入功能的容器,可以创建对象的容器。它负责实例化、定位、配置应用程序的对象并建立这些对象之间的依赖。

DI:由IOC容器动态的将某个对象所需的外部资源注入到组件(controller,service等)之中。就是IOC容器会把当前对象所需的外部资源动态的注入给我们。

AOP:也就是面向切面编程。基于IOC,是对oop(面向对象编程)的有效补充,它使用了一种“横切”的技术。就是封装与业务无关的逻辑或职责,但是又和业务一起调用,例如日志工能,这样可以减少系统的重复代码,减少模块之间的耦合度,提高系统的运作性和可维护性。aop具有两个明显的特征,良好的隔离性和代码无关性。

oop将程序分解成各个层次的对象,aop将程序运行过程分解成各个切面。

java设计模式:

代理模式:提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。

好处:在目标对象实现的基础上,增加额外的功能操作,即扩展目标对象的功能。

代理模式例子:假设我们想邀请一位明星,那么并不是直接访问明星,而是联系明星的经纪人,来达到同样的目的。明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决。

单例模式::因进程需要,有时我们只需要某个类同时保留一个对象,不希望有更多的对象,此时应该考虑单例模式的设计。

特点: 1.单例模式只能有一个实例。

​ 2.必须创建自己的唯一实例。

​ 3.必须向其他对象提供这一个实例。

单例模式实现方式之一:懒汉式(线程安全,调用效率不高,但是能延时加载):

public class SingletonDemo2 {
     
    //类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)
    private static SingletonDemo2 instance;
     
    //构造器私有化
    private SingletonDemo2(){}
     
    //方法同步,调用效率低
    public static synchronized SingletonDemo2 getInstance(){
        if(instance==null){
            instance=new SingletonDemo2();
        }
        return instance;
    }
}

之二:饿汉式(线程安全,调用效率高,但是不能延时加载):

public class ImageLoader{ 
    private static ImageLoader instance =  new ImageLoader; 
    
    private ImageLoader(){} 
    
    public static ImageLoader getInstance(){ 
      return instance; 
    } 
}

​ 一上来就把单例对象创建出来了,要用的时候直接返回即可,这种可以说是单例模式中最简单的一种实现方式。但是问题也比较明显。单例在还没有使用到的时候,初始化就已经完成了。也就是说,如果程序从头到位都没使用这个单例的话,单例的对象还是会创建。这就造成了不必要的资源浪费。所以不推荐这种实现方式。

什么是spring?

spring是一个轻量级的IOC和aop容器框架。目的是为了简化企业应用程序的开发,使开发者只需要关心业务的需求。

spring和springboot区别?

Spring Boot基本上是Spring框架的扩展,它消除了设置Spring应用程序所需的复杂例行配置。目标和Spring的目标是一致的,为更快,更高效为应用程序进行开发。

Spring Boot只是Spring本身的扩展,使开发,测试和部署更加方便。

19、什么是springMVC?

是一个MVC开源框架,是spring的一个后续产品,就是在spring原有基础上,提供了web应用的MVC模块。可以简单的把springMVC理解为是spring的一个模块。

springMVC原理图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0dyPEwq8-1593315454786)(C:\Users\xiaozhu\AppData\Roaming\Typora\typora-user-images\image-20200626205300265.png)]

  1. 用户发送请求到前端控制器;
  2. 前端控制器接收请求调用处理器映射器;处理器映射器找到具体的处理器(可以根据xml,注解进行查找),生成处理器对象以及处理器拦截器对象(如果有的话)返回给前端控制器;
  3. 前端控制器调用处理器适配器;处理器适配器调用后端控制器(controller);
  4. controller执行完返回ModelAndView;
  5. 处理器适配器将controller执行结果ModelAndView返回给前端控制器;
  6. 前端控制器将ModelAndView传给视图解析器;
  7. 试图解析器解析后返回view给前端控制器;
  8. 前端控制根据view进行渲染视图;
  9. 前端控制器响应结果给用户;

**前端控制器(DispatcherServlet):**接收结果,响应请求。(相当于电脑CPU)

**处理器映射器(HandlerMapping):**根据URL查看处理器

**处理器(Handler):**需要程序员写代码处理逻辑的

**处理器适配器(HandlerAdapter):**把处理器包装成适配器,这样可以支持多种类 型的处理器;

**视图解析器:**进行视图解析,多返回字符串,进行处理,可以解析成对应的页面;

20、mybatis分页原理:
  1. 逻辑分页:mybatis是通过我们设置的RowBounds来返回分页结果的。

    原理:首先将所有结果查询出来,然后通过计算offset和limit,只返回部分结果,操作在内存当中进行,也称为内存分页。

  2. 物理分页:直接在sql中添加limit

**分页插件的原理:**是使用mybatis提供的插件接口,实现自定义分页,在插件的拦截方法内拦截待执行的sql,然后重写sql,添加对应的物理分页语句和物理分页参数;

21、mybatis一、二级缓存:

一级缓存:缓存机制是hashmap存储数据。存储作用域是sqlsession。在操作数据库时需要构建sqlsession对象。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

二级缓存:缓存机制是hashmap存储数据。存储作用域是针对mapper级别进行缓存。使用二级缓存需要类实现Serializable序列化接口。

22、mysql三大范式:

范式是符合某一种设计要求的总结。

  1. 第一范式:保证列的原子性,保证列不可再分。
  2. 第二范式:唯一性 ;一个表只说明一个事物;有主键且非主键依赖主键;
  3. 第三范式:每列都与主键有直接关系,不存在传递依赖;

三大范式是一级一级依赖的。

23、数据库常用引擎有哪些?

MYISAM、Innodb、Memory、MERGE

  • Innodb:行级锁,提供了具有提交、回滚和崩溃回复能力的事务安全,支持自动增长列,支持事务,支持外键约束,并发能力强。处理效率相对差一些。
  • MYISAM:全表锁,较高的执行速度,不支持事务,不支持外键,并发能力差,占用空间相对较小,对事务完整性没有要求。
  • Memory:全表锁,存储在内容中,速度快。数据在mysql重启时会丢失。
  • MERGE是一组MYISAM表的组合。
24、MYISAM和Innodb的区别?
  1. Innodb支持事务,MYISAM不支持;
  2. Innodb支持外键约束,MYISAM不支持外键;
  3. Innodb是聚集索引,数据和索引是绑定在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询主键,然后在通过主键查询到数据。效率比MYISAM低。
  4. MYISAM是非聚集索引,数据文件是分离的,索引保存的数据文件是指针。主键索引和辅助索引是独立的。
  5. Innodb不保存表的具体行数。MYISAM用一个变量保存整个表的行数,执行速度比Innodb快。
  6. Innodb不支持全文索引,MYISAM支持全文索引,查询效率比Innodb高。
25、什么是事务?

多条sql语句执行,要么全部成功,要么全部失败。

事务的特性:ACID

  • A(原子性):事务包含的操作都成功,整个事务才会提交。任何一个操作失败,已经执行中的操作都必须撤销,让数据库返回初始状态。
  • C(一致性):事务操作成功后,数据库所处于的状态和它的业务规则是一致的,即数据不会被破坏。如:A转账100给B,不管操作是否成功,AB的总额是不变的。
  • I(隔离性):在并发操作数据时,不同的事务拥有各自的操作空间,彼此的操作不会产生干扰。
  • D(持久性):一旦事务提交成功,事务的所有操作都必须持久化到数据库中。
26、索引问题:

索引就是加快检索表中数据的方法。在数据库中,索引允许数据库程序迅速找到表中的数据,而不必扫描整个数据库。

  • 主键索引
  • 唯一索引
  • 普通索引
  • 全文索引
27、索引原理?

B+ tree

索引不是越多越好,创建索引需要耗费资源,一是增加了数据库的存储空间,二是在插入和删除时要花费较多的时间维护索引

  • 索引加快数据库的检索速度
  • 降低了增删改等维护任务的速度
  • 唯一索引可以确保每一行数据的唯一性
  • 通过使用索引,提高系统的性能
  • 索引需要占用物理和数据空间
28、并发事务带来的问题?
  1. 脏读:当A事务访问数据进行了修改,但修改之后还没有提交,这时B事务也访问了该数据。因为这个数据时还没有提交的数据,所以B事务读到的数据是"脏数据"。
  2. 丢失修改:当A事务读取一个数据时,另外B事务也访问了该数据,A事务修改了该数据后,B事务也修改了该数据。这样A事务修改的结果就会丢失。
  3. 不可重复性:当A事务多次读取一个数据,并且还没有结束时,B事务也访问了该数据,那么在A事务连续读取数据之间,B事务修改导致A事务两次读取的数据可能不一样。这就发生了一个事务内两次读取的数据时不一样的。
  4. 幻读:跟不可重复读类似。它发生在A事务读取了几行数据,接着B事务插入了一些数据。在随后的查询中,A事务就会发现多了一些原本不存在的记录。
29、事务隔离级别?
  • 读取未提交(read-uncommitted):最低的隔离机制。允许读取其他事务未提交的数据变化。可能会出现脏读,不可重复读,幻读。
  • 已提交读(read-committed):允许读取并发事务已经提交的数据。可以阻止脏读,但是幻读、不可重复读有可能发生。
  • 可重复读(repetable-read):对同一字段的多次读取结果都是一致的,除非数据是被本身事务所修改。可以阻止脏读、不可重读读,但是幻读还是可能发生。(mysql默认隔离机制)
  • 可串行化(serializable):最高的隔离机制。强制事务串行执行,完全服从ACID隔离级别。事务之间互不干扰。避免了幻读、不可重复读、脏读现象。
30、大表如何优化?
  1. 限定数据的范围。务必禁止不带任何限制数据范围的查询数据。

  2. 读/写分离。数据库拆分方案:主库负责写,从库负责读。

  3. 垂直分区垂直拆分就是把数据表列进行拆分,把一张列比较多的表拆分为多张表。

    优点:简化表的结构,易于维护。

    缺点:主键出现冗余,让事务变得复杂。

  4. 水平分区保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或库中,达到了分布式的目的。水平拆分可以支撑非常大的数据量。水平拆分最好分库尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度。

    • 数据分片两种常见方案:

      客户端代理:分片逻辑应用端,封装在jar包中,通过修改或者封装JDBC层来实现。

    • 中间件代理:在应用层和数据中间加一个代理层。分片逻辑统一维护在中间件服务中。例如用Mycat。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值