<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[xifeng191的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/xifeng191</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; xifeng191]]></copyright><item><title><![CDATA[Java 阻塞队列——实现生产者消费者模型]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/166690770</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/166690770</guid><author>xifeng191</author><pubDate>Sat, 26 Sep 2026 18:22:34 +0800</pubDate><description><![CDATA[wait() 的线程，在没有被notify唤醒的情况下，也可能被操作系统唤醒。所以不能用if判断队列状态，必须用while循环。// ❌错误！if只判断一次，虚假唤醒后不会二次校验if(队列是空){wait();// ✅while循环，唤醒之后再次循环检查条件while(队列是空){wait();原理：线程被唤醒后，会重新回到while条件判断。如果此时队列依旧为空，会再次进入wait等待，规避虚假唤醒带来的bug。无界队列OOM风险。]]></description><category></category></item><item><title><![CDATA[简历大师 oolong 小程序功能测试报告]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/166128064</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/166128064</guid><author>xifeng191</author><pubDate>Sun, 20 Sep 2026 13:38:33 +0800</pubDate><description><![CDATA[本次完成证件照制作模块全流程测试：3张不同类型图片（证件照、生活照）均可正常完成AI抠图、背景替换、证件照生成，AI图片处理能力稳定，图片识别效果符合产品预期。简历制作模块未完成完整流程，在执行生成环节触发积分与系统报错缺陷，功能被阻断。个人分析：证件照模块的AI图片处理能力表现良好；但简历制作模块在积分校验逻辑、异常提示交互上存在明显的产品体验缺陷。积分不足属于业务场景，不应该抛出“未知错误”这类技术故障提示，容易造成用户误解，降低用户留存与付费转化。]]></description><category></category></item><item><title><![CDATA[Java单例模式｜从基础到多线程安全]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/165890395</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/165890395</guid><author>xifeng191</author><pubDate>Fri, 18 Sep 2026 22:32:21 +0800</pubDate><description><![CDATA[单例核心：私有构造器 + 全局唯一实例 + 静态获取入口饿汉简单但无懒加载；基础懒汉多线程不安全；加锁方法性能差双重检查锁是重点，volatile禁止指令重排静态内部类：代码简洁，推荐业务开发使用枚举单例：安全性最高，《Effective Java》推荐，防止反射、序列化破坏。]]></description><category></category></item><item><title><![CDATA[Java多线程重点解析sleep,join,interrupt和死锁必要条件以及wait和sleep的区别]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164832115</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164832115</guid><author>xifeng191</author><pubDate>Thu, 10 Sep 2026 13:13:16 +0800</pubDate><description><![CDATA[多线程核心难点：不是开启线程，而是控制并发安全。先分清线程状态、基础API理解线程安全产生的底层原理（指令交错、缓存）掌握synchronized锁原理、锁升级、死锁拓展学习：线程池、Lock锁（AQS）、CAS、ThreadLocal。]]></description><category></category></item><item><title><![CDATA[HOJ判题测试报告]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164629504</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164629504</guid><author>xifeng191</author><pubDate>Tue, 08 Sep 2026 22:37:36 +0800</pubDate><description><![CDATA[本次模拟企业完整测试流程，对HOJ在线判题Web系统开展质量验证，覆盖手动功能测试、Fiddler抓包接口测试、UI自动化回归测试、JMeter性能压测。被测模块：用户注册登录、题目题库模块、训练集模块、比赛模块、提交评测模块、讨论区模块、排行榜团队模块。手动功能测试验证业务流程，发现页面交互、业务逻辑缺陷；UI自动化覆盖高频核心场景，用于版本迭代快速回归；Fiddler抓包篡改请求，校验接口参数校验、权限越权、判题提交接口报文；]]></description><category></category></item><item><title><![CDATA[电商项目测试报告]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164625108</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164625108</guid><author>xifeng191</author><pubDate>Tue, 08 Sep 2026 22:20:07 +0800</pubDate><description><![CDATA[本次模拟企业完整测试流程，对电商Web系统开展质量验证，覆盖功能测试、接口与抓包测试、自动化测试、性能测试被测模块：用户登录注册、首页商品、商品搜索详情、购物车、订单结算、个人中心、权限越权校验。功能测试保障业务流程可用，挖掘业务功能缺陷；UI自动化实现核心场景回归，减少重复手工回归工作量；使用Fiddler抓包，分析接口请求响应，发现参数校验、权限越权类后端漏洞；性能压测验证系统并发承压能力，提前识别性能瓶颈。]]></description><category></category></item><item><title><![CDATA[Java Socket网络编程｜TCP与UDP深度梳理]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164456907</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164456907</guid><author>xifeng191</author><pubDate>Mon, 07 Sep 2026 13:32:56 +0800</pubDate><description><![CDATA[阻塞问题accept()、IO流read()全部会阻塞线程。并发场景需要多线程，后续进阶NIO非阻塞IO。端口占用异常：端口被别的进程占用，启动直接报错；测试注意关闭旧程序释放端口。本机测试与跨机器测试127.0.0.1只能本机访问；跨机器要填写真实局域网IP，防火墙放行端口。数据读取长度陷阱：UDP必须使用；TCP字节流注意区分读到的有效字节长度和缓冲区数组总长度。TCP字节流无报文边界；UDP数据包自带边界，这是二者编程最大区别。异常处理。]]></description><category></category></item><item><title><![CDATA[Java IO 完整学习笔记｜字节流、字符流、缓冲流、资源关闭全梳理]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164270221</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164270221</guid><author>xifeng191</author><pubDate>Wed, 02 Sep 2026 08:00:00 +0800</pubDate><description><![CDATA[read()返回值是int，判断结束条件==‑1，不要强转byte/char再判断。字符流忘记flush/close，文件为空，数据丢失。FileWriter追加模式：构造传入第二个参数true，否则每次覆盖旧文件。FileReader/FileWriter跟随系统编码，跨平台乱码，指定编码优先用转换流。不要拿字符流读取二进制文件，文件直接损坏。流资源务必释放，优先，杜绝句柄泄漏。缓冲流是包装流，关闭外层缓冲流即可，内层被包装流会自动关闭。文件路径：Windows路径需要转义。]]></description><category></category></item><item><title><![CDATA[Java入门：线程创建的四种方法和为什么线程不安全]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164194050</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164194050</guid><author>xifeng191</author><pubDate>Sun, 30 Aug 2026 23:08:12 +0800</pubDate><description><![CDATA[多线程不是银弹，不是线程开越多速度越快；上下文切换有成本。线程安全是多线程开发最大坑点，只要共享可变数据就要警惕。start()和run()一定要分清：run只是普通方法，start才真正创建操作系统线程。守护线程适合做后台辅助任务，不能用来执行必须完成的业务。]]></description><category></category></item><item><title><![CDATA[Java多线程初阶完整总结｜线程、锁、volatile、等待通知、常见案例]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164097719</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164097719</guid><author>xifeng191</author><pubDate>Thu, 27 Aug 2026 20:00:00 +0800</pubDate><description><![CDATA[线程就是一条独立执行流，多个线程可以同时执行多份代码。进程是资源分配的最小单位；线程是CPU调度的最小单位。一个进程至少包含1个主线程；同一个进程内多个线程共享堆、方法区内存；每个线程私有虚拟机栈、本地方法栈、程序计数器；进程之间内存相互隔离；一个线程崩溃，会导致整个进程崩溃。充分利用多核CPU算力；IO等待时可以执行其他任务，提升程序整体效率；相比进程，线程创建、销毁、调度开销更小。]]></description><category></category></item><item><title><![CDATA[Java CAS 原理总结]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/164096241</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/164096241</guid><author>xifeng191</author><pubDate>Wed, 26 Aug 2026 20:16:26 +0800</pubDate><description><![CDATA[CAS只检查变量当前值是否等于预期值，它不关心中间是否被修改过。线程A读取变量值为A；线程B把值从A修改成B，又马上改回A；线程A执行CAS，发现内存值还是A，认为没有被修改过，执行更新操作。CAS只比对数值，无法识别“中间发生过变化又改回原值”的情况，在部分业务场景会产生逻辑bug。生活类比：二手手机，手机从A到B再回到A，手机本体已经被转手过，但数值没变，CAS识别不出。ABA不是一定会出bug；只有业务逻辑需要感知“变量是否被改动过”的时候才会造成问题。]]></description><category></category></item><item><title><![CDATA[Java--多态篇！！]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/155647852</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/155647852</guid><author>xifeng191</author><pubDate>Fri, 12 Dec 2025 12:14:09 +0800</pubDate><description><![CDATA[本文介绍了Java面向对象编程中的多态特性。主要内容包括：1.多态的概念和实现条件（继承体系、方法重写、父类引用调用）；2.方法重写的规则和注意事项；3.向上转型和向下转型的使用方法及注意事项；4.多态的优缺点（降低复杂度但影响效率）。通过代码示例展示了多态的具体应用场景，并比较了重写与重载的区别，最后指出多态虽然增强了代码灵活性，但也带来了运行效率降低的问题。]]></description><category></category></item><item><title><![CDATA[java--继承篇！！]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/155503019</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/155503019</guid><author>xifeng191</author><pubDate>Sat, 06 Dec 2025 21:04:11 +0800</pubDate><description><![CDATA[第四点解释，当我们重载子类构造方法时，this（）调用，会调用重载的子类构造方法。而this（）和super（）在构造方法中，都必须是第一条语句，所有不能同时出现。]]></description><category></category></item><item><title><![CDATA[Java--面向对象之封装篇!!!]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/155413462</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/155413462</guid><author>xifeng191</author><pubDate>Mon, 01 Dec 2025 10:39:35 +0800</pubDate><description><![CDATA[封装就像是把东西放在⼀个盒子里，并且控制谁可以打开这个盒子，以及如何使用盒子里的东西。在编程中，它指的是将数据（属性）和操作这些数据的方法（函数）包装在⼀个单元（通常是类）内。仅对外公开一些接口来和对象进行交互。]]></description><category></category></item><item><title><![CDATA[java--类和对象（详解！！）]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/155202007</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/155202007</guid><author>xifeng191</author><pubDate>Mon, 24 Nov 2025 23:16:11 +0800</pubDate><description><![CDATA[Java是一门面向对象的语言，在学习它之前需要先了解什么是对象？对象就是现实生活中的实体，比如，冰箱，洗衣机，人等等。面向对象是一种解题思想，就是依靠对象之间的交互完成任务。比如，人把衣服给洗衣机，这里人和洗衣机就是对象。我们只需要使用洗衣机就可以，不需要关注洗衣机是怎么洗衣服的。这就是依靠对象之间的交互来完成任务。类是⽤来对⼀个实体(对象)来进行描述的，主要描述该实体(对象)具有哪些属性(外观尺寸等)，哪些功能(用来⼲啥)，描述完成后计算机就可以识别了。]]></description><category></category></item><item><title><![CDATA[C语言--编译和链接（详细介绍）！！]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/154919656</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/154919656</guid><author>xifeng191</author><pubDate>Mon, 17 Nov 2025 15:22:13 +0800</pubDate><description><![CDATA[而如果我们在test.c的文件中使用了list.c定义的Add函数，由于每个文件都是单独经过编译器的编译，我们是没法知道调用函数的地址，这时候就暂时把这条指令（函数地址）搁置，等到链接时，链接器会根据函数名（Add）在其他文件中查找该函数的地址，然后将test.c文件中所有使用Add函数的指令修正，即定位到该函数正真的地址，这就是重定位。语义分析是在语法树的基础上（语法层面上）进行的语义分析，编译器进行的分析是静态的语义分析，即对函数类型的。链接的过程包括：地址和空间的分配，以及重定位。]]></description><category></category></item><item><title><![CDATA[C语言--文件读写函数的使用]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/154615943</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/154615943</guid><author>xifeng191</author><pubDate>Sun, 09 Nov 2025 22:09:46 +0800</pubDate><description><![CDATA[使用fopen来打开文件，就要了解关于文件的访问模式：使用“r”打开文件，打开的文件必须存在，否则，程序出错使用“w”打开文件，如果文件存在，并且文件中有数据，会清空数据。文件不存在，会建一个新文件打开文件用fopen有文件的打开就有文件的关闭，关闭文件用fcloseint main()return;//写文件//关闭文件fclose(pf);pf = NULL;return 0;]]></description><category></category></item><item><title><![CDATA[C语言--内存函数（详解）]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/154393349</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/154393349</guid><author>xifeng191</author><pubDate>Wed, 05 Nov 2025 00:24:35 +0800</pubDate><description><![CDATA[这里介绍的几个库函数，相比于strcpy,strcat,strcmp这些字符串库函数，它们的应用范围更加的广泛，不只局限于字符串，它们适用于任意类型的数据。]]></description><category></category></item><item><title><![CDATA[C语言--指针（详解）]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/154242984</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/154242984</guid><author>xifeng191</author><pubDate>Sat, 01 Nov 2025 19:06:15 +0800</pubDate><description><![CDATA[根据数组名是数组⾸元素的地址这个规则，⼆维数组的数组名表⽰的就是第⼀⾏的地址，是⼀维数组的地址。根据上⾯的例⼦，第⼀⾏的⼀维数组的类型就是 int [5] ，所以第⼀⾏的地址的类型就是数组指针类型 int(*)[5]&arr的地址值与arr相同，但类型不同（&arr的类型是int(*)[5]，指向整个数组）。指针的大小与其指向的数据类型无关，无论是指向char、int还是其他类型，指针本身的大小是固定的。⽐如： char* 的指针解引⽤就只能访问⼀个字节，⽽ int* 的指针的解引⽤就能访问四个字节。]]></description><category></category></item><item><title><![CDATA[（C语言）指针程序题——练习]]></title><link>https://blog.youkuaiyun.com/xifeng191/article/details/153922413</link><guid>https://blog.youkuaiyun.com/xifeng191/article/details/153922413</guid><author>xifeng191</author><pubDate>Sun, 26 Oct 2025 16:57:48 +0800</pubDate><description><![CDATA[但这个方法要用到一个数组形成的辅助空间，还可以有更好的选择，例如ABCDEFG，左旋3次后变成DEFGABC，有一个特殊的操作方式：先将要左旋的前三个家伙逆序（CBADEFG），然后将后半段也逆序（CBAGFED），最后整体逆序（DEFGABC）即可。strstr用于在一个字符串中查找另一个字符串的首次出现位置，如果找到子字符串，返回指向主字符串中子字符串首次出现位置的指针。有一个数字矩阵，矩阵的每行从左到右是递增的，矩阵从上到下是递增的，请编写程序在这样的矩阵中查找某个数字是否存在。]]></description><category></category></item></channel></rss>