interviews SpringMVC + Kafka+redis
SpringMVC是 Spring提供的用于简化web开发的框架。

1.5 Servlet
Servlet能够响应请求的对象。接收请求,返回响应
SpringMVC可以认为是Servlet的封装。

1.6 SpringMVC开发流程回顾
各种配置。Controller,DispatchServlet,
1.9 url-pattern配置及原理剖析
静态资源配置
<mvc:default-servlet-handler/>
<resources location="classpath:/" mapping="resources/**">
1.10 数据处理机制Model、Map及ModelMap
用ModelMap传输局
1.11 请求参数绑定 (就是url上的参数)
http协议,超文本传输协议
1.12 简单类型参数
可以一致可以不一致,添加注解
1.13 绑定POJO及包装类型参数回顾
- Pojo,属性名要对应
- 形参名无所谓
- 嵌套pojo 就是包装类型
1.14 接受日期类型参数
- 可以定义converter转换
- 配在springmvc.xml 配置转换
1.15 深刻理解Rest风格
1)Rest风格请求是什么样的?
事例. rest是一个URL请求的风格,基于这种风格设计请求的Url。没有Rest的话,
http://localhost:8080/user/.action?id=3
有了rest风格之后,rest中认为互联网中的所有东西都是资源,就会有一个Uri标识。根据请求方式不同有不同的操作动作
用占位符表示参数
1.19 拦截器监听器
作用:
- 做一些初始化工作
- 监听web的特定事件,比如监听session
- 拦截器:拦截handler
1.20 单个拦截器
四线接口 HandlerInterceptor
- preHandle. 往往在这里完成权限校验, 默认不通过 false,需要修改值
- postHandle
- afterCompletion
2.1 手写MVC框架值原理回顾

@Override public void init(ServletConfig config) throws ServletException { //加载配置文件 String location = config.getInitParameter("contextConfigLocation"); doLoadConfig(location); //扫描相关的类 doScan(""); //初始化相应Bean对象,实现IoC容器 doInstance(); //实现依赖注入 doAutoWired(); //构造一个handlerMapping处理器,映射器,将配置好的url和Method建立关系 initHandlerMapping(); System.out.println("Dispatcher init finish"); }
2.4 doScan把设置需要扫描的路径下面的Controller类名存起来
private void doScan(String packagePath) { String scanPackagePath = Thread.currentThread() .getContextClassLoader() .getResource("") .getPath() + packagePath.replaceAll("\\.", "/"); File pack = new File(scanPackagePath); File[] files = pack.listFiles(); for (File file : files) { if (file.isDirectory()) { doScan(packagePath + "." + file.getName()); } else if (file.getName().endsWith(".class")) { String className = packagePath+ "." + file.getName().replaceAll(".class", ""); classNames.add(className); } } } //加载配置文件 private void doLoadConfig(String location) { InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream(location); try { properties.load(resourceStream); } catch (Exception e) { e.printStackTrace(); } }
2.5 initHandlerMapping, 把url和对应处理方法存起来
private void initHandlerMapping() { for (Map.Entry<String, Object> entry : ioc.entrySet()) { Class<?> clazz = entry.getValue().getClass(); if (clazz.isAnnotationPresent(LagouController.class)) { String baseUrl = ""; if (clazz.isAnnotationPresent(LagouRequestMapping.class)) { LagouRequestMapping annotation = clazz.getAnnotation(LagouRequestMapping.class); baseUrl = annotation.value(); } Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.isAnnotationPresent(LagouRequestMapping.class)) { LagouRequestMapping methodAnnotation = method.getAnnotation(LagouRequestMapping.class); String methodUrl = methodAnnotation.value(); String url = baseUrl + methodUrl; handlerMapping.put(url, method); } } } } }
2.6 doAutoWired, 把Autowired对应的实例存起来
private void doAutoWired() { if (ioc.isEmpty()) { return; } //有对象再依赖注入处理 for (Map.Entry<String, Object> entry : ioc.entrySet()) { Field[] declares = entry.getValue().getClass().getDeclaredFields(); for (Field field : declares) { if (field.isAnnotationPresent(LagouAutoWired.class)) { LagouAutoWired annotation = field.getAnnotation(LagouAutoWired.class); String beanName = annotation.value(); if ("".equals(beanName.trim())) { beanName = field.getType().getName(); } field.setAccessible(true); try { field.set(entry.getValue(), ioc.get(beanName)); } catch (Exception e) { e.printStackTrace(); } } } } }
2.7 实现ioc容器 (存controller,service,的实例,service有注解,找对应的interface,然后把interface对应上service实例)
private void doInstance() { if (classNames.isEmpty()) return; try { for (String className : classNames) { //DemoController Class<?> clazz = Class.forName(className); //区分controller 和 service if (clazz.isAnnotationPresent(LagouController.class)) { //controller id不处理 String simpleName = clazz.getSimpleName(); String lowerName = lowerFirstAlpha(simpleName); ioc.put(lowerName, clazz.newInstance()); } else if (clazz.isAnnotationPresent(LagouService.class)) { LagouService annotation = clazz.getAnnotation(LagouService.class); //获取注解值 String beanName = annotation.value(); if (!"".equals(beanName.trim())) { ioc.put(beanName, clazz.newInstance()); } else { beanName = lowerFirstAlpha(clazz.getSimpleName()); ioc.put(beanName, clazz.newInstance()); } // service 是有接口的, 放入ioc Class<?>[] interfaces = clazz.getInterfaces(); for (Class<?> inter : interfaces) { ioc.put(inter.getName(), clazz.newInstance()); } } } } catch (Exception e) { e.printStackTrace(); } }
2.8 doScan 扫描包,存入class的路径
private void doScan(String packagePath) { String scanPackagePath = Thread.currentThread() .getContextClassLoader() .getResource("") .getPath() + packagePath.replaceAll("\\.", "/"); File pack = new File(scanPackagePath); File[] files = pack.listFiles(); for (File file : files) { if (file.isDirectory()) { doScan(packagePath + "." + file.getName()); } else if (file.getName().endsWith(".class")) { String className = packagePath + "." + file.getName().replaceAll(".class", ""); classNames.add(className); } } }
2.9 doLoadConfig 把配置文件放入内存
private void doLoadConfig(String location) { InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream(location); try { properties.load(resourceStream); } catch (Exception e) { e.printStackTrace(); } }
Spring
1 The lifecycle of a Java Bean
- Instantiation. Create an instance, use java reflection.
- Property Population: emp: name. circular dependency
- initialization. Aware, lifecycle
- Destruction. close
2 The advantages of Singleton Beans are:
- reduce object creation
- memory conservation
3 Is Spring Bean Thread-Safe?
- stateless (don't write change, the class members) is thread-safe.
- state, is not thread-safe
4 how to let bean be thread-safe
- not singolaton
- threadlocal
- stateless design
- use thread-safe classes
5 How Many Ways to Instantiate Beans in Spring?
- xml
- FactoryBean
- Annotation Based, Controller, Service, Repository, Component, Bean (for third party)
- Programmatic instantiation

@Bean is on method
6 Limitations of Autowired
-
Ambiguity with Multiple Beans of Same Type
-
Primitive Types and Strings Cannot Be Auto-Wired
7 How Many Ways to Use @Autowired in Spring?
- setter
- no
- byName, set
8 How Does Spring Solve Circular Dependencies?
@Component public class A { private B b; public A(B b) { // A depends on B this.b = b; } } @Component public class B { private A a; public B(A a) { // B depends on A this.a = a; } }
Solution: 3 level cache (map)
level1 : singletonObjects, beans are ready to use
level2: earlySingletonObjects, created but not fully initialized
level3: singletonFactories, can create early beans references
|
Step2: property poluation. |
![]() |
![]() |
|
use level2 cache can solve circle reference, but use aop duplicately.
Prototype-scoped bean can not solve circle reference, because it doesn't use 3 cache.
use lacy to solve construction problem.
9 What Extension Points Does Spring IoC Have?
- bean lifecycle
- bean definition
- configuration
- context events
- conditional
- factory
10 How Does Spring Avoid Getting Incomplete Beans in Concurrent Scenarios?
- Programmatic Transaction Management,code
- Declarative Transaction Management,xml
1)@Transactional
2)<tx> <aop>
3)interface
12 Spring Transaction Propagation Behaviors

13 Spring Transaction
AOP, parse advisor, try catch, autoCommit false
14 Spring Transaction Propagation Behaviors
Kafka
1 Kafka Architecture

zookeep is replaced by kraft, store consumers offset, elect leaders, control brokers.
read and write data are all leaders.
2 offset
topic -> partition -> offset, each partition has an offset.
3 borkers, (5 brokers, 3 replicas, 6 partations, peek QPS is 1000, 300QPS to process, so it is 3~4, add 2 extra partitions for future business growing. )

- checklog
- increase consumers, resources (short term)
- increase poll size, interverals (short term)
- improve the consumers processing speed
- rest offset
- Create Dead Letter Queue (DLQ) for Slow Messages
9 how does kafka generate message order?
-
Kafka only guarantees order within a partition, not across partitions
- Ensure Same Key Goes to Same Partition
-
Single-Threaded Partition Consumption
10 isr
ISR (In-Sync Replica) is one of the most important concepts in Kafka for ensuring data durability and consistency. Let me explain it in detail.
ISR refers to the set of replicas that are fully caught up with the leader partition.
- acks. props.put("acks", "all"); // Wait for all in-sync replicas to acknowledge
-
B. Enable Idempotence
-
Send with Callbacks
- retry.
broker side:
- isr
- store in dist,
- ack. (leader and replica all receive message.)
consumer
- exactly-once semantics
- mannual commit
12 How Does Kafka Guarantee Message Consumption Order?
- Kafka guarantees order only within a single partition during consumption
-
A. Single Consumer per Partition
-
C. Key-Based Processing with Partitioning
-
multiple threads. blockingqueue.
Redis
1 redis storage data types
- int
- list
- string
- map
- set
2 cache avalancce
Cache Avalanche is a critical failure scenario in distributed systems where a large number of caches expire simultaneously or a cache cluster fails all at once, causing massive requests to hit the database directly.
solutions:
- set expire time randomly
- hot data are set two differnet clusters
- when cache is nearly expired, run some tasks to reset the expiration
3 cache pentration
Cache Penetration (also called Cache Bypass) is a scenario where a system keeps querying non-existent data, causing requests to bypass the cache and hit the database directly every time.
solution:
- cache null
- Bloom Filter, (all valid keys, in a map)
- parameter validation
4 cache Breakdown
Cache Breakdown (also called Cache Hotspot Invalidation) is when a popular cache key expires at a bad time, causing massive concurrent requests to hit the database simultaneously.
- mutex locks (query the database)
- never expirting data + background update
- early refresh
5 why redis is so fast
- in memory storage
- single-threaded, no context switching
- simple data structure
- non-blocking i/o
6 Redis Data Eviction Policies
- lru
- lazy
- run scheduled tasks
7 cache and memcached
- redis some on disks, memcached all on cache,
- redis proptacal is different, data size
8 redis also support transaction
always is atomic. consistent, isolated.




浙公网安备 33010602011771号