- 博客(284)
- 资源 (2)
- 收藏
- 关注
原创 树的遍历算法-java实现
本文介绍了二叉树的四种基本遍历方法(前序、中序、后序和层次遍历)的Java实现。包括递归和迭代两种实现方式:1)递归实现简洁明了;2)迭代实现使用栈或队列数据结构。给出了完整的节点类定义、遍历算法实现代码和使用示例,并总结了各遍历方法的访问顺序特点。这些遍历方法在树操作中具有重要应用价值。
2026-01-28 14:00:00
285
原创 用java代码详解递归算法
递归是函数直接或间接调用自身的编程方法,通过分解问题为更小的相似子问题来解决。其核心包括基线条件(终止条件)和递归步骤(问题分解)。典型应用包括数学计算(阶乘、斐波那契数列)、数据结构操作(树遍历)以及分治和回溯算法。示例展示了Java实现阶乘、斐波那契和二叉树前序遍历。优点是代码简洁,适合递归结构;缺点是可能栈溢出和效率低下,可通过记忆化或迭代优化。
2026-01-28 07:00:00
710
原创 java volatile、指令重排序、内存屏障
指令重排序是编译器和处理器优化执行效率的技术,在不改变单线程结果的前提下调整指令顺序。主要发生在JIT编译和CPU执行阶段,可能导致多线程程序出现可见性和有序性问题。例如,两个线程分别执行writer()和reader()方法时,由于重排序可能导致reader线程读取到未更新的变量值。解决方案是使用volatile或synchronized等同步机制,它们通过插入内存屏障来禁止特定重排序,确保多线程程序的正确执行顺序和变量可见性。理解重排序机制对掌握Java内存模型和高并发编程至关重要。
2026-01-27 14:00:00
547
原创 编译原理-BNF 巴科斯-诺尔范式
我们来用BNF定义一个非常简单的语言,它只支持整数和加法。(就是加号本身)0123456789什么是数字?一个数字是一位0到9的整数。<数字> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9什么是整数?整数由至少一个数字组成(比如112305<整数> ::= <数字> # 一位数 | <整数> <数字> # 多位数(一个整数后面再接一个数字)什么是表达式?一个表达式可以是一个整数,或者一个表达式加上另一个整数。
2026-01-27 11:08:52
635
原创 好书分享:《两周自制脚本语言》-用java实现一个脚本语言
本文介绍了如何用Java实现《两周自制脚本语言》中的Stone脚本语言,揭示编程语言设计的核心机制。首先解析脚本语言的基础概念和核心组件,包括词法分析、语法分析、解释执行和环境管理。然后详细讲解Stone语言的Java实现过程,涵盖词法分析器、语法树构建、解释执行和变量作用域管理。重点讨论了函数、闭包和面向对象等特性的实现方法,并分析了性能优化和错误处理等挑战。通过该项目,读者可以深入理解语言设计原理,为进一步扩展类型系统或优化性能奠定基础。
2026-01-27 10:45:24
1562
原创 java sleep()和wait()方法的区别
摘要:sleep()和wait()是Java中线程控制的两种方法,核心区别在于锁的处理。sleep()是Thread类的静态方法,使线程休眠但不释放锁;wait()是Object类的实例方法,使线程等待并释放锁,必须在同步代码块中使用。sleep()用于单纯暂停线程,wait()用于线程间协作。示例显示sleep()期间其他线程无法获取锁,而wait()会立即释放锁,待notify()唤醒后才重新竞争锁。关键区别可归纳为:sleep()不释放锁,wait()释放锁用于线程通信。
2026-01-27 07:00:00
348
原创 Java线程状态&与操作系统进程的映射关系
摘要:Java线程的生命周期在JVM层面定义了6种抽象状态(NEW、RUNNABLE、BLOCKED等),而实际执行依赖操作系统原生线程的调度。JVM采用1:1线程模型,将Java线程映射为OS线程,其中RUNNABLE状态对应OS的就绪和运行状态,BLOCKED/WAITING状态对应OS的阻塞状态。这种抽象屏蔽了底层差异,实现了跨平台一致性,使开发者只需关注高级线程管理,而将CPU调度交由操作系统处理。
2026-01-26 09:00:09
746
原创 Executors 四种线程池的用法、使用场景、注意事项
摘要:Executors提供了四种常用线程池:1)FixedThreadPool(固定线程数,适用于CPU密集型任务);2)SingleThreadExecutor(单线程顺序执行);3)CachedThreadPool(弹性线程数,适合短生命周期任务);4)ScheduledThreadPool(定时任务)。前三者存在OOM风险(无界队列或无限线程),生产环境建议手动配置ThreadPoolExecutor参数(如核心线程数、队列容量和拒绝策略)以确保系统稳定性。
2026-01-26 08:46:29
596
原创 http请求完整的tcpdump抓包解读
摘要:本文详细解析了HTTP请求的完整TCP/IP通信流程,包括三个阶段:1)TCP三次握手建立连接(SYN→SYN-ACK→ACK);2)HTTP数据传输(GET请求→ACK→响应→ACK);3)TCP四次挥手关闭连接(FIN→ACK→FIN→ACK)。通过tcpdump捕获的11个核心数据包,展示了从192.168.1.100客户端到httpbin.org服务器(54.xxx.xxx.xxx)的完整交互过程,包括序列号确认、标志位变化和数据长度等关键信息,完整呈现了底层网络通信机制。
2026-01-25 16:30:27
817
原创 如何用tcpdump诊断tcp数据包问题
tcpdump是网络分析和故障排查的核心工具,能够捕获并解析网络数据包。本文从三个方面详细讲解其使用:1)基础语法和常用选项,如-i指定接口、-n禁用解析、-w保存文件;2)输出信息解读方法,包括时间戳、IP地址、TCP标志位等关键字段;3)实用命令示例,涵盖HTTP/HTTPS流量捕获、ICMP包分析、文件保存与读取等场景。文章特别强调了过滤表达式的灵活运用,帮助用户精准捕获目标流量,并建议结合Wireshark等工具进行深入分析。
2026-01-25 16:26:42
948
原创 TCP/IP每一层协议数据格式和字段说明
摘要:TCP/IP协议族采用分层封装机制,每层添加头部信息完成特定功能。应用层协议如HTTP包含请求行和头部字段;传输层TCP提供20字节头部(含端口、序列号、控制标志等),UDP仅8字节头部;网络层IPv4含20字节头部(含TTL、协议类型、IP地址等);网络接口层以太网帧包含MAC地址和类型字段。数据封装流程为:应用数据→添加传输层头→添加IP头→添加帧头尾→比特流传输,各层头部确保数据正确传输和处理。
2026-01-24 07:15:00
1141
1
原创 线程上下文切换的是什么
摘要: 上下文(Context)是线程的当前工作状态快照,包括CPU寄存器值(如程序计数器、栈指针)和线程管理信息。上下文切换(Switching)由操作系统调度器执行,分为三步:保存当前线程的寄存器状态到内存→选择新线程→恢复新线程的寄存器状态到CPU。通过快速保存/恢复寄存器数据,单核CPU能实现多线程并发执行,让每个线程“无缝”继续运行。本质是硬件状态的保存与替换,类比为学生轮换使用课桌时记录和恢复作业进度。
2026-01-23 07:00:00
2380
1
原创 Linux中进程和tty的关系
TTY(电传打字机) 是计算机系统中用于文本交互的终端接口,包括物理终端、虚拟终端和伪终端(PTY)。 进程与TTY的关系: 交互式进程(如 bash、vim)需要TTY进行输入输出。 守护进程(如 nginx、mysqld)无TTY,运行于后台。 部分进程启动后主动脱离TTY(如守护化进程)。 查看方法: 使用 ps aux,TTY列显示终端编号(如 pts/0)或 ?(无终端)。 总结:TTY仅分配给需文本交互的进程,非所有进程必备。
2026-01-22 15:00:00
474
原创 java synchronized关键字用法和底层原理
摘要: synchronized是Java实现线程同步的关键字,通过监视器锁机制确保共享资源安全访问。它支持三种用法:同步实例方法(锁this)、同步静态方法(锁Class对象)和同步代码块(自定义锁对象)。配合wait()/notify()可实现线程协作,需注意必须在同步块内调用,并用循环防止虚假唤醒。底层通过对象头的Mark Word实现锁升级(无锁→偏向锁→轻量级锁→重量级锁),平衡性能与线程安全。关键点包括可重入性、锁范围最小化及与Lock的区别,重量级锁涉及系统调用开销较大。
2026-01-22 10:54:14
1187
原创 CPU的内核态和用户态
内核态与用户态是操作系统实现安全与稳定的核心机制。内核态拥有最高权限,可直接访问硬件资源,运行操作系统核心代码;用户态权限受限,只能运行应用程序。两者通过系统调用切换:用户程序触发系统调用后,CPU切换到内核态执行请求,完成后返回用户态。这种隔离设计防止应用程序直接操作硬件,确保系统安全稳定,即使程序崩溃也不会影响内核。本质上是通过权限分级(Ring 0/3)实现的硬件级保护机制。
2026-01-22 09:26:47
660
原创 从CPU中断角度解释一下java 如何读取键盘输入的
本文详细解析了从按下键盘按键到Java程序获取输入的完整技术流程。当用户按下键盘时,硬件中断触发CPU响应,内核中断处理程序(ISR)读取扫描码并转换为字符,TTY子系统进行行缓冲处理。当Java程序调用System.in.read()时,若输入未就绪,进程被阻塞;回车触发内核唤醒进程,通过系统调用将数据从内核空间拷贝至用户空间,最终JVM处理并返回给应用程序。整个过程涉及多次用户态/内核态切换和关键的数据跨空间拷贝,展示了操作系统作为硬件与应用间高效安全桥梁的核心机制。
2026-01-22 07:00:00
904
原创 java 的 Error和Exception
Java异常体系分为Error和Exception两大类。Error表示系统级严重错误(如内存溢出),程序通常无法处理;Exception是程序可处理的异常,分为受检异常(必须处理,如IO异常)和非受检异常(运行时异常,如空指针异常)。异常处理使用try-catch-finally机制,可通过继承Exception或RuntimeException自定义异常。最佳实践包括精准捕获异常、避免空catch块、确保资源释放等。
2026-01-21 10:38:45
499
原创 举例说明Java 中 finally 与 return 的执行顺序
摘要:本文分析了Java中finally块与return语句的交互机制。通过代码示例说明,当return位于finally之后时,返回finally修改后的值(如示例返回7);若return在try内部,则返回值会先暂存,finally对基本类型变量的修改无效(返回6)。对于引用类型,finally修改对象属性会影响返回值。建议finally块专注资源清理,避免修改返回值相关变量以提高代码可读性。关键结论:finally总在方法返回前执行,但返回值确定时机取决于return位置。
2026-01-20 11:35:58
422
原创 小数和整数10进制转2进制算法
本文介绍了十进制数转换为二进制数的方法。整数部分采用"除2取余,逆序排列"的方法,如13转换为1101;小数部分采用"乘2取整,顺序排列"的方法,如0.625转换为0.101。对于包含整数和小数的数字,分别转换后合并,如13.625转换为1101.101。需要注意无限循环小数的情况,如0.1转换为0.000110011...循环。负数转换需使用补码表示法。通过表格总结了转换方法和示例。
2026-01-20 11:11:55
440
原创 java new对象时候静态变量、成员变量、构造方法的执行顺序
Java类初始化顺序遵循"先静态后普通,先父类后子类"原则。具体顺序为:1)父类静态成员和静态代码块;2)子类静态成员和静态代码块;3)父类普通成员和实例代码块;4)父类构造方法;5)子类普通成员和实例代码块;6)子类构造方法。静态初始化只在类首次加载时执行一次,同类中成员变量和代码块按代码顺序执行,构造方法最后执行。这种顺序确保了父类环境先被正确设置,子类才能在此基础上初始化。
2026-01-14 19:00:00
407
原创 java基本类型 、封装类型用equals 和 == 比较时有哪些陷阱
摘要:Java中基本类型与封装类型的比较存在关键区别。基本类型使用==直接比较数值,而封装类型是对象,==比较的是内存地址,应使用equals()比较值。特别注意Integer缓存(-128到127)会导致小数值的==比较为true。最佳实践是:基本类型用==,对象比较用equals(),混合类型比较会自动拆箱。要避免陷阱,需清楚数据类型并遵循类型对应的比较规则。
2026-01-14 07:00:00
1057
原创 java函数式接口 @FunctionalInterface用法
@FunctionalInterface是Java 8引入的标记注解,用于声明函数式接口。函数式接口只能有一个抽象方法,但可以包含多个默认或静态方法。该注解的主要作用:一是让编译器检查接口是否符合函数式接口规范,二是明确标识该接口用于Lambda表达式。使用示例展示了如何定义函数式接口、用Lambda实现以及作为方法参数传递。加上该注解能让代码意图更清晰,并获得编译器保护,是Java函数式编程的重要工具。
2026-01-13 19:00:00
405
原创 java final 关键字的各种用法和注意事项
本文详细解析了Java中final关键字的用法:修饰变量时表示值或引用不可变;修饰方法防止子类重写;修饰类则禁止继承;修饰参数确保方法内不被重新赋值。final能提升代码安全性、可读性和并发性,常用于定义常量、保护核心逻辑或创建不可变类。现代JVM已优化final性能,其设计意义大于效率考量。注意事项包括空白final初始化、static final常量命名规范及集合的不可变处理等。
2026-01-13 07:00:00
1882
原创 java 访问权限修饰符使用规则 & 注意事项
本文详细介绍了Java中的四种访问权限修饰符:public、protected、default(包级私有)和private。它们分别控制类、方法、变量和构造器的可见性范围,从完全公开到仅限本类访问。文章阐述了每种修饰符的使用规则、适用场景,并提供了代码示例。同时强调了使用注意事项,包括类修饰符限制、继承规则、接口成员默认修饰等。最后给出最佳实践建议,提倡优先使用最严格的访问权限,通过合理封装提升代码安全性和可维护性。
2026-01-12 19:00:00
728
原创 java 这一句为什么会报错: byte c = 10+20,精度提升
Java中byte、short、char在算术运算时通常会被自动提升为int类型,但存在例外情况:简单赋值(如byte b=100)、复合赋值(如b+=5)、自增自减运算(如b++)时会自动进行类型转换。其他运算如b1+b2结果均为int,需强制转换才能赋值给小类型变量。理解这些规则有助于避免类型不匹配的编译错误。
2026-01-12 07:00:00
614
原创 JVM 栈帧中的操作数栈(为啥JVM是基于栈)
操作数栈(Operand Stack)是JVM执行计算的核心结构,作为临时工作台存放操作数和中间结果。它采用后进先出(LIFO)结构,深度在编译时确定。工作流程包括压入操作数、执行计算和存储结果三个步骤,所有字节码指令都依赖该栈完成操作。与局部变量表的长期存储不同,操作数栈是瞬态计算空间,只能访问栈顶元素。通过"int c=a+b"的实例演示了其工作原理:先将变量压栈,执行加法计算,最后存储结果。理解操作数栈对掌握JVM执行机制至关重要,它如同厨师灶台,与局部变量表(储物柜)共同完成方法
2026-01-11 19:15:00
1741
原创 java Arrays.asList 返回是啥,和普通 ArrayList 有区别吗
Arrays.asList()返回一个由指定数组支持的固定大小List视图,与常规ArrayList有显著区别。关键差异在于:返回的Arrays$ArrayList是数组视图,大小固定,不支持增删操作(会抛出异常),但允许修改元素且与原数组共享数据;而java.util.ArrayList是完全独立、可变大小的集合。若需要可变列表,应使用new ArrayList<>(Arrays.asList(array))。该方法设计目的是在数组与集合API间快速转换,而非替代完整功能集合。
2026-01-11 14:00:00
286
原创 为什么 java 参数是 值传递,不是引用传递
Java严格采用"按值传递"机制,无论传递基本类型还是对象引用。对于基本类型,传递的是值的副本;对于对象引用,传递的是引用的副本而非对象本身。这意味着方法内可以修改引用指向的对象内容,但无法通过赋值改变原始变量的引用指向。这种设计与真正的"按引用传递"(如C++的&操作符)有本质区别,后者允许直接修改原始变量的引用指向。因此,Java的参数传递应准确描述为"传递值的副本",对于对象则是"传递引用的副本"。
2026-01-11 07:30:00
859
原创 ThreadLocalMap里面Entry key为什么要弱应用,实际上value没法回收,这么做是多此一举吗
摘要: ThreadLocal的弱引用Key设计并非多余,而是防止"双倍泄漏"(Key+Value)的关键机制。当外部引用消失时,弱引用允许Key被回收,使Entry变为可识别的"陈旧条目",为后续get/set操作提供自动清理的机会。虽然无法彻底避免Value泄漏,但相比强引用方案,弱引用将泄漏范围从"Key+Value"缩小到仅Value,并通过标记陈旧条目实现"尽力而为"的自动清理。这是一种权衡设计:在无法保证调用remo
2026-01-10 19:00:00
514
原创 java 中 i = i++ 和 i = ++i 到底有什么区别
摘要:通过分析i = i++和i = ++i的字节码指令,揭示了前后置自增的本质区别。后置自增(i++)会先将旧值压栈,执行自增后再将旧值存回,导致最终结果为0;而前置自增(++i)会先执行自增,再将新值压栈存回,结果为1。关键差异在于iinc和iload指令的执行顺序,这对应了Java语言规范中前后置自增的语义差异,展示了语言特性在JVM层面的具体实现方式。
2026-01-10 17:44:28
513
原创 CyclicBarrier、CountDownLatch、Semaphore 各自的作用和用法区别
摘要:CountDownLatch、CyclicBarrier和Semaphore是Java并发编程中三种重要的线程协作工具。CountDownLatch用于让一个或多个线程等待其他线程完成操作,具有一次性特性;CyclicBarrier允许多个线程相互等待至公共屏障点后继续执行,可循环使用;Semaphore则通过许可机制控制同时访问资源的线程数量。三者分别适用于主线程等待子线程、多线程分步协作和资源并发控制等不同场景,在计数器操作、可重用性和典型应用方面存在显著差异。
2026-01-10 07:00:00
791
原创 从源码层面解析一下ThreadLocal的工作原理
本文深入解析了Java中ThreadLocal的核心实现机制,重点剖析了Thread、ThreadLocalMap及其内部Entry类的数据结构。ThreadLocal通过ThreadLocalMap为每个线程维护独立变量副本,其中Entry采用弱引用存储ThreadLocal作为Key,强引用存储Value。文章详细解读了set()、get()和remove()方法的实现逻辑,特别强调了自动清理陈旧条目的机制(如replaceStaleEntry和expungeStaleEntry)及其在内存管理中的作用
2026-01-09 19:00:00
814
原创 java WeakReference 用法 原理
WeakReference(弱引用)是Java中的一种特殊引用类型,当垃圾回收器扫描时,只要对象仅被弱引用关联且没有其他强引用,就会被立即回收。与强引用不同,弱引用不会阻止垃圾回收。典型应用包括实现内存敏感缓存,当内存不足时自动清除缓存条目,避免内存泄漏。使用WeakReference时需注意配合ReferenceQueue进行清理,并处理get()返回null的情况。相比SoftReference(内存不足才回收),WeakReference回收更激进。主要用途包括规范化映射、缓存和监听器列表等场景,可有
2026-01-09 07:00:00
1624
原创 ReentrantLock的公平锁和非公平锁
摘要:公平锁与非公平锁的核心区别在于获取锁的机制。公平锁严格按照FIFO顺序获取锁,通过hasQueuedPredecessors()检查队列情况;非公平锁会直接尝试抢占锁,提供两次抢占机会。非公平锁吞吐量更高但可能导致饥饿,是默认选择;公平锁保证顺序但性能较低,适用于需要严格公平的场景。ReentrantLock通过FairSync和NonfairSync两种同步器实现这一差异,体现了性能与公平性的平衡。
2026-01-08 14:00:00
1177
原创 java CAS原理和用法
CAS(Compare-And-Swap)是一种无锁原子操作机制,通过比较内存值与预期值来决定是否更新,整个过程不可分割。Java通过java.util.concurrent.atomic包提供原子类实现CAS,如AtomicInteger和AtomicStampedReference(解决ABA问题)。其优点是高性能、避免死锁,但存在ABA问题和自旋开销。核心方法compareAndSet()保证了线程安全,适用于低竞争场景。
2026-01-08 07:00:00
2115
原创 java synchronized 和 retrantlock 对比
场景推荐大多数标准同步需求需要高级功能(可中断、超时、公平锁、多个条件)简单来说,是“傻瓜相机”,简单可靠;是“单反相机”,功能强大但需要更多操作。在现代Java开发中,除非你有明确理由需要使用的高级特性,否则默认选择是更明智和安全的做法。
2026-01-08 07:00:00
1660
原创 源码解析-ConcurrentHashMap
摘要: JDK8中的ConcurrentHashMap通过CAS操作和细粒度锁(仅锁单个桶)实现高效并发,相比HashMap具有线程安全特性但不允许null键值。其核心设计包括:1) put操作采用CAS尝试无锁插入,冲突时仅同步单个桶;2) get操作完全无锁,保证弱一致性;3) 支持多线程协助扩容。与HashMap相比,ConcurrentHashMap在并发场景下性能更优,但迭代器是弱一致性的,且读写操作存在不同的同步策略。
2026-01-07 14:00:00
675
原创 从HashMap源角度解释一下为什么对象的hashcode()和equals()方法要一起重写
HashMap的核心机制依赖于键的hashCode和equals方法协同工作。hashCode用于定位键在数组中的桶位置,而equals用于确认键的逻辑相等性。若只重写equals而不重写hashCode,会导致逻辑相等的键被分配到不同桶中,使得HashMap无法正确检索。因此,必须同时重写这两个方法,确保语义相等的对象具有相同的hashCode值,才能保证HashMap的正确运行。这是Java对象契约的强制性要求。
2026-01-07 07:00:00
1181
原创 java垃圾收集 minorgc majargc fullgc
摘要: JVM垃圾回收(GC)主要分为Minor GC、Major GC和Full GC三种类型。Minor GC仅回收年轻代(Eden+Survivor),触发于Eden区空间不足,速度快且频繁。Major GC回收老年代,触发于老年代空间不足,速度较慢。Full GC回收整个堆(年轻代+老年代+方法区),触发条件包括老年代不足、方法区不足等,STW时间最长,应尽量避免。三者关系形成对象生命周期:新对象在Eden分配→Minor GC存活后进入Survivor→年龄达标晋升老年代→老年代不足触发Major
2026-01-06 17:46:58
622
原创 java BIO、NIO、AIO用法样例
摘要: 本文介绍了三种Java网络I/O模型:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞)。BIO采用“一连接一线程”模式,简单但性能受限;NIO通过Selector单线程管理多路复用,减少线程开销;AIO基于回调机制实现真正的异步操作,适合高并发场景。每种模型均附有代码示例,分析其特点与适用场景,帮助开发者根据需求选择合适方案。
2026-01-06 17:34:48
643
基于java jdbc 的数据库表结构生成工具 源代码
2024-12-20
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅