校招 Java 面试常见知识点解析及实战案例分享

校招Java面试常见知识点全解析(附实战案例)

一、Java新特性实战

1. Lambda表达式与Stream API

案例:统计电商订单中金额大于1000的订单数量

java 复制代码
import java.util.Arrays;
import java.util.List;

public class LambdaStreamDemo {
    public static void main(String[] args) {
        List<Order> orders = Arrays.asList(
            new Order(1, "20230601", 899.0),
            new Order(2, "20230602", 1299.0),
            new Order(3, "20230603", 1599.0),
            new Order(4, "20230604", 699.0)
        );

        // 使用Stream API过滤并统计
        long count = orders.stream()
                .filter(order -> order.getAmount() > 1000)
                .count();

        System.out.println("金额大于1000的订单数量: " + count);
    }
}

class Order {
    private int id;
    private String orderDate;
    private double amount;

    // 构造方法、Getter/Setter省略
}

面试考点:Lambda表达式语法、Stream的中间操作与终端操作、函数式接口

2. Optional类的使用

案例:处理可能为空的用户信息

java 复制代码
import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        User user = null;
        // 使用Optional避免空指针异常
        Optional<User> optionalUser = Optional.ofNullable(user);
        
        String username = optionalUser
                .map(User::getUsername)
                .orElse("Guest");
                
        System.out.println("用户名: " + username);
    }
}

class User {
    private String username;
    
    // 构造方法、Getter/Setter省略
}

面试考点:Optional的创建方式、常用方法(map/flatMap/filter/orElse/orElseThrow)

二、集合框架高级应用

1. List与Set的线程安全实现

案例:高并发场景下的商品ID集合处理

java 复制代码
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

public class ConcurrentCollectionDemo {
    public static void main(String[] args) {
        // 线程安全的List
        CopyOnWriteArrayList<String> productIds = new CopyOnWriteArrayList<>();
        
        // 线程安全的Set
        CopyOnWriteArraySet<String> uniqueProductIds = new CopyOnWriteArraySet<>();
        
        // 模拟多线程添加商品ID
        Runnable task = () -> {
            productIds.add("P" + System.currentTimeMillis());
            uniqueProductIds.add("P" + System.currentTimeMillis());
        };
        
        // 启动10个线程
        for (int i = 0; i < 10; i++) {
            new Thread(task).start();
        }
    }
}

面试考点:CopyOnWrite容器的原理、适用场景及优缺点

2. Map的性能优化

案例:使用ConcurrentHashMap实现本地缓存

java 复制代码
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class LocalCacheDemo {
    private static final ConcurrentHashMap<String, CacheObject> cache = new ConcurrentHashMap<>();
    
    public static void put(String key, Object value, long expireTime) {
        cache.put(key, new CacheObject(value, System.currentTimeMillis() + expireTime));
    }
    
    public static Object get(String key) {
        CacheObject cacheObject = cache.get(key);
        if (cacheObject != null && System.currentTimeMillis() < cacheObject.getExpireTime()) {
            return cacheObject.getValue();
        }
        return null;
    }
    
    static class CacheObject {
        private Object value;
        private long expireTime;
        
        // 构造方法、Getter省略
    }
}

面试考点:ConcurrentHashMap在JDK8中的优化、本地缓存的实现策略

三、多线程与并发编程

1. CompletableFuture异步编程

案例:电商订单的并行处理

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 异步处理订单支付
        CompletableFuture<Boolean> paymentFuture = CompletableFuture.supplyAsync(() -> {
            try {
                // 模拟支付处理
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return true;
        });
        
        // 异步处理订单库存
        CompletableFuture<Boolean> inventoryFuture = CompletableFuture.supplyAsync(() -> {
            try {
                // 模拟库存检查
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return true;
        });
        
        // 组合两个异步任务
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(paymentFuture, inventoryFuture);
        
        // 所有任务完成后执行后续操作
        CompletableFuture<String> resultFuture = allFutures.thenApply(v -> {
            if (paymentFuture.join() && inventoryFuture.join()) {
                return "订单处理成功";
            } else {
                return "订单处理失败";
            }
        });
        
        System.out.println(resultFuture.get());
    }
}

面试考点:CompletableFuture的常用方法、异步编程模式

2. 线程池的合理配置

案例:配置适合IO密集型任务的线程池

java 复制代码
import java.util.concurrent.*;

public class ThreadPoolConfigDemo {
    public static void main(String[] args) {
        // 计算CPU核心数
        int cpuCores = Runtime.getRuntime().availableProcessors();
        
        // 对于IO密集型任务,线程数可设置为CPU核心数的2倍
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                cpuCores * 2,         // 核心线程数
                cpuCores * 4,         // 最大线程数
                60L,                  // 空闲线程存活时间
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),  // 任务队列
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略
        );
        
        // 提交任务
        for (int i = 0; i < 20; i++) {
            executor.submit(() -> {
                try {
                    // 模拟IO操作
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 执行任务");
            });
        }
        
        executor.shutdown();
    }
}

面试考点:线程池参数配置、拒绝策略选择、任务队列类型

四、JVM性能调优实战

1. 内存溢出排查

案例:模拟堆内存溢出并分析

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class HeapOOMDemo {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        
        // 不断创建大对象,导致堆内存溢出
        while (true) {
            list.add(new byte[1024 * 1024]); // 每次创建1MB的数组
        }
    }
}

JVM参数配置

ruby 复制代码
java -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError HeapOOMDemo

排查步骤

  1. 使用工具(如VisualVM、MAT)分析堆转储文件
  2. 定位内存占用最大的对象
  3. 检查代码中是否存在内存泄漏或过度创建大对象的情况

2. 垃圾回收器选择

案例:针对不同场景选择合适的垃圾回收器

ruby 复制代码
# 新生代使用ParNew,老年代使用CMS
java -XX:+UseParNewGC -XX:+UseConcMarkSweepGC MainClass

# 使用G1垃圾回收器
java -XX:+UseG1GC -Xms4g -Xmx4g MainClass

# 使用ZGC垃圾回收器(JDK11+)
java -XX:+UseZGC -Xms8g -Xmx8g MainClass

面试考点:各垃圾回收器的特点、适用场景、调优参数

五、Spring与微服务实战

1. Spring Boot自动配置原理

案例:自定义starter开发

java 复制代码
// 自动配置类
@Configuration
@ConditionalOnClass(RedisTemplate.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
    
    @Autowired
    private RedisProperties properties;
    
    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 配置序列化方式等
        return template;
    }
}

// 配置属性类
@ConfigurationProperties(prefix = "my.redis")
public class RedisProperties {
    private String host = "localhost";
    private int port = 6379;
    
    // Getter/Setter省略
}

// META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.RedisAutoConfiguration

面试考点:@Conditional注解、@ConfigurationProperties、spring.factories文件

2. Spring Cloud微服务架构

案例:基于Spring Cloud的电商微服务系统

java 复制代码
// 服务注册与发现(Eureka Server)
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

// 服务提供者
@SpringBootApplication
@EnableEurekaClient
public class ProductServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductServiceApplication.class, args);
    }
}

// 服务消费者(使用OpenFeign)
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

// Feign客户端接口
@FeignClient(name = "product-service")
public interface ProductServiceClient {
    @GetMapping("/products/{id}")
    Product getProduct(@PathVariable("id") Long id);
}

面试考点:服务注册与发现、服务调用、断路器、配置中心

六、数据库与ORM框架

1. MyBatis高级应用

案例:使用MyBatis实现复杂查询

xml 复制代码
<!-- Mapper XML文件 -->
<select id="getUserOrders" resultMap="UserOrderResultMap">
    SELECT u.*, o.* 
    FROM users u
    LEFT JOIN orders o ON u.id = o.user_id
    WHERE u.id = #{userId}
</select>

<resultMap id="UserOrderResultMap" type="com.example.entity.User">
    <id property="id" column="u_id"/>
    <result property="username" column="u_username"/>
    <collection property="orders" ofType="com.example.entity.Order">
        <id property="id" column="o_id"/>
        <result property="orderNo" column="o_order_no"/>
        <result property="amount" column="o_amount"/>
    </collection>
</resultMap>

面试考点:MyBatis的映射配置、动态SQL、延迟加载

2. 数据库索引优化

案例:优化电商订单查询性能

sql 复制代码
-- 原查询(慢)
SELECT * FROM orders 
WHERE user_id = 123 
  AND order_status = 'PAID' 
  AND create_time > '2023-01-01'
ORDER BY create_time DESC
LIMIT 10;

-- 优化方案:创建复合索引
CREATE INDEX idx_user_status_time ON orders (user_id, order_status, create_time DESC);

索引优化原则

  1. 最左前缀匹配原则
  2. 索引列尽量避免计算和函数操作
  3. 区分度低的列不宜作为索引(如性别字段)

七、分布式系统实战

1. 分布式事务解决方案

案例:基于Seata的分布式事务管理

java 复制代码
// 业务服务实现
@Service
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private StorageService storageService;
    
    @Autowired
    private AccountService accountService;
    
    @GlobalTransactional // 开启全局事务
    @Override
    public void createOrder(Order order) {
        // 1. 创建订单
        orderMapper.insert(order);
        
        // 2. 扣减库存
        storageService.reduceStock(order.getProductId(), order.getCount());
        
        // 3. 扣减账户余额
        accountService.reduceBalance(order.getUserId(), order.getAmount());
    }
}

面试考点:Seata的AT模式、TCC模式、Saga模式

2. 分布式缓存应用

案例:使用Redis实现商品缓存

java 复制代码
@Service
public class ProductServiceImpl implements ProductService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private ProductMapper productMapper;
    
    @Override
    public Product getProductById(Long id) {
        String key = "product:" + id;
        
        // 先从缓存获取
        Product product = (Product) redisTemplate.opsForValue().get(key);
        
        if (product != null) {
            return product;
        }
        
        // 缓存未命中,从数据库获取
        product = productMapper.selectById(id);
        
        if (product != null) {
            // 放入缓存,设置过期时间
            redisTemplate.opsForValue().set(key, product, 30, TimeUnit.MINUTES);
        }
        
        return product;
    }
}

面试考点:缓存穿透、缓存击穿、缓存雪崩的解决方案

八、性能优化实战

1. 接口性能优化

案例:优化用户信息查询接口

java 复制代码
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 优化前:串行调用多个服务
    @GetMapping("/{id}/profile")
    public ResponseEntity<UserProfile> getUserProfile(@PathVariable Long id) {
        User user = userService.getUserById(id);
        List<Order> orders = orderService.getOrdersByUserId(id);
        Address address = addressService.getAddressByUserId(id);
        
        UserProfile profile = new UserProfile(user, orders, address);
        return ResponseEntity.ok(profile);
    }
    
    // 优化后:并行调用多个服务
    @GetMapping("/{id}/profile/optimized")
    public ResponseEntity<UserProfile> getUserProfileOptimized(@PathVariable Long id) {
        CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() -> 
            userService.getUserById(id)
        );
        
        CompletableFuture<List<Order>> ordersFuture = CompletableFuture.supplyAsync(() -> 
            orderService.getOrdersByUserId(id)
        );
        
        CompletableFuture<Address> addressFuture = CompletableFuture.supplyAsync(() -> 
            addressService.getAddressByUserId(id)
        );
        
        CompletableFuture.allOf(userFuture, ordersFuture, addressFuture).join();
        
        UserProfile profile = new UserProfile(
            userFuture.join(), 
            ordersFuture.join(), 
            addressFuture.join()
        );
        
        return ResponseEntity.ok(profile);
    }
}

性能对比

  • 优化前:接口响应时间约为各服务调用时间之和
  • 优化后:接口响应时间约为最长服务调用时间

2. 高并发场景限流

案例:使用Sentinel实现接口限流

java 复制代码
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    private static final String RESOURCE_KEY = "createOrder";
    
    @PostMapping
    public ResponseEntity<String> createOrder(@RequestBody OrderDTO orderDTO) {
        Entry entry = null;
        try {
            // 资源限流
            entry = SphU.entry(RESOURCE_KEY, EntryType.OUT, 1);
            
            // 业务逻辑
            orderService.createOrder(orderDTO);
            return ResponseEntity.ok("订单创建成功");
            
        } catch (BlockException e) {
            // 限流处理
            return ResponseEntity.status(429).body("请求过于频繁,请稍后再试");
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }
}

Sentinel配置

java 复制代码
// 初始化限流规则
private void initFlowRules() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource(RESOURCE_KEY);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // 设置QPS阈值为100
    rule.setCount(100);
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

九、单元测试与代码质量

1. JUnit 5与Mockito

案例:测试订单服务

java 复制代码
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
    
    @Mock
    private OrderRepository orderRepository;
    
    @Mock
    private PaymentService paymentService;
    
    @InjectMocks
    private OrderServiceImpl orderService;
    
    @Test
    public void testCreateOrderSuccess() {
        // 准备测试数据
        Order order = new Order();
        order.setId(1L);
        order.setAmount(100.0);
        
        // 设置mock行为
        when(paymentService.processPayment(any())).thenReturn(true);
        when(orderRepository.save(any())).thenReturn(order);
        
        // 执行测试
        Order result = orderService.createOrder(order);
        
        // 验证结果
        assertNotNull(result);
        assertEquals(1L, result.getId());
        
        // 验证方法调用
        verify(paymentService, times(1)).processPayment(order);
        verify(orderRepository, times(1)).save(order);
    }
}

面试考点:JUnit 5的注解、Mockito的mock与verify

2. 代码覆盖率工具

JaCoCo配置

xml 复制代码
<!-- pom.xml -->
<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.8</version>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <execution>
                    <id>report</id>
                    <phase>test</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

执行测试并生成报告

bash 复制代码
mvn clean test

报告生成路径:target/site/jacoco/index.html

十、项目实战案例

1. 电商秒杀系统设计

架构设计

  1. 流量削峰:使用Redis预加载库存,令牌桶限流
  2. 异步处理:订单处理放入MQ队列,异步扣减库存
  3. 防超卖:Redis原子操作扣减库存,数据库乐观锁防超卖
  4. 熔断降级:使用Sentinel熔断降级非核心服务

关键代码实现

java 复制代码
// 库存扣减(Redis实现)
public boolean deductStock(Long productId, int quantity) {
    String stockKey = "seckill:stock:" + productId;
    // 使用Lua脚本保证原子性
    String script = "if redis.call('get', KEYS[1]) >= ARGV[1] then " +
                    "  redis.call('decrby', KEYS[1], ARGV[1]) " +
                    "  return 1 " +
                    "else " +
                    "  return 0 " +
                    "end";
    Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), 
                                      Collections.singletonList(stockKey), quantity);
    return result != null && result == 1;
}

2. 社交系统消息推送设计

技术选型

  1. WebSocket实现实时推送
  2. Redis发布订阅实现消息广播
  3. 离线消息存储在MongoDB
  4. Kafka处理海量消息

核心代码

java 复制代码
// WebSocket处理器
@Component
public class WebSocketHandler extends TextWebSocketHandler {
    
    private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        if (userId != null) {
            sessions.put(userId, session);
        }
    }
    
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理消息
    }
    
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        if (userId != null) {
            sessions.remove(userId);
        }
    }
    
    // 推送消息
    public void pushMessage(String userId, String content) {
        WebSocketSession session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            session.sendMessage(new TextMessage(content));
        }
    }
}

总结

通过以上实战案例可以看出,校招Java面试不仅关注基础知识,更注重实际应用能力。建议同学们:

  1. 深入理解核心知识点的原理和应用场景
  2. 多动手实践,通过项目积累经验
  3. 学习使用开发工具和性能调优工具
  4. 关注技术发展趋势,了解最新技术动态

希望本文能帮助大家更好地准备Java校招面试,祝大家面试顺利!

以上内容补充了Java新特性、微服务、分布式系统等最新技术的实战案例,包含完整的代码实现和面试考点分析。每个章节都提供了可运行的示例代码和详细的解释,帮助你更好地理解和应用这些技术。


Java 基础,面向对象编程,集合框架,多线程,并发编程,IO 流,网络编程,Spring 框架,MyBatis, 数据库,MySQL,Spring Boot, 算法与数据结构,JVM, 校招面试



资源地址: pan.quark.cn/s/14fcf913b...


相关推荐
·云扬·1 分钟前
【PmHub面试篇】PmHub 整合 TransmittableThreadLocal(TTL)缓存用户数据面试专题解析
缓存·面试·职场和发展
ademen1 小时前
spring4第6课-bean之间的关系+bean的作用范围
java·spring
cccl.1 小时前
Java在word中指定位置插入图片。
java·word
kingbal1 小时前
Elasticsearch:spring2.x集成elasticsearch8.x
java·spring2.x·elastic8.x
三两肉3 小时前
Java 中 ArrayList、Vector、LinkedList 的核心区别与应用场景
java·开发语言·list·集合
clk66074 小时前
SSM 框架核心知识详解(Spring + SpringMVC + MyBatis)
java·spring·mybatis
shangjg36 小时前
Kafka 的 ISR 机制深度解析:保障数据可靠性的核心防线
java·后端·kafka
Alan3168 小时前
Qt 中,设置事件过滤器(Event Filter)的方式
java·开发语言·数据库
拉不动的猪8 小时前
TS常规面试题1
前端·javascript·面试
小鹭同学_8 小时前
Java基础 Day28 完结篇
java·开发语言·log4j