北京互联网公司面试题精华解析
这是一家北京的互联网公司面试题含金量还是有的,直接操作。
一,链表的优点有什么:
动态内存分配
链表在运行时动态分配内存,无需预先知道数据规模,适合存储大小不确定的数据集。
高效的插入和删除操作
在已知节点位置的情况下,插入或删除操作的时间复杂度为O(1),无需像数组那样移动大量元素。
内存利用率高
链表按需分配内存,避免数组可能造成的空间浪费(如预留空间不足或过多)。
灵活的扩展性
链表长度可自由增减,理论上仅受系统内存限制,适合频繁增删的场景(如实现队列、栈)。
可轻松实现复杂结构
通过指针的灵活指向,能高效构建双向链表、循环链表等变体,满足特定需求(如LRU缓存)。
内存非连续存储
节点分散在内存中,避免数组对连续大块内存的要求,降低内存碎片化风险。
与树、图的关联性
链表是树和图等高级数据结构的基础组件,理解链表有助于掌握更复杂的数据组织方式。
说的有点多了哈这里就第二条重要哈。
二,红黑树和二叉树的区别是什么
红黑树是一种自平衡的二叉搜索树(BST),而普通二叉树不具备自平衡特性。以下是两者的核心区别:
平衡性
- 红黑树:通过颜色标记和旋转操作保持近似平衡,确保最坏情况下的操作时间复杂度为O(log n)。
- 普通二叉树:可能退化为链表结构(如插入有序数据时),导致最坏时间复杂度为O(n)。
节点规则
- 红黑树:每个节点标记为红或黑,需满足以下规则:
- 根节点和叶子节点(NIL)为黑。
- 红节点的子节点必须为黑(无连续红节点)。
- 从任一节点到其叶子节点的路径包含相同数量的黑节点。
- 普通二叉树:无额外规则,仅需满足左子节点小于父节点、右子节点大于父节点(BST规则)。
操作复杂度
- 红黑树:插入、删除、查找均为O(log n),因旋转和重新着色操作维持平衡。
- 普通二叉树:若不平衡,操作复杂度可能达O(n)。
应用场景
- 红黑树:适用于需要高效动态操作的场景(如Java的
TreeMap
、Linux进程调度)。 - 普通二叉树:适用于静态数据或数据随机性较强的情况。
实现复杂度
- 红黑树:实现复杂,需处理多种旋转和颜色调整情况。
- 普通二叉树:实现简单,但需额外处理平衡问题(如AVL树或B树)。
简而言之,红黑树通过规则约束保证了高效性,而普通二叉树更简单但性能不稳定。
三,AOP和IOC
AOP(面向切面编程)
AOP(Aspect-Oriented Programming)是一种编程范式,用于将横切关注点(如日志、事务、权限等)从业务逻辑中分离出来,提高代码的模块化和可维护性。
核心概念: 切面(Aspect):封装横切关注点的模块。 连接点(Join Point):程序执行过程中的特定点(如方法调用、异常抛出)。 通知(Advice):在连接点执行的动作(如前置通知、后置通知)。 切入点(Pointcut):定义哪些连接点会被通知拦截。
典型应用: 日志记录、性能监控、事务管理、安全检查等。
实现方式: 动态代理(如JDK动态代理、CGLIB)、字节码增强(如AspectJ)。
示例代码(Spring AOP):
@Aspect @Component public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void logBefore(JoinPoint joinPoint) {System.out.println("Method called: " + joinPoint.getSignature().getName());} }
IOC(控制反转)
IOC(Inversion of Control)是一种设计原则,将对象的创建和依赖管理交给容器处理,而非由代码直接控制。
核心思想: 依赖注入(DI):容器通过构造函数、Setter方法或字段注入依赖对象。 控制反转:将对象的生命周期管理交给框架或容器。
典型实现: Spring框架的IOC容器(如
ApplicationContext
)、Google Guice等。优势: 降低耦合度,提高代码可测试性和可维护性。
示例代码(Spring IOC):
@Service public class UserService {@Autowiredprivate UserRepository userRepository; }
AOP与IOC的关系
协同作用: IOC容器管理对象生命周期,AOP基于这些对象动态增强功能。 Spring框架通过IOC实现AOP,如代理对象的创建和依赖注入。
差异: IOC解决对象创建和依赖管理问题,AOP解决横切关注点分离问题。
四,怎么样定义一个bean对象,怎么样使用springboot定义bean对象
定义Bean对象
在Spring框架中,Bean是由Spring IoC容器管理的对象,可以通过XML配置、注解或Java配置方式定义。
方式1:使用@Component及其衍生注解
在类上添加@Component
注解或其衍生注解(如@Service
、@Repository
、@Controller
),Spring会自动扫描并注册为Bean。
import org.springframework.stereotype.Component;@Component
public class MyBean {// Bean的业务逻辑
}
方式2:使用@Bean注解(Java配置方式)
在配置类中使用@Bean
注解显式定义Bean,适用于第三方库的类或需要自定义初始化逻辑的Bean。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic MyBean myBean() {return new MyBean();}
}
方式3:XML配置方式(传统方式)
在applicationContext.xml
中定义Bean,适用于旧项目。
<bean id="myBean" class="com.example.MyBean"/>
在Spring Boot中使用Bean
Spring Boot简化了Bean的定义和注入过程,主要通过自动配置和依赖注入来管理Bean。
注入Bean的方式
1. 使用@Autowired自动注入
在需要依赖的字段、构造方法或Setter方法上使用@Autowired
,Spring会自动注入Bean。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate MyBean myBean; // 自动注入
}
2. 构造器注入(推荐方式)
通过构造函数注入依赖,避免@Autowired
,更符合依赖注入的原则。
@Service
public class MyService {private final MyBean myBean;public MyService(MyBean myBean) {this.myBean = myBean;}
}
3. 使用@Resource或@Inject(可选)
@Resource
(JSR-250)或@Inject
(JSR-330)也可用于依赖注入。
import javax.annotation.Resource;@Service
public class MyService {@Resourceprivate MyBean myBean;
}
验证Bean是否生效
可以通过ApplicationContext
获取Bean实例,或在单元测试中验证:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class MyApp {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(MyApp.class, args);MyBean myBean = context.getBean(MyBean.class); // 获取BeanSystem.out.println(myBean != null ? "Bean加载成功" : "Bean未找到");}
}
总结
- 定义Bean:使用
@Component
、@Bean
或XML配置。 - 注入Bean:推荐构造器注入,也可用
@Autowired
、@Resource
。 - Spring Boot优化:自动扫描
@SpringBootApplication
所在包及其子包,无需额外配置。
定义Bean对象
在Spring框架中,Bean是由Spring IoC容器管理的对象,可以通过XML配置、注解或Java配置方式定义。
方式1:使用@Component及其衍生注解
在类上添加@Component
注解或其衍生注解(如@Service
、@Repository
、@Controller
),Spring会自动扫描并注册为Bean。
import org.springframework.stereotype.Component;@Component
public class MyBean {// Bean的业务逻辑
}
方式2:使用@Bean注解(Java配置方式)
在配置类中使用@Bean
注解显式定义Bean,适用于第三方库的类或需要自定义初始化逻辑的Bean。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic MyBean myBean() {return new MyBean();}
}
方式3:XML配置方式(传统方式)
在applicationContext.xml
中定义Bean,适用于旧项目。
<bean id="myBean" class="com.example.MyBean"/>
在Spring Boot中使用Bean
Spring Boot简化了Bean的定义和注入过程,主要通过自动配置和依赖注入来管理Bean。
注入Bean的方式
1. 使用@Autowired自动注入
在需要依赖的字段、构造方法或Setter方法上使用@Autowired
,Spring会自动注入Bean。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate MyBean myBean; // 自动注入
}
2. 构造器注入(推荐方式)
通过构造函数注入依赖,避免@Autowired
,更符合依赖注入的原则。
@Service
public class MyService {private final MyBean myBean;public MyService(MyBean myBean) {this.myBean = myBean;}
}
3. 使用@Resource或@Inject(可选)
@Resource
(JSR-250)或@Inject
(JSR-330)也可用于依赖注入。
import javax.annotation.Resource;@Service
public class MyService {@Resourceprivate MyBean myBean;
}
验证Bean是否生效
可以通过ApplicationContext
获取Bean实例,或在单元测试中验证:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class MyApp {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(MyApp.class, args);MyBean myBean = context.getBean(MyBean.class); // 获取BeanSystem.out.println(myBean != null ? "Bean加载成功" : "Bean未找到");}
}
总结
- 定义Bean:使用
@Component
、@Bean
或XML配置。 - 注入Bean:推荐构造器注入,也可用
@Autowired
、@Resource
。 - Spring Boot优化:自动扫描
@SpringBootApplication
所在包及其子包,无需额外配置。
五,你所定义的bean对象是单例还是多例的
在Spring框架中,Bean的默认作用域是单例(Singleton),但也可以根据需求配置为多例(Prototype)或其他作用域。以下是具体说明:
单例模式(Singleton)
- 定义:Spring容器中每个Bean定义对应一个唯一的实例。
- 特点:所有请求该Bean的依赖注入都会返回同一个实例。
- 适用场景:无状态的Bean,如工具类、服务层(Service)、数据访问层(DAO)等。
- 配置方式:默认作用域,无需显式声明。也可通过注解或XML显式指定:
@Scope("singleton") @Component public class MySingletonBean { ... }
<bean id="myBean" class="com.example.MySingletonBean" scope="singleton"/>
多例模式(Prototype)
- 定义:每次请求Bean时都会创建一个新的实例。
- 特点:适用于需要维护状态的Bean,每次注入或调用
getBean()
都会生成新对象。 - 适用场景:有状态的Bean,如用户会话、请求处理类等。
- 配置方式:需显式声明作用域为
prototype
:@Scope("prototype") @Component public class MyPrototypeBean { ... }
<bean id="myBean" class="com.example.MyPrototypeBean" scope="prototype"/>
其他作用域
- Request/Session/Application:Web环境中可用的作用域,分别针对HTTP请求、会话或整个应用生命周期。
- 自定义作用域:通过实现
Scope
接口扩展。
选择建议
- 性能考虑:单例模式减少对象创建开销,但需注意线程安全问题。
- 状态管理:多例模式适合有状态的Bean,但会增加内存消耗。
通过合理选择作用域,可以平衡资源利用与业务需求。
接下来还有
mysql的索引,最左原则,mysql引擎,ajax,线程的生命周期,RocketMQ发送了延迟消息,消息跟丢了怎么办,发两次怎么办,synchronized有什么用,轻量级锁和重量级锁的区别,下次再发