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

Screenshot 2026-03-12 at 4.25.44 PM

@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

 

 

Screenshot 2026-03-12 at 5.52.42 PM

Step2: property poluation.

Screenshot 2026-03-12 at 5.52.48 PM
Screenshot 2026-03-12 at 5.52.53 PM
Screenshot 2026-03-12 at 5.52.25 PM

 


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?

synchronized block. (all the functions, property population, initializion....)
double-check locking (level2~level3 cache, not level1 cache), thread 1 locks this, so when thread 2 comes in, it is blocked.
twice getSingleton.
 
11 What Transaction Management Types Does Spring Support?
  • Programmatic Transaction Management,code
  • Declarative Transaction Management,xml

1)@Transactional

2)<tx> <aop>

3)interface

 

12 Spring Transaction Propagation Behaviors

 Transaction propagation defines how a transactional method should behave when called within the context of an existing transaction.
Often use REQUIRED for write, 
Often use SUPPORT for read

Screenshot 2026-03-12 at 7.24.37 PM

13 Spring Transaction 

AOP, parse advisor, try catch, autoCommit false

 

14 Spring Transaction Propagation Behaviors

 
15 Can Spring Multi-Threading Transactions Guarantee Consistency?
no, threadlocal, one thread, one transaction
 
16 Spring Transaction Failure Reasons
Screenshot 2026-03-12 at 10.00.47 PM

 

Kafka

 

1 Kafka Architecture

Screenshot 2026-03-13 at 12.37.11 PM

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. )

 

Screenshot 2026-03-13 at 12.48.00 PM

 

4 consumers (1 group, 6 consumers.)
each consumer consumes the same partition's topic.
 
5 producers
 
 
6 workflow
broker -> zooker -> controller (topic, has the newest route information)
consumer can find route information through topic, 
 
7 Kafka Zero-Copy 
Zero-copy is a technique that eliminates unnecessary data copying between kernel space and user space when transferring data from disk to network socket.
without zero-copy (4 copies)
disk -> page -> Application -> socket -> NIC
 
with zero->copy (2 copies)
disk -> page -> socket
 
8 How to Handle Massive Message Backlog in Kafka
  • 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.

newest learder election
replica data sync. when a replica can not catch up with leader, remove, will rejoin if it catches up.
fault-tolerance.
 
11. How Does Kafka Guarantee No Message Loss?
 
producer side: 
  • 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.

solutions:
  • 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

When Redis runs out of memory, it needs to evict (remove) some data to make room for new data. Redis provides 8 different eviction policies to handle this.
  • 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.

 

 

 
https://www.bilibili.com/video/BV1qSCLBjE6Q?spm_id_from=333.788.videopod.episodes&vd_source=8c42b55896f8a24fb4f65b7a3383faa1&p=20
 
posted @ 2024-02-23 12:02  ylxn  阅读(43)  评论(0)    收藏  举报