七月还能开美团日常实习?看看面试题难不难

2024-09-26 12:57:48 浏览数 (1)

大家好,我是程序员牛肉。

临近暑假,不知道大家都找到实习没有。今天在某APP里闲逛,发现有人竟然七月份还能拿到美团的日常实习。我们来逐一解析一下他的面试题。

其实总体来看也不太难,但是涉及到八股并不多,因此靠死记硬背是走不通的。这里面的很多知识还是需要自己对Java有自己的理解。

那么在这里我们就看看这些面试题要如何回答:

01、Java的线程池是怎么设计的

Java的线程池设计是通过java.util.concurrent包中的ExecutorService接口实现的,它提供了一种灵活的线程池管理机制。线程池的主要设计目标是减少线程创建和销毁的开销,提高资源利用率和程序性能。以下是线程池设计的一些关键点:

  1. 线程复用:线程池维护一组线程,当任务提交给线程池时,线程池会尝试将任务分配给已有的空闲线程,而不是每次都创建新线程。
  2. 控制并发:线程池可以设定核心线程数和最大线程数,控制同时运行的线程数量,防止因线程过多导致系统资源耗尽。
  3. 任务队列:线程池通常包含一个任务队列,当所有线程都忙碌时,新提交的任务会被放入队列中等待执行。
  4. 线程生命周期管理:线程池可以自动管理线程的生命周期,包括线程的创建、执行任务、空闲等待以及销毁。
  5. 异常处理:线程池可以处理任务执行过程中的异常,保证线程池的稳定运行。
  6. 任务拒绝策略:当任务队列已满且线程池中的线程数达到最大值时,线程池需要定义一种策略来处理新提交的任务,比如丢弃任务、抛出异常或者运行一个额外的线程来处理任务。

02、核心线程数设置为多少合适

1.IO密集型任务

一般来说:文件读写、DB读写、网络请求等

推荐:核心线程数大小设置为2N 1 (N为计算机的CPU核数)

2.CPU密集型任务

一般来说:计算型代码、Bitmap转换、Gson转换等

推荐:核心线程数大小设置为N 1 (N为计算机的CPU核数)

03、Java中锁的分类和特点

1. 按锁的实现分类:

  • 内置锁(Synchronized):
    • 特点:由Java语言内置支持,通过synchronized关键字实现。
    • 使用范围:方法或代码块。
    • 作用:确保同一时刻只有一个线程可以执行特定代码段。
    • 缺点:可能导致性能问题,因为它是一种重量级锁。
  • 显式锁(Lock):
    • 特点:需要通过java.util.concurrent.locks.Lock接口实现,如ReentrantLock。
    • 使用范围:代码块。
    • 作用:提供了比synchronized更灵活的锁定机制。
    • 优点:支持尝试非阻塞获取锁、可中断的锁获取、超时等特性。

2. 按锁的作用范围分类:

  • 方法锁:
    • 特点:锁定整个方法。
    • 适用场景:当整个方法需要同步执行时。
  • 代码块锁:
    • 特点:锁定一段特定的代码块。
    • 适用场景:当只有部分代码需要同步执行时。

3. 按锁的可重入性分类:

  • 可重入锁:
    • 特点:同一个线程可以多次获取同一个锁。
    • 例子:synchronized和ReentrantLock。
  • 不可重入锁:
    • 特点:一个线程不能多次获取同一个锁。
    • 注意:Java标准库中没有提供不可重入锁的实现,但可以通过设计实现。

4. 按锁的公平性分类:

  • 公平锁:
    • 特点:按照线程请求锁的顺序来获取锁。
    • 例子:ReentrantFairLock。
  • 非公平锁:
    • 特点:线程获取锁的顺序不一定按照请求的顺序。
    • 例子:ReentrantLock默认是非公平锁。

5. 按锁的可中断性分类:

  • 可中断锁:
    • 特点:线程在尝试获取锁的过程中可以被中断。
    • 例子:ReentrantLock。
  • 不可中断锁:
    • 特点:线程在尝试获取锁的过程中不能被中断。
    • 例子:synchronized。

04、介绍一下java的反射机制

Java的反射机制是一种在运行时检查或修改程序行为的能力。它允许程序在运行时动态地加载类、查询类信息、创建对象、调用方法、访问字段等。反射是Java语言的一个重要特性,它提供了以下主要功能:

  1. 类加载:通过反射,可以在运行时加载一个类,而不需要在编译时就知道这个类。
  2. 类型检查:可以检查一个对象是否属于某个特定的类或接口。
  3. 创建对象:可以使用反射机制动态地创建类的实例,即使这个类的构造函数是私有的。
  4. 访问字段:可以访问类的私有字段,甚至可以修改其值。
  5. 调用方法:可以调用类的方法,包括私有方法。
  6. 获取类信息:可以获取类的各种信息,如类名、方法列表、字段列表等。
  7. 修改访问控制:可以修改访问控制,访问或修改私有成员。

05、MySQL事务的原子性如何保证

1.事务日志(transaction log):MySQL使用事务日志记录对数据库的所有修改操作。在事务执行期间,所有的修改操作都会被写入事务日志,而不是直接写入磁盘上的数据文件。这意味着即使在事务执行过程中发生故障,MySQL可以通过回滚日志来撤销事务中的操作,使数据回滚到事务开始前的状态,从而保证原子性。

2.回滚日志(undo log):MySQL使用回滚日志记录对事务进行回滚操作所需的信息。当事务需要回滚时,MySQL可以使用回滚日志中的信息来还原修改操作,将数据恢复到事务开始之前的状态。回滚日志的存在可以确保在事务回滚时的原子性,即将所有操作全部回滚,不会留下部分修改。

3.锁机制:MySQL使用锁来控制对数据的并发访问,保证事务的隔离性和原子性。在事务执行期间,MySQL会根据事务的隔离级别对涉及的数据进行加锁,防止其他事务对数据进行修改。当事务成功提交或回滚后,MySQL会释放相应的锁,确保事务的原子性。

06、MySQL如何解决慢查询

1.查询语句应该尽量避免全表扫描,首先应该考虑在Where子句以及OrderBy子句上建立索引,但是每一条SQL语句最多只会走一条索引,而建立过多的索引会带来插入和更新时的开销,同时对于区分度不大的字段,应该尽量避免建立索引,可以在查询语句前使用explain关键字,查看SQL语句的执行计划,判断该查询语句是否使用了索引;

2.应尽量使用EXIST和NOT EXIST代替 IN和NOT IN,因为后者很有可能导致全表扫描放弃使用索引;

3.应尽量避免在Where子句中对字段进行NULL判断,因为NULL判断会导致全表扫描;

4.应尽量避免在Where子句中使用or作为连接条件,因为同样会导致全表扫描;

5.应尽量避免在Where子句中使用!=或者<>操作符,同样会导致全表扫描;

6.使用like “�c%” 或者like “�c” 同样也会导致全表扫描,而like “abc%”会使用索引。

7.在使用Union操作符时,应该考虑是否可以使用Union ALL来代替,因为Union操作符在进行结果合并时,会对产生的结果进行排序运算,删除重复记录,对于没有该需求的应用应使用Union ALL,后者仅仅只是将结果合并返回,能大幅度提高性能;

8.应尽量避免在Where子句中使用表达式操作符,因为会导致全表扫描;

9.应尽量避免在Where子句中对字段使用函数,因为同样会导致全表扫描

10.Select语句中尽量 避免使用“*”,因为在SQL语句在解析的过程中,会将“”转换成所有列的列名,而这个工作是通过查询数据字典完成的,有一定的开销;

11.Where子句中,表连接条件应该写在其他条件之前,因为Where子句的解析是从后向前的,所以尽量把能够过滤到多数记录的限制条件放在Where子句的末尾;

12.若数据库表上存在诸如index(a,b,c)之类的联合索引,则Where子句中条件字段的出现顺序应该与索引字段的出现顺序一致,否则将无法使用该联合索引;

13.From子句中表的出现顺序同样会对SQL语句的执行性能造成影响,From子句在解析时是从后向前的,即写在末尾的表将被优先处理,应该选择记录较少的表作为基表放在后面,同时如果出现3个及3个以上的表连接查询时,应该将交叉表作为基表;

07、请求到Spring Boot处理函数的流程

  1. 接收请求:
    • 客户端(如浏览器或移动应用)向Spring Boot服务器发送HTTP请求。
  2. Tomcat作为内嵌容器:
    • Spring Boot默认使用Tomcat作为内嵌容器来接收和处理HTTP请求。
  3. DispatcherServlet:
    • 请求首先到达DispatcherServlet,它是Spring MVC的前端控制器,负责将请求路由到相应的处理器。
  4. HandlerMapping:
    • DispatcherServlet使用HandlerMapping来确定请求应该由哪个处理器(Controller)来处理。
  5. HandlerInterceptor:
    • 在请求到达Controller之前,可以被一系列的HandlerInterceptor拦截,用于执行前置处理。
  6. Controller:
    • 请求被路由到相应的Controller中的处理函数(通常用@RequestMapping或其他注解标记)。
  7. 业务逻辑处理:
    • Controller调用业务逻辑层(Service层)来处理请求。
  8. 数据访问:
    • 如果需要,Service层会调用数据访问层(Repository或DAO层)来访问数据库或外部数据源。
  9. 返回结果:
    • 业务逻辑处理完成后,Controller将处理结果返回给DispatcherServlet。
  10. 视图解析:
    • 如果Controller返回的是视图名称,DispatcherServlet将使用视图解析器(ViewResolver)来解析视图。
  11. 渲染视图:
    • 视图被渲染后,返回给客户端,如果是HTML页面,客户端浏览器将展示给用户。
  12. 返回响应:
    • 如果是RESTful API,Controller可能直接返回JSON或XML响应。
  13. HandlerInterceptor的后置处理:
    • 请求处理完成后,HandlerInterceptor可以执行一些后置处理。
  14. 请求完成:
    • DispatcherServlet完成请求处理,并将响应发送回客户端。
  15. 日志记录:
    • 整个请求处理过程可能会被日志记录,以便于问题排查和性能监控。

大致就是这些问题了,其实综合来看并不是很难。但是比较考察面试者真正的功力,大部分面试题已经不是八股的范围了,需要面试者在日常生活中就经常积累。

0 人点赞