当前位置: 首页 > 后端技术 > Java

【大厂专访】美团面试两次,最后有惊喜?

时间:2023-04-02 10:01:24 Java

本期是【大厂专访】系列文章的第4期,话题来自美团店二面。现场面试官:首先,进程和线程有什么区别?独白:老八卦文哈哈大斌:进程是系统进行资源分配和调度的独立单位,每个进程都有自己的内存空间和系统资源大斌:线程是进程的一个实体,被调度和调度CPU调度的基本单元是比进程更小,可以独立运行的基本单元。大斌:多线程是实现并发的有效手段。进程和线程都是并发的基本单位。面试官:那为什么要用多线程呢?独白:哎,这个简单大斌:使用多线程的主要原因是为了提高系统的资源利用率。大斌:多个线程同时运行,可以减少线程上下文切换的开销,提高并发能力和CPU利用效率。大斌:多线程在日常工作中也很常见。比如Tomcat每处理一个请求,都会从线程连接池中取出一个线程来处理。面试官:嗯,一般在使用多线程的时候,可能会遇到线程安全的问题。告诉我什么是线程安全?大斌:我是这么理解的。当多个线程访问一个对象时,如果不需要考虑运行时环境中这些线程的调度和交替执行,不需要进行额外的同步,就可以获得调用这个对象的行为。如果结果正确,则此对象是线程安全的。面试官:那你平时是怎么处理线程安全问题的呢?大斌:这个要具体分析。首先判断是否存在线程安全问题,如果存在,根据具体情况处理线程安全问题。大斌:比如涉及到操作的原子性,可以考虑使用atomic包下的atomic类。大斌:如果涉及到线程控制,可以考虑线程工具类CountDownLatch/Semaphore等。大斌:对于集合类,可以考虑java.util.concurrent包下的集合类。大斌:还有synchronized和lock包下的类,redis分布式锁等等。面试官:嗯,刚才提到了Redis分布式锁。你认为在什么场景下需要使用分布式锁?大斌:在单机环境下,可以通过ReentrantLock、synchronized、并发契约下的一些线程安全类来避免线程安全问题。大斌:在多机部署环境下,需要保证多进程下的线程安全。Java提供的这些API只能保证单个JVM进程内多线程访问共享资源的线程安全,已经不满足要求。这时候就需要使用分布式锁来保证线程安全。大斌:Redis2.6.12之前的版本使用setnx+expire实现分布式锁。Redis2.6.12版本之后,setnx增加了过期时间参数,只需要使用setnx来实现分布式锁。面试官:那说说Redis分布式锁的原理?独白:在面试中造火箭,在工作中搞砸?大斌:首先介绍一下Redis的加锁逻辑。大斌:setnx竞争key的锁。如果key已经存在,则不执行任何操作。过一会继续重试,确保只有一个客户端可以持有锁。dabin:value设置为requestId(可以用机器ip加入当前线程名),表示哪个request加了锁。解锁时需要判断当前请求是否持有锁,防止误解锁。比如客户端A加锁,在执行解锁之前,锁就过期了。此时客户端B尝试加锁成功,然后客户端A执行del()方法,客户端B的锁被释放。大斌:那就用expire给锁加一个过期时间,防止锁因为异常而被释放。大斌:然后就是解锁的逻辑。大斌:先获取锁对应的值,检查是否与requestId相等,相等则删除锁。使用lua脚本实现原子操作,保证线程安全。面试官:对,简历上写着你熟悉TCP。给大家介绍一下在TCP中挥四次?独白:嗯嗯,大斌我很熟:假设A是客户端,B是服务端。首先,A的应用进程首先向自己的TCP发送一个连接释放报文段(FIN=1,seq=u),并停止发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。B收到连接释放报文段后,发送确认报文段(ACK=1,ack=u+1,seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时TCP处于半关闭状态,A到B的连接被释放。A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发送的连接释放报文段。B发送完数据后,会发送一个连接释放报文段(FIN=1,ACK=1,seq=w,ack=u+1),B进入LAST-ACK(最终确认)状态,等待A的确认。A收到B的连接释放报文段后,发送确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP没有被释放,只有经过时间等待定时器设置的时间2MSL(maximumsegmentlifetime)后A才进入CLOSED状态。B收到A的确认报文段后关闭连接,如果没有收到A的确认报文段,B将重传连接释放报文段。面试官:建立连接的时候,有3次握手。为什么释放连接的时候要挥手四次?不是三遍吗?大斌:因为在建立连接时,服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。大斌:但是关闭连接的时候,服务器端收到客户端的连接释放报文的时候,很可能不会马上关闭SOCKET,所以服务器端先回复一个ACK报文,告诉客户端我收到了你的连接发布消息。只有当服务器端的所有消息都发送完后,服务器端才能发送连接释放消息,然后双方才真正断开连接。所以需要四波。面试官:嗯,你了解https吗?https解决什么问题?独白:一点都不慌哈哈大斌:HTTP是明文传输的,很容易被黑客窃听或篡改,所以不安全。大斌:HTTPS主要解决了HTTP明文协议的缺陷。它在HTTP的基础上增加了SSL/TLS协议,依靠SSL证书来验证服务器的身份,在客户端和服务器之间建立SSL通道,保证数据传输的安全。面试官:那么http和https具体有什么区别呢?大斌:http和https的区别在于:HTTP是一种超文本传输??协议,信息以明文形式传输;HTTPS是一种安全的ssl加密传输协议。HTTP和HTTPS使用不同的端口,HTTP端口为80,HTTPS为443。HTTPS协议需要向CA机构申请证书,一般需要一定的费用。HTTP运行在TCP协议之上;HTTPS运行在SSL协议之上,SSL运行在TCP协议之上。面试官:对,请教一些MySQL相关的面试官:索引在什么情况下会失效?大斌:有几种情况会导致索引失效。对于复合索引,如果不使用复合索引的最左边字段,则该索引将不会用于以%开头的like查询,如%abc,不能使用索引;like不以%开头的查询,比如abc%,等同于范围查询,会使用索引查询条件中的列类型是字符串,如果不使用引号,可能会因为不同而发生隐式转换类型,这将使??索引无效。判断索引列是否不等于某个值时,查询条件用or连接,也会导致Index失效面试官:很好,明天可以入职吗?独白:背心、头盔、盒子三件套?