2024.04.23美团基础研发平台java实习

  • 美团
  • 一面
  • 实习
大约 6 分钟全民制作人ikun

2024.04.23美团基础研发平台java实习

1.tcp如何保证可靠传输

TCP 是通过序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输的。

2.进程之间通信方式

进程间通信的方式包括:管道、共享内存、消息队列、信号量、信号和套接字Socket等

3.操作系统中的锁有哪些

悲观锁: 重量级锁: 获取不到锁,马上进入阻塞状态 自旋锁: 获取不到锁,等一段固定时间,再进入阻塞状态
自适应自旋锁: 根据线程最近获得锁的状况来调整等待时间

乐观锁: CAS机制: 不加锁,通过比较并交换来控制同步和线程安全 轻量级锁: 使用CAS机制标记方法的状态,避免加锁 偏向锁: 使用CAS机制记录执行该方法的线程ID,避免加锁

4.讲乐观锁和悲观锁

  • 乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法)。

  • 悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。

5.讲synchronized和reentlock区别

(1) synchronized 是Java的一个内置关键字,而ReentrantLock是Java的一个类。 (2) synchronized只能是非公平锁。而ReentrantLock可以实现公平锁和非公平锁两种。 (3) synchronized不能中断一个等待锁的线程,而Lock可以中断一个试图获取锁的线程。 (4) synchronized不能设置超时,而Lock可以设置超时。 (5) synchronized会自动释放锁,而ReentrantLock不会自动释放锁,必须手动释放,否则可能会导致死锁。

6.讲reentLock是如何实现乐观锁和悲观锁的

java.util.concurrent包中的ReentrantLock是一种可重入的互斥锁,它既可以实现悲观锁,也可以实现乐观锁。

  1. 实现悲观锁:

    • ReentrantLock默认采用的就是悲观锁策略。
    • 当线程试图获取锁时,如果锁已被其他线程占用,当前线程就会阻塞等待,直到获取到锁。
    • 这种方式保证了共享资源在任意时刻只有一个线程在使用,从而避免了数据竞争问题。
  2. 实现乐观锁:

    • ReentrantLock提供了tryLock()方法,允许线程尝试获取锁,但不会阻塞。
    • 如果成功获取到锁,则返回true;否则返回false。
    • 线程可以根据tryLock()的返回值来决定是否继续执行操作,从而实现乐观锁的策略。

7.讲openFeign调用原理

参考链接open in new window

Spring Cloud OpenFeign 的核心工作原理经上文探究可以非常简单的总结为:

  • 通过 @EnableFeignCleints 触发 Spring 应用程序对 classpath 中 @FeignClient 修饰类的扫描
  • 解析到 @FeignClient 修饰类后, Feign 框架通过扩展 Spring Bean Deifinition 的注册逻辑, 最终注册一个 FeignClientFacotoryBean 进入 Spring 容器
  • Spring 容器在初始化其他用到 @FeignClient 接口的类时, 获得的是 FeignClientFacotryBean 产生的一个代理对象 Proxy.
  • 基于 java 原生的动态代理机制, 针对 Proxy 的调用, 都会被统一转发给 Feign 框架所定义的一个 InvocationHandler , 由该 Handler 完成后续的 HTTP 转换, 发送, 接收, 翻译HTTP响应的工作

8.讲nacos服务注册原理

Nacos服务注册的原理:

Nacos采用服务注册表的方式来存储服务注册信息。注册表的外层Map按命名空间划分,内层Map则按服务名和分组维度存储服务信息。

每个服务信息包含一个Cluster对象,Cluster中保存了该服务的持久实例和临时实例。服务启动时,客户端会调用Nacos的注册接口将自己注册到注册表中。

Nacos服务端接收到注册请求后,会先判断是新增还是更新服务,然后将最新的实例信息更新到注册表,并通过Distro协议同步给其他Nacos节点。

为了支持高并发注册,Nacos采用队列+异步线程的方式,并使用CopyOnWrite思想避免读写冲突。这样可以确保服务注册信息的一致性和可靠性。

9.openFeign发送失败的策略

  • OpenFeign 在处理服务调用失败的情况下,提供了多种策略供开发者选择:

    1. 重试机制(Retry)

      • OpenFeign 支持服务调用重试,当调用失败时会自动重试几次。
      • 重试次数、重试间隔时间等参数都可以进行配置。
      • 这种机制适用于临时性的网络异常或服务端短暂不可用的情况。
    2. 熔断机制(Circuit Breaker)

      • OpenFeign 可以与 Hystrix 等熔断框架集成,在检测到大量服务调用失败时,开启熔断保护,拒绝后续请求。
      • 当服务恢复正常后,逐步恢复流量。
      • 熔断机制可以在服务不可用时快速返回,提高系统的整体可用性。
    3. 降级机制(Fallback)

      • OpenFeign 支持配置 Fallback 方法,当服务调用失败时,回退到 Fallback 方法执行。
      • Fallback 方法可以返回一个默认值或优雅的降级结果,而不是抛出异常。
      • 降级机制确保了服务的最低可用性,提升了用户体验。
    4. 兜底策略(Fallthrough)

      • 当以上所有机制都无法处理服务调用失败时,OpenFeign 会执行最后的兜底策略。
      • 这通常意味着直接抛出异常,让上层应用自行处理。

10.库存的Redis和mysql数据一致性如何保证

  • 实时一致性方案:采用“先写 MySQL,再删除 Redis”的策略,这种情况虽然也会存在两者不一致,但是需要满足的条件有点苛刻,所以是满足实时性条件下,能尽量满足一致性的最优解。
  • 最终一致性方案:采用“先写 MySQL,通过 Binlog,异步更新 Redis”,可以通过 Binlog,结合消息队列异步更新 Redis,是最终一致性的最优解。

11.threadLocal的作用

ThreadLocal的作用是提供线程内的局部变量,在多线程环境下访问时能保证各个线程内的ThreadLocal变量各自独立。也就是说,每个线程的ThreadLocal变量是自己专用的,其他线程是访问不到的。

12.不使用nacos,直接由A模块向B模块发请求,能不能成功得到处理

不懂

13.算法:查找前k小的元素

题目链接open in new window

class Solution {
public:
    vector<int> smallestK(vector<int>& arr, int k) {
        sort(arr.begin(),arr.end());
        vector<int> res;
        for(int i=0;i<k;i++) res.push_back(arr[i]);
        return res;
    }
};