11.04-蔚来后端日常实习一面面经

11.04-蔚来后端日常实习一面面经
最新回答
离鸿

2026-08-15 08:42:48

以下是针对蔚来后端日常实习一面问题的详细解答:

  1. 自我介绍

    需简洁清晰,涵盖教育背景(学校、专业、相关课程)、技术栈(如Java、Python等后端开发语言,框架如Spring Boot)、项目经历(重点说明与后端开发相关的项目,包括项目目标、技术选型、个人职责及成果)、实习经历(如有,说明公司、岗位、工作内容及收获)、个人优势(如学习能力、问题解决能力、团队协作能力等)。

  2. 拷打实习

    面试官可能针对过往实习经历进行深入提问,需提前梳理实习中参与的项目,包括项目背景、技术架构、使用的工具和技术栈、遇到的问题及解决方案、个人贡献和成长。例如,若实习中参与过微服务开发,可说明如何进行服务拆分、如何解决服务间通信问题、如何保证服务的高可用性等。

  3. 对面向对象概念的理解

    核心概念:面向对象是一种编程范式,以对象为核心,将数据和操作数据的方法封装在一起,通过对象之间的交互来完成任务。

    三大特性:

    封装:隐藏对象的内部实现细节,只对外提供必要的接口,提高代码的安全性和可维护性。

    继承:子类继承父类的属性和方法,实现代码复用,同时可以扩展和修改父类的功能。

    多态:同一操作作用于不同的对象,可以有不同的解释和执行结果,提高代码的灵活性和可扩展性。

  4. Java有没有什么反面向对象的?

    基本数据类型:Java中的基本数据类型(如int、float、boolean等)不是对象,它们直接存储值,不具有对象的特性,如封装、继承和多态。不过,Java提供了对应的包装类(如Integer、Float、Boolean等)来支持面向对象操作。

    静态成员:静态变量和静态方法属于类,而不是对象,它们不依赖于对象的实例存在,在一定程度上违背了面向对象中“一切皆对象”的思想。

    过程式代码:在Java代码中,如果大量使用过程式的编程风格,如函数式编程中的纯函数(无副作用、不依赖外部状态),而不注重对象的封装和交互,也可以认为是对面向对象思想的偏离。

  5. 注解有用到吗,经常用的注解有哪些,原理是?

    常用注解:

    @Override:用于标识子类中重写父类的方法,编译器会检查该方法是否确实重写了父类的方法,提高代码的可读性和安全性。

    @Autowired:Spring框架中的注解,用于自动装配依赖的Bean,简化代码中的对象创建和依赖管理。

    @RequestMapping:Spring MVC中的注解,用于将HTTP请求映射到特定的处理方法上,实现URL与控制器方法的对应。

    @Transactional:用于声明事务,确保方法在事务环境下执行,保证数据的一致性和完整性。

    原理:注解本身只是元数据,在编译时或运行时被特定的处理器处理。例如,Java编译器会处理@Override注解进行语法检查;Spring框架在启动时会通过反射机制扫描带有@Autowired、@RequestMapping等注解的类和方法,根据注解的信息进行相应的处理,如依赖注入、URL映射等。

  6. 注解除了代码简洁,在面向对象的概念里有什么好处?

    增强可读性:注解可以清晰地表达代码的意图和用途,使代码更易于理解和维护。例如,@Transactional注解明确表示该方法需要在事务中执行,开发人员无需阅读方法内部的代码就能了解其事务特性。

    提高可扩展性:通过注解可以方便地添加新的功能或行为,而无需修改原有的代码结构。例如,可以使用自定义注解来实现AOP(面向切面编程)功能,如日志记录、权限控制等,将横切关注点与业务逻辑分离。

    促进代码复用:注解可以定义通用的行为和规则,多个类或方法可以共享相同的注解配置,提高代码的复用性。例如,多个控制器方法可以使用相同的@RequestMapping注解配置来映射相同的URL前缀。

  7. 反射有使用到吗,在什么情况下会使用到?反射是面向对象的一个基础吗?他的思想是面向对象吗

    使用场景:

    框架开发:如Spring框架通过反射机制实现依赖注入、AOP等功能,动态地创建对象、调用方法、访问属性等。

    动态代理:在需要为某个对象创建代理对象时,可以使用反射来动态生成代理类的字节码,并在运行时加载和执行代理方法。

    通用工具类:开发一些通用的工具类,如JSON序列化和反序列化工具,可以通过反射获取对象的属性和方法,实现对象的自动转换。

    是否为面向对象基础:反射不是面向对象的基础,面向对象的基础是封装、继承和多态等核心概念。反射是一种在运行时动态获取和操作类信息的机制,它是对面向对象编程的一种补充和扩展。

    思想是否面向对象:反射的思想在一定程度上与面向对象的思想相关,但它更侧重于在运行时对类和对象的动态操作,而不是通过对象之间的交互来完成任务。反射可以突破封装的一些限制,访问对象的私有属性和方法,但这并不违背面向对象的思想,而是在特定场景下提供了一种更灵活的编程方式。

  8. ConcurrentHashMap和普通的HashMap有什么区别,原理,对象结构,扩容流程

    区别:

    线程安全性:HashMap是非线程安全的,多线程环境下同时对HashMap进行读写操作可能导致数据不一致、死锁等问题;ConcurrentHashMap是线程安全的,通过分段锁或CAS+synchronized等方式保证多线程环境下的数据一致性。

    性能:在单线程环境下,HashMap的性能通常优于ConcurrentHashMap,因为ConcurrentHashMap需要额外的同步机制来保证线程安全;但在多线程环境下,ConcurrentHashMap的性能优势明显,它避免了全局锁的使用,提高了并发访问的效率。

    原理:

    Java 7:ConcurrentHashMap采用分段锁技术,将整个哈希表分成多个段(Segment),每个段相当于一个小的哈希表,每个段都有自己的锁。对不同的段进行操作时,可以并发进行,只有对同一个段进行操作时才需要获取该段的锁。

    Java 8:ConcurrentHashMap放弃了分段锁的设计,采用CAS+synchronized的方式实现线程安全。在哈希表的每个节点(Node)上使用CAS操作来保证插入和更新的原子性,对于需要扩容或链表转红黑树等操作,使用synchronized锁住当前节点或当前桶的首节点。

    对象结构:

    HashMap:由数组和链表(或红黑树)组成,数组的每个元素是一个链表(或红黑树)的头节点,链表(或红黑树)中存储着键值对节点(Node)。

    ConcurrentHashMap:Java 7中由Segment数组和哈希表数组组成,每个Segment包含一个哈希表;Java 8中与HashMap类似,由数组和链表(或红黑树)组成,但在节点上增加了更多的同步控制信息。

    扩容流程:

    HashMap:当哈希表中的元素数量超过负载因子(默认0.75)乘以容量时,会触发扩容操作。扩容时会创建一个新的更大的数组,然后将原数组中的所有元素重新计算哈希值并插入到新数组中。

    ConcurrentHashMap:Java 7中扩容时需要获取所有段的锁,然后对每个段进行独立的扩容操作;Java 8中扩容时采用多线程协作的方式,将扩容任务分配给多个线程同时进行,每个线程负责处理一部分桶的元素迁移,提高了扩容的效率。

  9. 举几个你使用到锁的场景,包括数据库的,分布式的,乐观锁,悲观锁

    数据库锁:

    悲观锁:在查询数据时加上排他锁(如SELECT ... FOR UPDATE),确保在事务完成前其他事务无法修改该数据,适用于并发冲突频繁的场景,如银行转账业务。

    乐观锁:通过版本号或时间戳等方式实现,在更新数据时检查版本号是否发生变化,如果未变化则更新,否则回滚事务,适用于并发冲突较少的场景,如商品库存的更新。

    分布式锁:

    Redis分布式锁:使用Redis的SETNX命令实现,当某个客户端获取到锁后,其他客户端无法再次获取,直到锁被释放。适用于分布式系统中的资源竞争问题,如分布式任务调度。

    Zookeeper分布式锁:利用Zookeeper的临时顺序节点和Watcher机制实现,客户端在Zookeeper上创建临时顺序节点,通过比较节点顺序获取锁,适用于需要强一致性的分布式场景。

    Java中的锁:

    synchronized:Java内置的同步锁,用于修饰方法或代码块,保证同一时刻只有一个线程可以访问该方法或代码块,适用于简单的同步场景。

    ReentrantLock:可重入锁,提供了比synchronized更灵活的锁操作,如可中断、可超时、公平锁等,适用于复杂的同步场景。

  10. 数据库用什么比较多?数据库选型怎么考虑,MongoDB还是MySQL

  • 常用数据库:MySQL是关系型数据库,使用广泛,适用于大多数传统的业务场景,如电商系统、金融系统等;MongoDB是非关系型数据库,适用于数据结构灵活、需要快速开发和扩展的场景,如日志管理、实时分析等。
  • 数据库选型考虑因素:

    数据模型:如果数据具有明确的结构和关系,如用户信息、订单信息等,适合选择关系型数据库(如MySQL);如果数据结构灵活,如文档、图片等,适合选择非关系型数据库(如MongoDB)。

    性能需求:对于高并发读写、低延迟的场景,如实时交易系统,需要考虑数据库的读写性能和响应时间,MySQL在事务处理和复杂查询方面性能较好,MongoDB在写入性能和水平扩展方面具有优势。

    可扩展性:如果业务需要快速扩展,数据量增长迅速,需要考虑数据库的可扩展性,MongoDB支持水平扩展,可以通过分片技术将数据分布在多个节点上;MySQL也可以通过主从复制、读写分离等方式提高可扩展性,但水平扩展相对复杂。

    生态系统:考虑数据库的生态系统,包括开发工具、社区支持、第三方库等,MySQL拥有丰富的生态系统和成熟的解决方案,MongoDB的生态系统也在不断发展壮大。

  1. 数据库分库分表的阈值是什么?为什么要分库分表
  • 分库分表阈值:没有固定的阈值,通常根据业务需求、数据量、并发量等因素综合考虑。一般来说,当单表数据量超过500万 - 1000万条,或者数据库的读写性能无法满足业务需求时,可以考虑进行分库分表。
  • 分库分表原因:

    提高性能:通过将数据分散到多个数据库和表中,减少单个数据库和表的负载,提高查询和写入的性能。

    提高可用性:当某个数据库或表出现故障时,不会影响整个系统的正常运行,其他数据库和表可以继续提供服务。

    扩展性:分库分表可以方便地进行水平扩展,当业务增长时,可以通过增加数据库节点和表的数量来满足需求。