- 博客(34)
- 收藏
- 关注
原创 注解@Min
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZWmFb8U-1744882023189)(https://i.imgur.com/mXJzQgP.png)]等注解结合使用,确保数据符合业务规则。如果需要校验更复杂的规则(如自定义逻辑),可以进一步学习。规范中的一个注解,用于校验。
2025-04-17 17:27:44
378
原创 注解@NotNull
规范一起使用(如 Hibernate Validator 实现),在 Spring Boot 等框架中广泛用于数据校验。(Validation Annotation),用于标记字段、方法参数或返回值。如果需要更复杂的校验(如自定义规则),可以进一步学习。在 Swagger UI 中会标记该字段为。(Spring 中),可通过。
2025-04-17 17:16:11
854
原创 StringBuilder 和 append() 方法
多次拼接会产生大量中间对象,浪费内存和 GC 时间。,用于高效地拼接、修改字符串,而。是其最核心的方法之一。是 Java 提供的。
2025-04-08 09:53:03
390
原创 注解@RestController
是现代 Spring 应用中构建 RESTful 服务的核心注解,它简化了 API 开发流程,使开发者能够专注于业务逻辑而非样板代码。是 Spring MVC 框架中的一个关键注解,用于标记一个类作为 RESTful Web 服务的控制器。的组合注解,专门为构建 REST API 设计。Spring 会根据请求的。
2025-04-07 17:28:57
366
原创 注解@Slf4j
是 Lombok 提供的一个实用注解,用于简化 Java 项目中的日志记录。它自动为类生成一个 SLF4J 的日志对象,让你可以直接使用 变量进行日志记录,而无需手动声明。实现原理Lombok 会在编译时自动生成以下代码:支持的日志级别通过 变量可以使用所有标准日志级别方法:优势减少样板代码:无需手动声明日志对象一致性:确保所有类使用相同的日志记录方式可读性:使业务代码更加简洁清晰使用前提项目中必须添加 Lombok 依赖需要 SLF4J 的实现(如 Logback、Log4
2025-04-07 17:09:04
567
原创 toString()
是 Java 中一个非常重要的方法,定义在 类中,所有 Java 类都继承了这个方法。默认实现在 类中的默认实现是:这会返回:使用 StringBuilder(性能更好)4. 最佳实践包含所有重要字段:但排除敏感信息(如密码)格式一致:保持一致的输出格式避免复杂逻辑:toString() 应该简单快速考虑性能:对于复杂对象,使用 StringBuilder文档说明:在方法注释中说明输出格式5. IDE 自动生成大多数 IDE 可以自动生成 toString() 方法:Ecl
2025-04-07 16:33:53
316
原创 字符串常量NONE
这种常量定义在业务逻辑中广泛使用,是 Java 开发中的基础实践。:多个类共享同一常量,避免重复定义。:常量仅在当前类中使用。
2025-04-07 15:54:39
439
原创 MySQL 深入浅出系列05—优化特定类型的查询
两种非常不同的作用:它可以统计某个列值的数量,也可以统计行数。(不统计 NULL)。如果在 COUNT() 的括号中指定了列或者列的表达式,则统计的就是这个表达式有值的结果数。。当 MySQL 确认括号内的表达式值不可能为空时,实际上就是在统计行数。最简单的就是当我们使用COUNT(*) 的时候,这种情况下通配符*并不会像我们猜想的那样扩展成所有的列, 会忽略所有列直接统计所有的行数。MyISAM 的 COUNT() 函数快的前提条件是,因为此时无须实际地去计算表的行数。
2024-03-15 22:22:16
647
原创 MySQL 深入浅出系列03—索引的基础
索引(MySQL 中也叫做“键”)是存储引擎用于快速找到记录的一种数据结构。数据量越大,索引对性能影响越大。
2024-03-15 12:21:22
168
原创 MySQL 深入浅出系列02—范式和反范式
在范式化的数据库中,每个事实数据会出现并且只出现 一次。相反,在反范式化的数据库中,信息是冗余的, 可能会存储在多个地方。
2024-03-15 00:16:52
449
原创 JUC 进阶成神系列08—共享模型之无锁
线程保证volatile变量都是直接操作主存,即一个线程对volatile变量的修改,对另一个线程可见。如果没有,虽然不会进入阻塞,但由于没有分到时间片,仍然会进入可运行状态,还会导致上下文切换,因此CAS需要多核CPU才能发挥优势,才能不发生上下文切换。过程中将A改成B,再将B改成A,再将A改成C。无锁情况下,即使重试失败,线程始终在高速运行没有停歇,而synchronized会让线程在没有获得锁的时候,发生上下文切换进入阻塞。的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,再重试。
2024-03-14 17:37:28
356
原创 JUC 进阶成神系列07—共享模型之内存
Clock Cycle Time(cpu 的时钟周期时间),等于主频的倒数,是 cpu 能识别的最小时间单位,比如 4G 主频的 cpu 的 Clock Cycle Time 就是 0.25ns,作为对比,我们墙上挂钟的 Cycle time 是 1s。例如,运行一条加法指令一般需要一个时钟周期时间。线程对volatile变量的写(写入主存中,读写操作都是以主存中去读),对接下来其他线程对该变量的读可见。线程start前对变量的写,对该线程开始后(线程还没启动写入的变量,在线程启动以后)对该变量的读可见。
2024-03-14 17:20:03
319
原创 JUC进阶成神系列06—线程安全之ReentrantLock
try 块写的是要保护的临界区的代码,finally 块是为了将来无论有没有出现异常都能正确释放对象的锁,释放锁就是调用 unlock 方法。默认的 synchronized 和 ReentrantLock 的 Lock 方法也好,它们都是不可打断的,这种情况别人持有锁,我需要获得锁,就需要一直等待下去。本意是为了解决饥饿问题,但没必要,后面讲源码再细讲。比如哲学家就餐问题,一人一只筷子的死锁问题,(先入先得,公平锁),释放筷子让别人拿到就能解决死锁。先入先得,用得少,影响性能,其他方法一般都是非公平的。
2024-03-14 16:47:03
280
原创 JUC 进阶成神系列05—线程安全之 Park&Unpark
Park&Unpack 是以线程为单位来阻塞和唤醒线程,而 notify 只能随机唤醒一个等待线程,notifyAll 是唤醒所有等待线程,就不那么精确。检查_conter,本情况为 1,这时线程无需阻塞,继续运行,设置_counter 为 0。唤醒_cond 条件变量中的 Thread_0,线程恢复运行,运行之后又把干粮吃掉,设置_counter 为 0。线程:旅人,Parker:背包,条件变量:背包中的帐篷,_counter:背包中的备用干粮(0为耗尽,1为充足)备用干粮充足,不需停留,继续前进。
2024-03-14 16:21:58
317
原创 JUC进阶成神系列04—线程安全之 wait notify
obj.wait()让进入 object 监视器的线程到 waitSet 等待。**wait()**方法会释放对象的锁,进入 WaitSet 等待区,从而让其他线程就机会获取对象的锁。
2024-03-14 16:10:07
419
原创 JUC 进阶成神系列03—线程安全之 synchronized
这里的线程安全指的是,多个线程调用它们同一个实例的某个方法时,是线程安全的。加锁与不加锁得分相近的原因:JIT即时编译器会对字节码进行进一步优化,对java代码是用解释的方法执行,但是对热点代码反复调用的方法会进行优化,手段是分析看局部变量是不是能优化,根本不可能逃离方法作用范围,不可能被共享,synchronized 解决方案即俗称的对象锁,采用互斥的方式让同一时刻最多只有一个线程能持有对象锁,其他线程再想获取这个对象锁就会阻塞,保证拥有锁的线程可以安全执行临界区代码,不用担心上下文切换。
2024-03-14 15:55:17
286
原创 JUC 进阶成神系列02—Java 与线程
狭义上的用户线程指的是完全建立在用户空间的线程库上,系统内核不能感知到用户线程的存在及如何实现的。HotSpot:它的每一个Java线程都是直接映射到一个操作系统原生线程来实现的,而且中间没有额外的间接结构,所以HotSpot自己是不会去干涉线程调度的(可以设置线程优先级给操作系统提供调度建议),全权交给底下的操作系统去处理,所以何时冻结或唤醒线程、该给线程分配多少处理器执行时间、该把线程安排给哪个处理器核心去执行等,都是由操作系统完成的,也都是由操作系统全权决定的。
2024-03-14 15:07:12
461
原创 JUC 进阶成神系列01—进程与线程
并发:单核CPU下,线程CPU串行执行,任务调度室将CPU时间片-最小15毫秒,切换非常快,肉眼察觉不到,“微观串行,宏观并行”,线程轮流使用CPU。线程通信简单,更轻量级,线程上下文切换比进程切换比底本低。程序由指令和数据组成,指令需要运行就要加载到CPU,数据需要读写就要加载到内存,进程就是加载指令、管理内存、管理IO的。进程有共享资源,供内部线程共享。线程共享进程内的内容,比如多个线程可以访问同一个共享变量。并行:多核CPU下,每个核都可以调度运行线程。线程存在于进程中,是进程的子集。
2024-03-14 14:29:22
179
原创 JVM 夯实基础系列05—经典垃圾收集器详解
相比起来CMS的卡表就相当简单, 只有唯一一份,而且只需要处理老年代到新生代的引用,反过来则不需要,由于新生代的对象具有朝生夕灭的不稳定性,引用变化频繁,能省下这个区域的维护开销是很划算的。浮动垃圾:在CMS的并发标记和并发清理阶段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分 垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们,只好留待下一次垃圾收集时再清理掉。G1是一个面向全堆的收集器,不再需要其他新生代收集器的配合工作。
2024-03-13 16:02:20
351
原创 JVM 夯实基础系列04—栈帧和方法调用
“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行结束的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
2024-03-12 22:23:10
1602
原创 JVM 夯实基础系列03—类加载机制
Java 虚拟机把描述类的数据从 Class 文件中加载到内存,并对数据进行检验、转换解析和初始化,最终变成可以被虚拟机直接使用的 Java 类型的过程叫虚拟机类加载机制。
2024-03-12 14:47:49
700
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人