最近有很多小伙伴们问小编,后端开发面试一般会问什么?小编这里立马就整理了一些后端开发会经常问到的面试题,快一起来看看吧。
一、使用Spring框架的好处是什么?
轻量:Spring是轻量的,基本的版本大约2MB
控制反转(IOC):Spring通过控制反转实现类松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
面向切面的编程(AOP):Spring支持面向切面的编程,并且把业务逻辑和系统服务分开。
容器:spring包含并管理应用中对象的生命周期和配置。
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务。
异常处理:Spring提供方便的API把具体技术相关的异常转换为一致的unchecked异常。
二、Java工厂模式和Spring IOC的区别在哪?
Java工厂是在工厂中修改,在工厂中修改就要重修编译工厂类,重新编译的话就要先停了JVM再重新启动。
Spring IOC是热插拔的,在XML中直接修改,修改xmlspring就会立即发现你改动了XML,会再重新读一遍XML,就会发现新改动了,根本不用重新启动JVM。
三、ORM框架(Object relation mapping)有什么概念?
ORM对象关系映射关系,面向对象的对象模型和关系型数据之间的相互转换。
Hibernate和Mybatis都是常用的ORM框架,两者区别:
1.mybatis手写SQL,而hibernate提供映射机制,开发人员无需担心。
2.mybatis控制更细粒度,但可移植型差,hibernate开发DAO很简单,可移植性好。
3.hibernate拥有完整的日志系统,mybatis则欠缺一些
4. mybatis相比hibernate需要关心很多细节
5. sql直接优化上,mybatis要比hibernate方便很多
四、数据库事务的四大特性及事务隔离级别是什么?
1.事务的四大特性:
原子性(Atomicity):事务包含的所有操作要么全部成功,要么全部失败回滚。
一致性(Consistency):一个事务执行之前和执行之后都必须处于一致性状态。
隔离性(Isolation):当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性(Durability):一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
2.事务隔离:
更新丢失:两事务同时更新,一个失败回滚覆盖另一个事务的更新。
脏读:事务T1读取到事务T2修改了但是还未提交的数据,之后事务T2又回滚其更新操作,导致事务T1读到的是脏数据。
不可重复读:事务T1读取某个数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
虚读(幻读):事务T1读取在读取某范围数据时,事务T2又插入一条数据,当事务T1再次数据这个范围数据时发现不一样了,出现了一些“幻影行”。
不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
幻读和不可重复读的异同:都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
3.事务隔离的级别:
读未提交(1000):只限制同一数据写事务禁止其他写事务。解决”更新丢失”。
读已提交(1100):只限制同一数据写事务禁止其它读写事务。解决”脏读”,以及”更新丢失”。
可重复读(1110):限制同一数据写事务禁止其他读写事务,读事务禁止其它写事务(允许读)。解决”不可重复读”,以及”更新丢失”和”脏读”。
串行化(1111):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
五、假设有一张用户表,正常的表只能存放大概一千万或是两千万左右的数据,但是有上亿的用户?怎么存储?
横向分割或者纵向分割。
不太严格的将,对于海量数据的数据库,如果是因为表多而数据多,这时候适合垂直切分,即把关系紧密的(比如同一模块)的表切分出来出来放在一个servlet上。如果对于表并不多,但每张表的数据非常多,这时候就适合水平切分,即把表的数据按某种规则切分到对个数据库(server)上。
可以横向分割,把表分割成多个表然后分布式存储。
六、库函数和系统调用是什么?
1.系统调用是为了方便应用使用操作系统的接口,而库函数是为了方便入门编写应用程序而引出的,比如自己编写一个函数其实也可以说是一个库函数,
2.系统调用可以理解为内核提供给我们在用户态的接口函数,可以认为是某种内核的库函数。
3.read()函数是系统调用,而fread()函数是C标准库函数。
七、Java设计模式有哪些?
创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。
行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
八、讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序。
父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
结论:对象初始化的顺序,先静态方法,再构造方法,每个又是先基类后子类
父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
父类构造方法
子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
子类构造方法
九、请你讲述数组和链表数据结构之间各自的时间复杂度。
数组,是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少插入和删除元素,就应该用数组。
链表 中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存储 数据元素 的 数据域,另一个是存储下一个结点地址的 指针。
如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表。
内存存储区别
数组从栈中分配空间, 对于程序员方便快速,但自由度小。
链表从堆中分配空间, 自由度大但申请管理比较麻烦.
逻辑结构区别
数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。
链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项)
总结
存取方式上,数组可以顺序存取或者随机存取,而链表只能顺序存取;
存储位置上,数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定;
存储空间上,链表由于带有指针域,存储密度不如数组大;
按序号查找时,数组可以随机访问,时间复杂度为O(1),而链表不支持随机访问,平均需要O(n);
按值查找时,若数组无序,数组和链表时间复杂度均为O(1),但是当数组有序时,可以采用折半查找将时间复杂度降为O(logn);
插入和删除时,数组平均需要移动n/2个元素,而链表只需修改指针即可;
空间分配方面:
数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败;
链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效;
以上就是整理的一些关于后端开发的面试题了,如果你还想要了解更多相关的java面试题内容就快快关注我们网站吧。
推荐阅读: