Java

浏览该分类下的所有文章

面试篇【一】

文章系统梳理了面试常考的技术要点:Spring AOP 动态代理实现原理、JDK8 前后 HashMap 与 ConcurrentHashMap 的结构与扩容机制、线程池大小的 CPU/IO 区分、G1 垃圾回收特性与 OOM 排查、MySQL 事务隔离级别及默认 REPEATABLE_READ、SQL 慢查询优化、缓存穿透/击穿/雪崩的原因与防御、LRU 实现、JVM 堆参数设置、栈队列应用、InnoDB 与 B+ 树索引、MVCC 与 undo log 原理以及索引失效情形。

IDEA 2022.2版本新特性

IDEA 2022.2 引入远程开发模式,后端部署在服务器,前端 thin client 本地使用,通过 SSH 分担重任务提升流畅度;全面支持 Spring 6 与 Spring Boot 3,包括 @AutoConfiguration、@ConfigurationProperties 等新特性;新增 ⌃⇧. /⌃⇧, 快捷键全局调节编辑器字体大小;JSON、YAML、properties 中的 http/https 链接可直接点击打开或生成 HTTP 请求;实验性 GraalVM 原生调试器支持调试本地镜像;Bean Validation 注解的消息属性支持引用与折叠;其他改进包括 Groovy 集成查询、升级内置 Kubernetes/Docker、运行当前文件无需配置、导入受信任 SSL 证书、HTTP 客户端优化、JBR11→JBR17、代码检查与补全增强等。

解决SpringBoot打成jar包无法加载resources下文件的问题

文章介绍了SpringBoot 打成 jar 包后在 Linux 环境中无法直接读取 resources 目录下文件(如 application.yml、ip2region.db)的常见问题,并提供了解决方案。核心思路是使用 Spring 提供的 PathMatchingResourcePatternResolver 获取资源对象,再通过 Apache Commons IO 的 FileUtils.copyInputStreamToFile 将资源流写入本地文件,从而实现对 jar 包内部资源的读取。文中给出完整代码示例,并列出所需的核心依赖(spring‑core 与 commons‑io),帮助开发者在部署时顺利加载 resources 中的文件。

StringUtils部分API的用法与区别

本文系统演示了 Apache Commons‑Lang3 中 `StringUtils` 常用判断 API 的使用差异。通过示例代码说明:`isEmpty` 只判断 null 与空串,不把空格算作空;`isAnyEmpty` 任意参数为 null/空串即返回 true;`isNoneEmpty` 与 `!isAnyEmpty` 等价,所有参数均非空才为 true;`isBlank` 同时把空格视为空值;`isAnyBlank`、`isNoneBlank` 分别检测是否存在或全部不存在空格或空值。文末列出 `StringUtils` 其它常用方法(trim、equals、startsWith、split、replace、pad 等)并提供官方文档链接,帮助读者快速选用合适的字符串工具。

过多赠予,无所适从

本文以 Spring @Autowired 为例,解析“required a single bean, but 2 were found”错误的根源——在容器中存在同类型的多个 Bean,且缺乏 @Primary、@Priority 或名称匹配等优先级标识,导致 Spring 无法决定注入对象。通过源码剖析展示了 Bean 的实例化与属性填充过程以及 AutowiredAnnotationBeanPostProcessor 的工作原理。解决思路包括为其中一个实现加 @Primary、使用 @Qualifier 或通过属性名与 Bean 名称精确匹配等方式,以明确注入目标,进而消除冲突。

原型 Bean 被固定

Spring 中把 @Service 标记为原型(@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE))的 Bean 注入到单例 @RestController 的字段时,Autowired 只在容器创建控制器时一次性实例化并固定该对象,导致原型作用失效并出现启动错误。源码分析显示 AutowiredAnnotationBeanPostProcessor 在 populateBean 阶段通过反射把找到的 Bean 直接赋值给字段,后续不再重新获取。解决办法有两种:①注入 ApplicationContext 并在方法中调用 applicationContext.getBean(ServiceImpl.class) 每次获取新实例;②在控制器中声明带 @Lookup 的抽象方法 getServiceImpl(),Spring 利用 CGLIB 生成子类并在调用时从 BeanFactory 动态获取原型 Bean。两种方式均能保证每次请求得到新的 ServiceImpl。文章还解释了 @Lookup 的实现原理以及 Spring 通过反射和方法覆盖实现原型注入的细节,提醒使用者注意单例‑原型混用的潜在陷阱。

定义的 Bean 缺少隐式依赖

文章指出,Spring 在创建标记为 @Service(或其他注解)的 Bean 时,如果该类显式声明了构造器,容器会依据构造器参数类型自动在 BeanFactory 中查找对应的 Bean 并注入。若参数(如 String)没有相应的 Bean,Spring 在 AbstractAutowireCapableBeanFactory#createBeanInstance → autowireConstructor → resolveDependency 过程中抛出 “Parameter … could not be found” 异常。解决办法是为构造器参数提供相应的 Bean(如通过 @Bean 定义 String serviceName()),或避免出现多个可选构造器导致歧义。文章提醒开发者不要把 Spring Bean 当作普通对象直接 new,需了解其隐式依赖规则,以免出现装配失败。

隐式扫描不到 Bean 的定义

Spring Boot 启动类使用 @SpringBootApplication 时,内部的 @ComponentScan 若未指定 basePackages,会默认扫描启动类所在的包。将 Controller 移到其他包后超出默认扫描范围,导致 Bean 找不到,应用失效。解决办法是显式配置扫描路径,如在启动类上添加 @ComponentScan("com.zou.controller"),或使用 @ComponentScans 指定多个包。需要注意显式指定后默认包不再被扫描,避免遗漏。

Java8新特性之Stream流

Stream 是 Java 8 处理集合的核心抽象,提供惰性求值、不可变数据源、可并行执行等特性。文章先介绍了 Stream 的分类(无状态/有状态、短路/非短路),随后列举了五种常用创建方式:Collection 的 stream()/parallelStream()、Arrays.stream、Stream.of/iterate/generate 以及 BufferedReader.lines、Pattern.splitAsStream。接着详细说明了中间操作——filter、limit、skip、distinct、map、flatMap、sorted、peek 等的使用场景和示例。随后阐述了终止操作,包括匹配/查找(allMatch、anyMatch、findFirst 等)、规约(reduce)以及收集(collect),并通过 Collectors 提供的 toList、toSet、toMap、joining、counting、summing、averaging、summarizing 等方法展示了如何将流结果转化为常用容器或统计信息。全文以代码示例为主,帮助读者快速掌握 Stream 的创建、转换、过滤、排序、终止及收集全过程。

全面拥抱Java17!

Java 17作为自Java 11后的第二个 LTS 版本,带来了多项语法升级。文章围绕九个核心特性展开:文本块简化多行字符串;switch 表达式支持返回值、箭头语法和 yield;record 让不可变数据类一行声明;sealed class 通过 permits 限定子类继承范围;instanceof 模式匹配在判断时直接完成类型转换并绑定变量;Helpful NullPointerExceptions 在 NPE 报错中指明空值来源;以及日期周期、紧凑数字格式化的改进和 Stream.toList() 的便捷集合创建。通过示例代码,作者展示了这些新特性提升可读性、简化代码与调试效率,鼓励 Java 开发者全面迁移至 Java 17。

基于SpringBoot的在线招聘网站

本文介绍了一个基于SpringBoot的在线招聘系统的整体设计与功能实现。系统采用SpringBoot、MyBatisPlus、Layui、MySQL、Redis、Shiro、WebSocket、Thymeleaf等技术栈,分为游客、求职者、HR和管理员四类角色。游客可浏览首页;求职者可进行职位检索、查看详情、在线聊天、生成并分享简历链接,且支持个人信息和密码修改;HR可管理公司信息、发布/编辑/下线岗位、管理员工、与求职者聊天并点击职位或简历链接;管理员提供用户、简历、公司、岗位的全局管理、聊天记录监控及封禁违规用户等后台功能。整体实现了职位查询、即时通讯、敏感词过滤及权限控制等核心业务。

面试现场【Spring篇】

本文系统梳理了 Spring 面试常见知识点:列举了 Spring 使用的工厂、代理、单例、模板方法、观察者、适配器等设计模式;概述了 Core、Context、Web、MVC、DAO、ORM、AOP 等核心模块;阐释 IOC/DI 的本质、BeanFactory 与 ApplicationContext、FactoryBean 的区别以及 @Repository、@Service、@Component、@Controller 的分层意义;介绍 AOP 的概念、通知类型、动态/静态代理及 JDK 与 CGLIB 的实现差异,并比较 Spring AOP 与 AspectJ AOP;详细说明 Bean 的四阶段生命周期、三级缓存如何解决单例循环依赖以及为何需三级缓存;对比 @Autowired 与 @Resource 的注入策略;梳理 Spring 事务的五种隔离级别和七种传播行为;最后解析 Spring Boot 自动装配的 EnableAutoConfigurationImportSelector、spring.factories 与条件过滤机制。