篇幅考虑,本文给出10个题目,每个题目给出4个左右的题目答案。完整200+题的PDF文档可以私信一、Java面试宝典制作面试自备过程。当时在网上找了一些试题,但是没有答案。也是靠着这个梳理,面试一路过关斩将,offer收获率100%。上了头条,美团三个事业部都收到了offer。也祝各位被学校招的朋友都能拿到满意的offer1:Java基础String、Stringbuffer、StringBuilder的区别。答:String是一个final类,不能被继承和修改。每次修改都会创建一个新的String对象。Stringbuffer和StringBuilder可以正常修改。两者的区别在于StringBuffer的每个方法都是加锁的,是线程安全的。为什么JAVA8的ConcurrentHashMap会放弃段锁呢?有什么问题吗?如果你设计它,你如何设计它。答:在1.8之前,ConcurrentHashMap传递的是一个Segment数组,大小为16。这16个Segment继承自ReenterLock,类似于16把锁均匀维护所有的桶。每次写操作都会锁住一个segment下的所有bucket,锁力强,会降低支持的并发数。因此1.8做了优化,使用了更细粒度的锁。散列后,如果没有相关的桶,则不加锁,直接通过Unsafe类似的CAS操作,将值放入桶中。如果有桶,则桶被锁定。其他桶中的节点仍然可以正常运行。继承和聚合有什么区别?答:继承主要描述'AisB'的关系,聚合描述'AhasB'的关系。一般来说,聚合是首选,因为继承可能会从父类继承一些不必要的特性和属性。方法。但是,如果需要向上转型,就需要使用继承。反射的原理,反射创建类实例的三种方式是什么。答:当一个类被加载时,会生成一个Class对象,Class对象可以获得该类的所有属性、方法等数据。方法一:对象调用getClass()方法方法二:类名.class方法三:Class.forName(全路径名)创建类对象后,直接调用类对象的newInstance()方法创建实例2:JvmJvm包括那些部分。答:主要包括4个部分:类加载器、字节码执行引擎、内存模型、本地方法调用。什么情况下会出现栈内存溢出。答:一般在递归调用的时候容易出现。虚拟机栈描述了Java方法执行的内存模型。每个方法的执行都会创建一个栈帧来保存局部变量表、操作数栈、动态链接、方法出口等信息。如果请求的堆栈深度大于虚拟机允许的最大深度,将抛出StackOverFlowError,如果无法请求到所需的内存,将抛出OutOfMemoryError。为什么JVM内存分为新生代、老年代、永久代。为什么新生代分为Eden和Survivor。答:分为新生代、老年代和永久代。不同的region根据自己的特点采用不同的GC策略。和两个幸存者区域。oldgeneration和persistentbands一般使用mark-and-clear算法。详细介绍CMS垃圾收集器。答:CMS是老年代垃圾收集器,目标是停顿时间最短。其工作主要包括四个阶段:(1)初始化标记,主要标记老年代GCroots和新生代引用的对象,需要STW(2)并发标记:从第一步对象开始,并发完成标记(3)Re-标记:因为第二步是并发完成的,过程中对象引用可能会发生变化。这一步主要是为了保证标记在真正清除之前是正确的,这就需要STW(4)并发清除:并发清除被标记的对象虽然第一步和第三步仍然需要STW,但是要完成的工作更简单,更少,花费更少的时间;最耗时完成的标记过程和清除过程是同时进行的,所以CMS可以控制更短的停顿时间。三:开源框架知识简单介绍一下Spring的加载过程。答:资源定位(Resource)->bean解析(BeanDefinition)->bean注册(conncurrentHashMap)SpringAOP实现原理?解释几个AOP相关的专业术语?答:原理:通过IOC和dynamics,aop本质上是对bean的增强。当通过getBean()获取bean时,bean初始化后会有一些后处理过程。Aop就是在这里实现的。如果发现bean有关联的advisor或Interceptor,将通过dynamic*增强。术语:建议:方面的工作,何时使用方面,之前,之后,返回之后,之后,周围;JoinPoint:应用程序中可以插入切面的点;切点(PointCut):一个或多个连接点讲的是Spring事务的传播特性。答:spring事务传播属性的主要作用是当事务方法被另一个事务方法调用时,spring如何处理这些事务的行为。比如默认的传播属性PROPAGATION_REQUIRED是有当前事务就加入当前事务,没有事务就创建新事务。Spring在TransactionDefinition中定义了事务的7个传播属性和5个隔离级别。为什么Spring将bean设计成默认的单例?这种设计的优点和缺点是什么?答:(1)避免频繁创建实例,减少开销,提高性能;(2)避免频繁创建对象导致OOM或频繁GC;(3)可以充分利用缓存加快检索速度它的缺点也很明显,因为大家共享一个bean,所以在多线程环境下可能会出现线程安全问题。四:Linux操作系统下有几种IO模型,各自的含义是什么。答:5种IO模型:阻塞IO模型、非阻塞IO模型、IO多路复用模型、信号驱动IO、异步IO阻塞IO:进程阻塞,直到数据拷贝完成。非阻塞IO:通过反复调用,如果内核没有准备好数据,会立即返回失败,上游决定继续重试,直到准备好。数据复制过程仍然阻塞。IO多路复用模型:使用select、poll或epoll还是会阻塞,但是可以同时监听多个IO口,哪个通道就绪优先。信号驱动IO:立即返回,当数据准备好后,向调用进程发送信号。异步IO:数据准备好后,内核通过完成后的回调函数通知用户进程通常使用哪些Linux命令。答案:cd、mkdir、touch、cp、vi、cat、netstat、kil、top浏览文件:catmoreless查看日志:tail-n100-fcantina。文件字节数)top看负载,cpudfdu看磁盘使用情况。df-hdu-d1-h/useriostat-d-k看磁盘IOfree-m看内存使用介绍下你了解的操作系统中的线程切换过程。答:进程切换一般发生在中断、异常或系统调用时。此时,(1)被中断的进程A保存当前上下文信息,然后挂起,修改线程状态,进入相关进程队列。(2)恢复进程B的上下文信息,分配cpu时间片处理进程和线程的差异。答:进程操作系统资源分配的基本单位,线程是任务调度和执行的最小单位。一般一个进程会包含多个线程,一个线程就是一个轻量级的进程。开销:一个进程有自己独立的代码和内存空间,切换开销大,而多个线程共享进程的代码和数据空间,每个线程都有自己独立的线程栈和程序计数器。五:多线程和多线程的几种实现,什么是线程安全。答:通过继承Thread,或者实现Runnable接口,也可以通过线程池实现Callable接口。当多个线程访问某个类时,不需要额外的同步措施,这个类仍然可以表现出正确的行为。行为,这个类是线程安全的。volatile的原理和作用可以替代锁。答:当向一个被volatile修饰的变量写入数据时,JVM会自动给处理器加锁指令。处理器收到锁定指令后,会立即将新修改的值写回主存,同时使这个变量在其他任务中被使用。内存中的值无效。它可以作为一种轻量级的同步方法,可以保证数据在每个线程中的可见性,避免指令重排序。但是volitaleb不能代替锁。虽然volatile可以保证可见性,但是如果对volatile变量的操作不依赖于当前值,那还好,但是如果依赖了,就是多步操作,比如i++,还是需要加锁的。睡眠和等待的区别。答:sleep是Thread类中的静态方法,wait是Object中定义的普通方法。两种方法都会释放cpu资源,让线程进入waiting状态,但是sleep不会释放锁,wait会释放锁。Lock和Synchronized的区别。A:首先,实现方式不同。Synchronized在字节码层面是支持的,而lock底层是通过AbstractQueuedSynchronizer来实现的。加锁的方式,以UnfairLock为例,就是尝试setState。如果成功,则将状态加1。如果失败,则排到队尾,等待锁持有者唤醒。释放锁就是state减1。第二,Lock比synchronized的功能更丰富。比如trylock尝试加锁,带过期时间加锁,公平锁和非公平锁等。六:网络知识http1.0和http1.1有什么区别。答:(1)http1.1支持长链接,通过请求头的keep-alive,1.0是针对短链接的,每次请求都会建立一个tcp连接。(2)增加主机字段。以前认为每台服务器都有一个唯一的ip,但是随着虚拟技术的发展,一台服务器上可以有多个虚拟主机,它们共享一个ip地址。(3)新增状态码100。客户端首先发送一个没有内容的请求头。如果服务器接受了,则返回100。然后客户端继续其他请求,测试服务器是否收到请求,节省带宽。(4)引入分块传输编码来解决上述问题。发送方将消息分成若干个任意大小的数据块。length块作为消息结束的标志。此方法允许发送方仅缓冲消息的一个片段,避免因缓冲整个消息而导致的过载。(5)在1.0的基础上,增加了一些新特性。当缓存对象的Age超过Expire时,它??就变成了过期对象。而不是直接丢弃staleobject,而是重新激活TCP三次握手和四次挥手的过程,为什么要3次建立连接,2次不够,4次握手需要3次才能disconnect,因为tcp是双向通信协议,2次握手只让一方建立连接,另一方然后确认,也就是说只有一方可以发送数据。因此需要3次握手来确认双方可以发送和接收数据。3次握手建立连接的第二次信号中,ack和syn是同时发送的,所以比断开连接少了一个发送过程。当客户端向服务端发送断开连接的FIN请求时,意味着客户端将不再向服务端发送数据,但是客户端可能还有数据没有收到,服务端还需要继续发送剩余的数据给客户。当服务器没有数据要发送给客户端时,服务器正在发送断开连接请求,客户端可以确认,所以是4次握手。说说你知道的几种HTTP响应码,比如200、302、404。答:2**一般是指请求成功,比如200成功。3**表示重定向,301永久移动,302临时移动。4**表示请求错误,404未找到,403禁止。5**表示服务器异常,500服务器内部错误,503服务不可用。七:分布式分布式集群下的架构设计以及如何实现序列号唯一。答:uuid->segment获取号段方案->segment+double*->snowflake。详细说明可以参考美团科技相应文章公众号如何使用redis和zookeeper实现分布式锁?区别有哪些优缺点,会出现什么问题,适用于哪些场景。答:一个简单的redis分布式锁可以通过setnx命名,同一个key设置setnx为1,因为只有一个会成功,所以达到了加锁的目的,但是会有问题,因为value全为1,有可能锁会被其他客户端释放,所以一般的衡量方式是,该值是一个随机数或者一个时间戳。但是这只是针对单机的redis。如果redis是一个集群,master的数据还没有同步到slave。如果master挂了,锁就失效了,其他client可以重新获取锁。因此,redis的作者提出了redlock。客户端向多个节点申请锁。每个节点设置一个比锁过期时间小得多的等待时间。当成功节点数大于一半时,获取成功。但是这样会出现和上面单节点一样的问题。如果某个节点崩溃或者某个节点被阻塞导致过期等,也会出现问题。REST与RPC的异同?答:(1)对象不同:REST是面向资源的,而RPC是面向服务和方法的(2)类别不同:REST主要用于http,而RPC主要是远程如何调用zk保证多个客户端同时创建节点,只有一个创建成功。答:通过查看zk的源码可以发现,createNode的实现会先根据节点的路径获取上层路径的父节点,并使用父节点锁定后续的节点创建手术。当父节点getchildren包含当前节点时,直接失败。八:数据库知识MysqlMyIsam和InnoDB引擎索引结构有什么区别。什么是数据库隔离级别,它们的含义是什么,MYSQL默认的隔离级别是什么。答:有4种隔离级别。Uncommittedreads:最低级别,只保证不读取物理损坏的数据Committedreads:可以避免脏读Repeatablereads:默认级别,可以避免脏读和不可重复读Serializable:最高级,脏读,非-可避免重复读和幻读。什么是幻读。答:一个事务按照相同的条件读取之前读取的数据,发现其他事务插入了符合条件的数据。避免幻读的一般措施是使用间隙锁。不可重复读侧重于被其他事务修改的数据,而幻读侧重于其他事务插入的符合条件的新数据。Mysql的索引原理,索引有哪些类型,如何创建合理的索引,如何优化索引。答:索引使用B+树来快速检索数据。B+树索引、哈希索引、前缀索引、全文索引等。建立合理的索引:(1)首先你要知道你的业务中的使用场景,哪些字段会被频繁用作检索条件,然后考虑字段的分散程度(2)根据需要适当建索引,不要过头,索引不是越多越好(3)长字段可以考虑前缀索引,多字段可以考虑联合索引-field(4)InnoDB还可以充分利用聚簇索引优化。我觉得主要是优化有索引但是没用的情况:或者每个条件都必须有索引,否则不会使用索引;是否位于综合指数前列;像模糊查询模糊匹配%放在最前面;字符串不带引号引起的隐式类型转换9:消息队列messagequeue使用场景。答:消息队列一般用于系统间的解耦。例如,当一个订单组中出现各种与订单相关的mq消息时,关心订单操作的系统可以自行申请相关的mq。异步处理,相对于rpc的同步调用,需要等待结果返回,mq是异步处理,比如库存扣款的主流程只??依赖于redis,扣款DB可以通过mq实现最终一致性.瞬时流量的平滑调峰处理。对于瞬时大流量,可以放入mq,消费端不断拉取任务进行处理,实现平滑调峰。消息重传,补充策略。答:消费成功后,消费者会给消息中间件一个确认消息,中间件可以删除相关消息。但是,由于网络的不可靠性或其他因素,为了保证消息的一定投递,消息中间件一般会采取各种重传措施。常见的措施包括超时重传和消息确认机制。如何保证MQ系统的数据不丢失。答:各大消息中间件采取的措施其实大同小异,可以相互借鉴。以卡夫卡为例。发送方一般使用ACK响应机制。当Kafka收到消息后,会生成响应消息。可以配置是不需要响应,leader响应,还是所有follower完成响应。消息队列一般持久化到文件系统,节点的主从机制,主节点的*机制。消费者一般通过响应机制和超时重传来保证消息的可靠性。Kafka通过位置十:缓存如何防止缓存崩溃和雪崩来控制数据不丢失。答:(1)缓存穿透:是指在找不到缓存的情况下检查数据库。当有人用大量不存在的键恶意检查你的缓存时,大量的请求就会打到数据库上,给数据库造成压力。一般可以采取的措施是在查询缓存之前加一层过滤,比如通过bitmap。(2)缓存击穿:指访问频繁的个别热点SKU。当这些热点SKU过期时,大量请求将命中数据库。可以考虑加锁,或者设置更长的过期时间,甚至不过期。(3)缓存雪崩:指大面积的key同时过期,所有请求都发给DB。采用的方法可以在密钥的过期时间上加上一个随机数。其他可以采取的措施可以防止在单机上刷通过Guava。其实前面几个问题的关键是给数据库带来压力,所以可以在数据库端实现限流或者分布式锁。Redis有哪些数据结构,适用于什么样的场景?答:String、list、hash、set、zsetString使用最广泛,适合存储各种key-value数据。List底层是一个双向链表,适用于列表、队列等,Hash适用于对象存储,Set适用于场景充值集合Zset是有序集合,可以用来实现PriorityQueue什么的使用Redis时要注意答:(1)冷热数据分开存放,不同业务数据分开存放(2)规范key(3)注意垃圾回收,给key设置合适的过期时间(4)大文本数据可以先压缩(5)hash,set的关键字段不要太多,可以根据业务,用几个hash和set(6)设计sharding机制。redis和mem*d的区别。答:redis和mem*d都适合做缓存,都是用内存来存储数据的。主要区别如下:(1)支持的数据类型:mem*d只支持简单的key-value,而redis支持的更丰富(2)线程模型:redis是单线程的,mem支持多线程,当量数据量大,mem有一定的优势(3)持久性:mem是纯内存,断电一切都没有了。Redis支持两种持久化方式:rdb或aof(4)内存管理:mem将内存分成固定大小的块,大小相同的块组成一个slab类。存储数据时,寻找最合适的chunk进行存储可能会导致碎片化,内存利用率低。通过用C语言包装malloc/free,redis将申请内存块的大小放在内存块的头部区域,实现内存的精准申请和释放。同时当内存不够用的时候,mem使用LRU删除,redis除了LRU之外还可以使用虚拟内存将部分value转移到磁盘中,key仍然保存在内存中。(5)分布式:mem本身不支持分布式,只能在客户端实现。从3.0版本开始,redis原生支持集群。如果这篇文章对你有帮助,别忘了给我3个链接,点赞、转发、评论,我们下期见!答案获取方式:点赞、评论、关闭~可以说这篇文章(书)熟悉了本文80%以上的内容,找个开发工作问题不大。对于有3-5年经验的朋友来说,也是快速复习的利器!本次的内容大致介绍到这里。由于内容太多,这里只能简单介绍一下。需要以上内容完整版的可以私信我获取~~后台关注我私信回复:【666】获取
