得分点 :地址空间、开销、并发性、内存
标准回答 :进程和线程的主要差别在于它们是不同的操作系统资源管理方式。
1.进程有独立的地址空间,线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间;
1).一个线程可以多个协程,一个进程也可以单独拥有多个协程。
2) 线程进程都是同步机制,而协程则是异步。
3)协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。
4)线程是抢占式,而协程是非抢占式的,所以需要用户自己释放使用权来切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程的能力。
5)协程并不是取代线程, 而且抽象于线程之上, 线程是被分割的CPU资源, 协程是组织好的代码流程, 协程需要线程来承载运行,
线程是协程的资源, 但协程不会直接使用线程, 协程直接利用的是执行器(Interceptor), 执行器可以关联任意线程或线程池,
可以使当前线程, UI线程, 或新建新程.。 6)线程是协程的资源。协程通过Interceptor来间接使用线程这个资源。
解题思路
得分点 :检索效率、存储资源、索引维护
标准回答: 索引就像指向表行的指针,是一种允许查询操作快速确定哪些行符合WHERE子句中的条件,并检索到这些行的其他列值的数据结构;
索引主要有普通索引、唯一索引、主键索引、外键索引、全文索引、复合索引几种;
在大数据量的查询中,合理使用索引的优点非常明显,不仅能大幅提高匹配where条件的检索效率,还能用于排序和分组操作的加速。 当时索引如果使用不当也有比较大的坏处:比如索引必定会增加存储资源的消耗;同时也增大了插入、更新和删除操作的维护成本,因为每个增删改操作后相应列的索引都必须被更新。
加分回答:只要创建了索引,就一定会走索引吗? 不一定。 比如,在使用组合索引的时候,如果没有遵从“最左前缀”的原则进行搜索,则索引是不起作用的。 举例,假设在id、name、age字段上已经成功建立了一个名为MultiIdx的组合索引。索引行中按id、name、age的顺序存放,索引可以搜索id、(id,name)、(id, name, age)字段组合。如果列不构成索引最左面的前缀,那么MySQL不能使用局部索引,如(age)或者(name,age)组合则不能使用该索引查询。
解题思路
得分点 :线程和进程的关系、为什么使用多线程
标准回答
线程是操作系统调度的最小单元,它可以让一个进程并发地处理多个任务,也叫轻量级进程。所以,在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈、局部变量,并且能够共享进程内的资源。
由于共享资源,处理器便可以在这些线程之间快速切换,从而让使用者感觉这些线程在同时执行。 总的来说,操作系统可以同时执行多个任务,每个任务就是一个进程。进程可以同时执行多个任务,每个任务就是一个线程。一个程序运行之后至少有一个进程,而一个进程可以包含多个线程,但至少要包含一个线程。 使用多线会给开发人员带来显著的好处,而使用多线程的原因主要有以下几点:
1.更多的CPU核心现代计算机处理器性能的提升方式,已经从追求更高的主频向追求更多的核心发展,所以处理器的核心数量会越来越多,充分地利用处理器的核心则会显著地提高程序的性能。而程序使用多线程技术,就可以将计算逻辑分配到多个处理器核心上,显著减少程序的处理时间,从而随着更多处理器核心的加入而变得更有效率。
解题思路
得分点 原子类、volatile、锁
标准回答
Java保证线程安全的方式有很多,其中较为常用的有三种,按照资源占用情况由轻到重排列,这三种保证线程安全的方式分别是原子类、volatile、锁。
得分点 争夺共享资源、相互等待、互斥条件、请求和保持条件、不剥夺条件、环路等待条件
标准回答:
得分点 管道、命名管道、信号、消息队列、共享内存、内存映射、信号量、Socket
标准答案 进程间通信主要包括:管道、命名管道、信号、消息队列、共享内存、内存映射、信号量、Socket
得分点 mvc概念,model、view、controller模块功能
标准回答 MVC是一种设计模式,在这种模式下软件被分为三层,即Model(模型)、View(视图)、Controller(控制器)。
Model代表的是数据,View代表的是用户界面,Controller代表的是数据的处理逻辑,它是Model和View这两层的桥梁。
将软件分层的好处是,可以将对象之间的耦合度降低,便于代码的维护。
加分回答 为了解耦以及提升代码的可维护性,服务端开发一般会对代码进行分层,服务端代码一般会分为三层:表现层、业务层、数据访问层。在浏览器访问服务器时,请求会先到达表现层最典型的MVC就是jsp+servlet+javabean模式。 以JavaBean作为模型,既可以作为数据模型来封装业务数据,又可以作为业务逻辑模型来包含应用的业务操作。 JSP作为视图层,负责提供页面为用户展示数据,提供相应的表单(Form)来用于用户的请求,并在适当的时候(点击按钮)向控制器发出请求来请求模型进行更新。 Serlvet作为控制器,用来接收用户提交的请求,然后获取请求中的数据,将之转换为业务模型需要的数据模型,然后调用业务模型相应的业务方法进行更新,同时根据业务执行结果来选择要返回的视图。 当然,这种方式现在已经不那么流行了,Spring MVC框架已经成为了MVC模式的最主流实现。 Spring MVC框架是基于Java的实现了MVC框架模式的请求驱动类型的轻量级框架。前端控制器是DispatcherServlet接口实现类,映射处理器是HandlerMapping接口实现类,视图解析器是ViewResolver接口实现类,页面控制器是Controller接口实现类
得分点 Redis5种数据结构
标准回答
Redis主要提供了5种数据结构:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。
Redis还提供了Bitmap、HyperLogLog、Geo类型,但这些类型都是基于上述核心数据类型实现的。5.0版本中,Redis新增加了Streams数据类型,它是一个功能强大的、支持多播的、可持久化的消息队列。 string可以存储字符串、数字和二进制数据,除了值可以是String以外,所有的键也可以是string,string最大可以存储大小为2M的数据。 list保证数据线性有序且元素可重复,它支持lpush、blpush、rpop、brpop等操作,可以当作简单的消息队列使用,一个list最多可以存储232-1个元素 hash的值本身也是一个键值对结构,最多能存储232-1个元素 set是无序不可重复的,它支持多个set求交集、并集、差集,适合实现共同关注之类的需求,一个set最多可以存储232-1个元素 zset是有序不可重复的,它通过给每个元素设置一个分数来作为排序的依据,一个zset最多可以存储232-1个元素。 加分回答 每种类型支持多个编码,每一种编码采取一个特殊的结构来实现 各类数据结构内部的编码及结构: string:编码分为int、raw、embstr;int底层实现为long,当数据为整数型并且可以用long类型表示时可以用long存储;embstr底层实现为占一块内存的SDS结构,当数据为长度不超过32字节的字符串时,选择以此结构连续存储元数据和值;raw底层实现为占两块内存的SDS,用于存储长度超过32字节的字符串数据,此时会在两块内存中分别存储元数据和值。 list:编码分为ziplist、linkedlist和quicklist(3.2以前版本没有quicklist)。ziplist底层实现为压缩列表,当元素数量小于2且所有元素长度都小于64字节时,使用这种结构来存储;linkedlist底层实现为双端链表,当数据不符合ziplist条件时,使用这种结构存储;3.2版本之后list一般采用quicklist的快速列表结构来代替前两种。 hash:编码分为ziplist、hashtable两种,其中ziplist底层实现为压缩列表,当键值对数量小于2,并且所有的键值长度都小于64字节时使用这种结构进行存储;hashtable底层实现为字典,当不符合压缩列表存储条件时,使用字典进行存储。 set:编码分为inset和hashtable,intset底层实现为整数集合,当所有元素都是整数值且数量不超过2个时使用该结构存储,否则使用字典结构存储。 zset:编码分为ziplist和skiplist,当元素数量小于128,并且每个元素长度都小于64字节时,使用ziplist压缩列表结构存储,否则使用skiplist的字典+跳表的结构存储。
得分点 乐观锁、悲观锁定义及使用场景
标准回答
得分点 单例模式、工厂模式
标准回答
创建型包括:单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式;
结构型包括:代理模式、装饰模式、适配器模式、组合模式、桥梁模式、外观模式和享元模式;
行为型包括:模板方法模式、命令模式、责任链模式、策略模式、迭代器模式、中介者模式、观察者模式、备忘录模式、访问者模式、状态模式和解释器模式。
面试中不要求23种设计模式全部了解,但至少应掌握单例模式和工厂模式。
加分回答 可以说出知道的框架所用到的设计模式或底层设计模式,例如Spring中的单例模式、工厂模式,AQS的模板模式等等。
得分点 AOP概念、AOP作用、AOP的实现方式
标准回答 AOP( aspect oriented programming)是一种是面向切面编程,是通过预编译方式和运行期动态代理的方式实现不修改源代码的情况下给程序动态统一添加功能的技术。
AOP 有切面,连接点,通知,切点。 aop是基于动态代理的技术,在程序运行的时候,动态的修改class字节码生成新的class文件进行运行的技术,可以对某个类的某个方法、多个类的多个方法,通过配置切点表达式进行匹配,然后改造被匹配到的类的某一些方法,然后运行;动态代理已知两种,cjlib的基于子类的动态代理,jdk自带的基于接口的动态代理。 常见的aop使用场景,日志统一管理,事务管理器。
得分点 RDB、AOF
标准回答 Redis4.0之后,Redis有RDB持久化、AOF持久化、RDB-AOF混合持久化这三种持久化方式。
reids的持久化方式有两种:RDB和AOF RDB:它是通过数据集快照的方式来记录redis中的所有数据,在某个时间段内,将数据写入一个临时文件中,持久化结束,用这个临时文件替换上次的持久化文件,达到数据恢复。好处:只有一个dump.rdb文件,便于存储,容灾性较好,性能最大化,子进程来完成写操作,主进程继续处理命令。缺点:数据安全性低,RDB是隔一段时间进行一次备份,在此期间,如果发生了异常,可能导致数据的不完整性。 AOF:它是通过记录redis的所有命令,每执行一次就记录一次数据,保存在AOF文件中。优点:保证了数据的安全性和完整性,即便是中途宕机,也可以恢复过来。缺点:他的文件比RDB文件大,如果是数据集大的时候,他的恢复速度比RDB文件慢,启动速度也慢。 Redis默认是用RDB文件存储。
得分点 饿汉式单例模式、懒汉式单例模式、线程安全的懒汉式单例模式
标准回答 单例模式(Singleton
Pattern)是最简单的创建型设计模式。它会确保一个类只有一个实例存在。单例模式最重要的特点就是构造函数私有,从而避免外界直接使用构造函数直接实例化该类的对象。
单例模式在Java种通常有两种表现形式:
-
public class Singleton{
// 构造方法私有,确保外界不能直接实例化
private static Singleton instance = new Singleton();
//保证私有,这样该类就不可以被实例化
private Singleton(){ }
//有一个唯一可以访问对象的方法
public static Singleton getInstance(){
return instance;
}
public void doSomething() {
System.out.println("Do Something");
}
//调用
public static void main(String[] args) {
// 正确获取唯一单例方式
Singleton instance = Singleton.getInstance();
// 用单例做一些事情
instance.doSomething();
}
}
懒汉式单例模式: 类在加载时不会初始化静态变量instance,而是在第一次被调用时将自己初始化
public class LazySingleton {
// 私有构造方法,确保外界不能直接实例化。
private static LazySingleton instance = null;
// 构造方法私有,保证自身初始化
private LazySingleton() {}
//提供一个唯一的访问方法
public static LazySingleton getInstace() {
// 此处会有线程问题,如果线程A和线程B都执行到了步骤1,并未完成步骤2,那么就会创建多个实例
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
public void doSomething(){
System.out.println("Do Something");
}
}
但这时有一个问题,如果线程A和B同时调用此方法,会出现执行
if (instance == null)
语句时都为真的情况,那么线程AB都会创建一个对象,那内存中就会出现两个对象,这违反了单例模式的定义。为解决这一问题,可以使用synchronized关键字对静态方法
getInstance()进行同步,线程安全的的懒汉式单例模式代码如下:
public class LazySingleton {
private static LazySingleton instance = null; // 私有构造方法,确保外界不能直接实例化。
private LazySingleton() {} // 通过公有的静态方法获取对象实例
synchronized public static LazySingleton getInstace() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
饿汉式单例类在资源利用效率上不如懒汉式单例类,但从速度和反应时间来看,饿汉式单例类要优于懒汉式单例类。
加分回答
1.单例模式的优点:
2.单例模式的缺点:
标准回答 1. 物理内存以前,还没有虚拟内存概念的时候,程序寻址用的都是物理地址。
程序能寻址的范围是有限的,这取决于 CPU 的地址线条数。比如在 32 位平台下,寻址的范围是 232 也就是 4G。并且这是固定的,如果没有虚拟内存,且每次开启一个进程都给 4G 物理内存,就可能会出现很多问题:
- 虚拟内存 由于物理内存有很多问题,所以出现了虚拟内存。虚拟内存是计算机系统内存管理的一种技术。
它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
得分点 控制反转与依赖注入含义
标准回答 IOC是控制反转的意思,是一种面向对象编程的设计思想。
在不使用IOC的情况下,我们要维护对象与对象之间的关系,可能会造成耦合性问题,而IOC可以避免这种情况的产生,它可以帮我们维护对象之间的关系,降低对象的耦合性问题。 控制反转,控制就是获取资源的方式,之前由程序员new对象主动创建,反转之后,就变成了对象由IOC容器创建,实现ioc的方式是依赖注入.
引自牛客网秋招面试题