Java IO流知识地图:从字节流到NIO的实战与踩坑
接手过一个老项目的附件导入导出功能里面清一色是FileInputStream读完再FileOutputStream写回。功能跑得通但线上时不时冒出中文报表乱码、处理大清单卡到超时甚至偶尔报Too many open files。我把里面所有和流相关的代码重新理了一遍也算是把 Java 里常用的流知识整体梳理成了一张网。这篇就把我的理解完整记录下来从流的本质和分类到常用流怎么选型、装饰链怎么组合、NIO 时代有哪些更省心的替代再到我实际踩过的坑和排查思路。适合刚接触 Java IO 的新人也适合写过流代码但遇到问题还要靠搜索的开发者。1. 先搞懂“流”到底是什么1.1 数据管道类比“流”这个名字听着抽象其实就是一个数据管道。数据在 Java 程序和外部世界之间单向流动从外部读进程序叫输入流从程序写到外部叫输出流。可以把InputStream理解为自来水管一端是文件、网络套接字或内存数组另一端是程序数据像水一样按顺序流过来程序读多少就拿多少没读到的还留在管子里等下次取。OutputStream则反过来把程序里的数据排放出去。这种单向性解释了为什么同一个文件既要读又要写时往往需要分别维护两个不同的流对象。这个管道模型还有一个重要特点数据是“串行”的。流不像集合那样可以随意跳跃访问某个位置读过了就过去了除非用支持随机访问的RandomAccessFile或者把整个文件映射成字节数组。所以大多数基于流的读写逻辑都是顺序处理配合循环把数据一段段搬运完。理解了这一点再看skip、mark、reset这些少用的方法时就不会觉得神秘。1.2 字节流与字符流的底层差异Java IO 的抽象根上是四个类InputStream、OutputStream处理字节Reader、Writer处理字符。所有流类都是从这四个基类派生的。字节流处理的是原始二进制数据比如图片、音频、压缩包、协议报文一次最少一个字节完全不带编码概念。代码里读出来的每个值都是 0 到 255 的整数拼接成什么含义完全由业务解释。字符流则面向人类可读文本内部其实还是字节流只是外面多了一层字符编码解码器读取 UTF-8 编码的文件时字符流负责把若干字节组合成一个 Unicode 字符再转成 Java 里的char或String。很多初学者问过同一个问题“为什么FileReader读中文会乱码换成new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)就好了”答案就在这里。FileReader是InputStreamReader的简便子类但它默认使用 JDK 启动时探测到的平台字符集在 Windows 中文环境里通常是 GBK于是 UTF-8 编码的中文文件被 GBK 解码自然出现了乱码。字符流的本质是“字节流加编码规则”这个观念越早建立后面就越不容易被编码问题折磨。1.3 为什么日常代码里总是层层包装单独一个FileInputStream能力很有限每次read()都可能触发一次系统调用性能差不支持按行读取也不带缓冲。java.io解决这个问题的方式是“过滤器流”也就是装饰器模式用一个流包装另一个流每包一层就叠加一层能力而且层与层之间可以自由组合。new BufferedInputStream(new FileInputStream(file))这样写等于在原始文件流外面加了一个默认 8KB 的缓冲桶数据不再是逐字节从磁盘搬而是一次搬一大块进内存再从内存逐字节用。new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))则是在字节流之上加了编码转换再加了按行读取的能力。这个“套娃”设计是理解所有流组合的关键也是面试里经常提到的装饰器模式在 JDK 中最典型的落地场景。2. 日常开发中出场率最高的常用流盘点2.1 基础字节流文件的起点和终点FileInputStream和FileOutputStream是最基础的节点流直接对接文件系统。FileInputStream构造时要给定一个文件路径或File对象文件不存在会抛FileNotFoundExceptionFileOutputStream默认覆盖目标文件想追加内容就传第二个参数true。它们本身没有缓冲区也不做任何编码处理适合读写原始数据。ByteArrayInputStream和ByteArrayOutputStream也是节点流不过数据源不是磁盘而是内存里的字节数组。前者把一个byte[]包装成流方便用流的方式读内存数据后者在内存中维护一个可增长的字节数组常用于程序内部需要临时缓存输出内容的场景比如把图片字节拼到一块再统一写出。2.2 缓冲流不用白不用的默认选择BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter是四个最常用的缓冲流。它们各自包在对应的普通流外面默认缓冲区大小是 8192 字节。作用一句话减少底层系统调用次数把多次小读写合并成批量大读写。举个例子不包缓冲流时每写一个字节到FileOutputStream都可能触发一次写磁盘操作性能可想而知。包上BufferedOutputStream后数据先攒到 8KB 缓冲区里攒满了才真正写一次磁盘。很多性能问题不是算法问题而是少了这一层缓冲包装。所以只要做文件读写默认第一反应应该是加缓冲。2.3 转换流编码处理的唯一正确姿势InputStreamReader和OutputStreamWriter是字节流和字符流之间的桥。它们接收一个字节流再按指定字符集解码成字符流或者把字符按指定字符集编码成字节流。关键点是构造时必须显式传Charset我建议一律用StandardCharsets.UTF_8不要依赖平台默认值。这两个流在日常代码里很少单独出现更多是作为BufferedReader或BufferedWriter的里层存在比如读取一个 UTF-8 编码的日志文件推荐组合是new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))。很多人记不住这么多层其实可以用Files.newBufferedReader(path, charset)代替效果一样签名更清爽。2.4 数据流与对象流从“按字节搬运”到“按结构读写”DataInputStream和DataOutputStream支持直接读写 Java 基本类型和字符串比如writeInt、writeUTF、readDouble。它们按固定字节布局把数据写到流里读的时候按同样的顺序取回适合自定义二进制协议或紧凑格式存储。需要注意读写顺序必须严格一致否则解析出来全是错的而且很难排查。ObjectInputStream和ObjectOutputStream做的是 Java 对象序列化把实现了Serializable接口的对象整体写成一串字节之后可以完整恢复。这个很方便但坑也不少。对象里的serialVersionUID一旦随类结构变化而不同反序列化会抛InvalidClassException读回来的对象通过反射构造绕过了构造方法某些安全校验可能失效。所以序列化对象建议显式写死一个serialVersionUID并谨慎对待类结构变更。2.5 打印流最被忽视的“输出流”PrintStream和PrintWriter专门用来输出格式化文本System.out就是一个PrintStream。它们的优势是print、println、printf特别好用而且这些方法不会抛出受检异常只在内部设置一个错误标记用checkError()才能查到。写入目标可以是文件、字节数组或其他输出流。区别是PrintStream输出字节PrintWriter输出字符且支持指定字符集和自动刷新。写文本文件时PrintWriter配BufferedWriter是常规操作写日志时把PrintStream包装进装饰链也很常见。我一直把打印流当成“写文本的便利工具”而不是追求底层性能的主通道。常用流包装/对接目标典型使用场景备注FileInputStream / FileOutputStream文件原始字节读写无缓冲BufferedInputStream / BufferedOutputStream字节流批量读写大文件默认8KB缓冲InputStreamReader / OutputStreamWriter字节流与字符集编解码转换务必显式指定字符集BufferedReader / BufferedWriter字符流按行读写文本配合转换流使用DataInputStream / DataOutputStream字节流读写基本类型/字符串顺序敏感ObjectInputStream / ObjectOutputStream字节流对象序列化注意类版本控制PrintStream / PrintWriter字节流或字符流格式化输出不抛受检异常3. 流的组合与装饰链一份可直接抄的读写方案3.1 从最原始的文件复制说起先用最基础的节点流实现文件复制流程是创建输入流打开源文件创建输出流写目标文件循环从输入流读一块数据到字节数组再写到输出流。try (InputStream in new FileInputStream(source); OutputStream out new FileOutputStream(target)) { byte[] buffer new byte[8192]; int len; while ((len in.read(buffer)) ! -1) { out.write(buffer, 0, len); } }这里有两个关键细节。第一read(buffer)不一定每次都把缓冲区填满所以必须用返回值len作为写入长度不能直接out.write(buffer)否则会把上一次残留的数据也写进去导致文件内容重复或错位。第二缓冲区大小 8192 是反复实测后比较平衡的值太小则系统调用频繁太大则占用内存且收益递减。很多线上问题其实不是流本身有问题而是循环逻辑写错了。3.2 为什么要再包一层缓冲流基础版已经用了byte[]批量读写实际项目中我还会再包一层缓冲流尤其是写文件频繁或数据量大的时候。try (InputStream in new BufferedInputStream(new FileInputStream(source)); OutputStream out new BufferedOutputStream(new FileOutputStream(target))) { byte[] buffer new byte[8192]; int len; while ((len in.read(buffer)) ! -1) { out.write(buffer, 0, len); } }类比一下FileInputStream每次read都像拎着一个小杯子去水龙头接水一来一回全是开销BufferedInputStream相当于在中间放了一个大水桶先把桶灌满再一杯一杯从桶里取只有在桶空时才再去接。即使外层已经用了 8KB 的数组内层缓冲依然能减少底层同步和系统调用次数。实测下来某些场景读写大文件时加与不加差距能到数倍甚至更多。3.3 try-with-resources 自动关闭上面的示例已经用了try-with-resources这是 Java 7 引入的语法要求流对象实现AutoCloseable。资源声明放在try括号里代码块结束后 JDK 会自动按逆序调用close()也就是后声明的先关闭。这样可以彻底告别手写finally { close }的繁琐和遗漏。注意声明顺序就是打印顺序out在in之后声明所以会先关out再关in。这个顺序很重要因为输出流可能还有缓冲数据没写完先关输出流能确保这些数据刷到磁盘如果先关输入流输出流照常工作也不会出问题但反过来先关输出流再读数据就不完整了。装饰链长的场景更要靠这个机制兜底。3.4 字符流处理文本的标准模板读取 UTF-8 文本并按行处理我建议直接用这个模板Path path Path.of(data.txt); try (BufferedReader reader Files.newBufferedReader(path, StandardCharsets.UTF_8)) { String line; while ((line reader.readLine()) ! null) { // 业务处理 } }Files.newBufferedReader内部就是new BufferedReader(new InputStreamReader(new FileInputStream(path.toFile()), charset))只是把啰嗦的嵌套封装掉了。如果业务逻辑可以写成函数式管道还可以配合Files.lines(path, charset)得到一个StreamString但那个流必须在一个try-with-resources里使用后续会专门讲。写文本时同理用Files.newBufferedWriter指定 UTF-8需要格式化再用PrintWriter包一层。3.5 flush 与关闭顺序的讲究缓冲流为什么要flush因为数据先写在内存缓冲区没满之前不会真正落到目的地。close()内部会先调用flush()所以正常关闭时不会丢数据。但有一种场景必须手动flush同一个流对象要跨长生命周期持续写入而下游立刻需要看到数据。比如写日志、写网络响应写完一批就该刷一次否则对面一直等不到内容。关闭顺序和刷新还有一层关系。装饰链BufferedOutputStream - FileOutputStream中close最外层时BufferedOutputStream会先flush自己的缓冲区再关闭内层FileOutputStream。所以千万不要在图省事时手动先关内层的FileOutputStream不然外层缓冲区的数据就再也写不进去了。经典错误是先fileOut.close()再bufferedOut.close()结果写文件缺尾排查还特别费劲。我的经验是只关最外层里层交给装饰链自己收尾。4. 从流到 NIOFiles、Channel 与缓冲区的新玩法4.1 小文件直接交给 Files 工具类如果文件不大完全可以不用手动搭装饰链java.nio.file.Files提供了一堆一键方法。Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); byte[] allBytes Files.readAllBytes(sourcePath); ListString allLines Files.readAllLines(sourcePath, StandardCharsets.UTF_8);Files.copy底层根据文件大小自动选择复制策略比自己写循环复制更省心。readAllBytes适合配置文件、小图片这类体量可控的场景一句话拿回全部字节readAllLines适合需要一次性加载所有文本行的场景。但它们都有一个前提文件大小适合放入内存。拿几百 MB 的日志文件直接readAllBytes内存立刻吃紧GC 还救不回来。所以小文件用Files大文件请继续走流式路线。4.2 大文件流式处理与 FileChannel处理大文件的核心原则是“不把整个文件放入内存”而是分块读取。用传统 IO 的缓冲流已经能解决大部分需求但追求更高吞吐时FileChannel是更好的选择。它属于 NIO读写都围绕ByteBuffer展开。try (FileChannel in FileChannel.open(sourcePath, StandardOpenOption.READ); FileChannel out FileChannel.open(targetPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) { ByteBuffer buffer ByteBuffer.allocateDirect(8192); while (in.read(buffer) ! -1) { buffer.flip(); while (buffer.hasRemaining()) { out.write(buffer); } buffer.clear(); } }这里每个方法都有含义read把数据从通道读进缓冲区返回 -1 表示读完flip把缓冲区从写模式切换成读模式write把缓冲区内容写到输出通道clear恢复写模式。使用allocateDirect时缓冲区直接分配在 JVM 堆外少一次堆内拷贝大数据量场景性能更好。如果只是单机复制文件FileChannel还有个杀手锏transferTo可以直接在内核态搬数据连用户态缓冲都省了。4.3 内存映射MappedByteBufferFileChannel.map可以把文件的某段区域直接映射到进程虚拟内存应用像操作字节数组一样访问文件内容内核按需把缺失的页加载进来。try (FileChannel channel FileChannel.open(path, StandardOpenOption.READ)) { MappedByteBuffer mapped channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); while (mapped.hasRemaining()) { byte b mapped.get(); // 处理字节 } }优点是读写大文件时不用反复执行系统调用数据看起来就在内存里缺点也很明显映射占用地址空间文件被映射后如果被外部程序改写行为可能难以预期。我的经验是追求超高吞吐的自定义文件格式解析可以上普通业务文件读写反而没必要省下的时间会花在排查映射导致的诡异问题上。4.4 Files.list 与 Files.walk 目录遍历Files还提供了一系列目录遍历方法。Files.list(dir)返回当前目录下一层路径的StreamPathFiles.walk(dir, depth)可以递归遍历到指定深度按需配合Filter找出符合后缀的文件。try (StreamPath stream Files.walk(rootPath, 5)) { stream.filter(p - p.toString().endsWith(.log)) .forEach(System.out::println); }这两个方法返回的Stream跟 IO 流一样需要关闭因为它底层持有目录的句柄。不在try-with-resources里用完就关长时间运行的程序会打开大量目录句柄最终触发句柄耗尽的报错。这个场景和第 6 章要讲的Stream概念有交叉先在这里提个醒。5. 那些年我在流上翻过的车排查链路完整复盘5.1 中文乱码先确认解码方向再确认字符集翻车案例来自一个导出报表功能读模板文件填充数据后输出Windows 服务器上跑得好好的换到 Linux 服务器上导出的 Excel 里中文全部变成问号。查了一遍代码发现读取模板用的是new FileReader(template)写输出用的是new OutputStreamWriter(..., UTF-8)。输入依赖平台字符集输出固定 UTF-8两边编码不一致编码链路就断了。排查顺序是先确认源文件到底什么编码再看读取端用什么解码最后看写入端用什么编码。后来我把所有文本流的读写都改成显式指定UTF-8FileReader、FileWriter一律不用乱码问题再也没复发。这类问题的本质不是测试环境不同而是代码里存在隐式的平台依赖。5.2 数据神秘丢失BufferedOutputStream 没 close另一个案例是程序正常退出但生成的文件大小永远是 0。代码里写了new BufferedOutputStream(new FileOutputStream(outFile))写完数据后直接结束线程没有调用close()。因为缓冲区没满数据还躺在内存里线程结束不会替你 flush文件自然就是空的。排查时我先确认数据确实写过再逐步给BufferedOutputStream构造参数加true自动刷新或手动flush()问题立刻消失。这也是为什么我建议所有资源都要用try-with-resources它保证close必然执行等于给缓冲数据上了保险。如果代码里还残留手写close的旧逻辑不妨顺手迁到新的资源管理方式。5.3 Too many open files句柄泄漏的完整复盘遇到过最隐蔽的坑是日志模块偶尔报Too many open files。单看代码每条日志都是new PrintWriter(file, UTF-8)写完立刻close()逻辑上没问题。但后来发现写日志的线程发生异常时会走另一个分支那个分支里忘了close()写失败的流对象一直挂在那里句柄越积越多最终把进程的文件描述符耗尽。排查时我先看异常堆栈确认不是业务 SQL 问题接着用系统工具查看进程打开的句柄数量一眼就看到大量残留的.log文件句柄再根据句柄数量随时间上升的速度定位到异常分支缺了关闭操作。修复就是把资源声明放进try-with-resources让异常路径也能自动关闭。从那以后我对所有持有系统资源的对象都坚持“声明即关闭范围可见”的原则。5.4 性能突然差 100 倍单字节 read 黑洞一个老模块读取文件做校验2MB 文件要处理几分钟。代码是while ((i input.read()) ! -1)一次读一个字节而且外层还没缓冲。单字节read()每次都潜在触发系统调用哪怕数据已经在内存也要反复穿越 JNI 边界性能自然被拖垮。修复很简单换成八字节数组批量读或包一层BufferedInputStream。性能直接提升两个数量级。遇到这种问题先看读取模式再看缓冲区存在与否基本能找到根因。后来我把这条经验总结成一句话“没有缓冲的逐字节读写是流性能问题的第一嫌疑犯。”5.5 反序列化失败类版本编号不一致对象流最经典的问题就是serialVersionUID。同事改了实体类的一个字段名没有更新版本号结果之前序列化到文件的对象在反序列化时报InvalidClassException生产数据直接读不回来。排查时先对比两个时间点的类定义确认字段变化再看serialVersionUID发现两个版本一致但类结构已经变了所以套用了老版本的序列化数据后结构对不上。修复分两步一是新代码显式声明serialVersionUID二是写兼容逻辑老数据做字段映射或重建。此后我对所有参与序列化的类都要求显式声明版本号宁可多写一行也不赌编译器自动生成的稳定性。5.6 排查流问题的心法复盘这几个案例后我沉淀出一套排查顺序先看读写方向和数据长度确认数据是否真的进了流再看缓冲区状态有没有 flush 和 close再看编码和解码器是否一致最后看系统资源句柄、内存有没有泄漏。流问题看起来五花八门本质上都绕不开“数据流向、缓冲落盘、编码解码、资源关闭”这四个环节按顺序排查很少走弯路。6. 别把 IO 流和 Java 8 Stream 混为一谈6.1 两种“流”是两套完全不同的东西标题里的“流”在 Java 里其实有两个含义一个是java.io的数据流另一个是 Java 8 引入的java.util.stream.Stream。它们共享同一个中文字面但一个是字节/字符管道一个是集合数据的函数式处理管道。Stream处理的是内存中的元素序列支持filter、map、collect这类声明式操作。它的数据来源通常是集合、数组或生成器函数处理过程是惰性求值的只有遇到collect等终止操作才真正开始计算。IO 流则是对外部数据源的顺序访问到达终端后数据就没了。两者的本质差异是“外部系统的顺序 I/O”和“内存数据的函数式变换”。6.2 核心差异对照维度java.io 流java.util.stream.Stream数据来源文件、网络、内存数组等外部源集合、数组、生成器等内存数据核心操作读写字节/字符filter/map/reduce 等函数式操作消费方式单向、一次性单项、一次性但可并行资源释放close() 关闭底层资源部分持有 I/O 资源的 Stream 也要 close()用途数据传输与落盘数据处理与计算最容易混淆的场景是Files.lines(path, charset)它返回一个StreamString但背后打开的是文件 IO。不少开发者拿到这个流后没有关闭或者在一个普通集合的Stream中先入为主地认为可以反复消费结果要么句柄泄漏要么第二次消费时报“stream has already been operated upon or closed”。6.3 Files.lines 的正确用法把大的文本文件按行交给函数式管道处理是很优雅的写法但必须记得这个Stream持有文件句柄要用try-with-resources包住try (StreamString lines Files.lines(path, StandardCharsets.UTF_8)) { long count lines.filter(line - line.contains(error)) .count(); System.out.println(count); }这个写法既能享受函数式 API 的简洁又不会泄漏资源。如果只是普通集合转出来的Stream不持有外部资源确实不需要关闭但养成在流上不反复使用的习惯总没错。6.4 我的个人实践建议我现在处理文件时有一套固定取舍小文件优先Files.readAllBytes或readAllLines中等文件按行处理用Files.newBufferedReader需要函数式管道就Files.lines并配try-with-resources大文件二进制读写优先FileChannel配合堆外缓冲区追求极致复制性能就Files.copy或transferTo。这套取舍不是为了炫技而是每类方法背后对应不同的资源成本和内存模型选对了线上问题能少一大半。回到开头说的那个老项目我最终把附件模块全部改造了一遍文本统一显式指定UTF-8所有流都用try-with-resources包裹大文件换成缓冲流分块读写小文件直接由Files.copy接管。改动不算大但线上乱码、超时、句柄报错都陆续消失了。期间踩过的那些坑大多不是 API 不会用而是没想清楚流背后的数据方向、缓冲时机和资源生命周期。把这些基础想明白Java 里的流相关知识基本就成了一张清清楚楚的地图。

相关新闻

Easy LESS 基础使用:在 VSCode 里把 .less 自动编译成 CSS 的完整配置

Easy LESS 基础使用:在 VSCode 里把 .less 自动编译成 CSS 的完整配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 4:27:46 阅读更多 →
拒绝通宵赶论文!7款AI写作辅助软件1天实现毕业流程全通关|TaoToken统一Key接入实测

拒绝通宵赶论文!7款AI写作辅助软件1天实现毕业流程全通关|TaoToken统一Key接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 4:27:46 阅读更多 →
C++构造函数可以重载,析构函数为什么不行?原理与替代方案

C++构造函数可以重载,析构函数为什么不行?原理与替代方案

前两天在技术群里又看到有人在问:“构造函数和析构函数可以重载吗?”下面很快有人抢答:构造函数可以重载,析构函数不可以。结论确实没问题,但继续追问一句“为什么析构函数不可以?如果我真的需要不同清理方…

2026/10/10 4:27:46 阅读更多 →

最新新闻

@nteract/actions 动作系统指南:nteract 核心 SDK 中 Redux 动作与 action creator 的完整解析

@nteract/actions 动作系统指南:nteract 核心 SDK 中 Redux 动作与 action creator 的完整解析

开发工具数据科学 【免费下载链接】archived-desktop-app The old electron based nteract notebook 项目地址: https://gitcode.com/gh_mirrors/nt/archived-desktop-app 点击查看 免费下载 nteract/actions 是 nteract 核心 SDK 中负责定义 动作常量(…

2026/10/10 5:10:27 阅读更多 →
Lit-LLaMA TPU 支持实战指南:在 Google Cloud TPU v4 上运行 LLaMA 推理

Lit-LLaMA TPU 支持实战指南:在 Google Cloud TPU v4 上运行 LLaMA 推理

人工智能大模型预训练微调LoRA模型量化 【免费下载链接】lit-llama Implementation of the LLaMA language model based on nanoGPT. Supports flash attention, Int8 and GPTQ 4bit quantization, LoRA and LLaMA-Adapter fine-tuning, pre-training. Apache 2.0-licensed. 项…

2026/10/10 5:10:27 阅读更多 →
LogicStack-LeetCode 刷穿 LeetCode:611. 有效三角形的个数(中等)——排序、二分与双指针三解法全解析

LogicStack-LeetCode 刷穿 LeetCode:611. 有效三角形的个数(中等)——排序、二分与双指针三解法全解析

教程文档 【免费下载链接】LogicStack-LeetCode 公众号「宫水三叶的刷题日记」刷穿 LeetCode 系列文章源码 项目地址: https://gitcode.com/gh_mirrors/lo/LogicStack-LeetCode 点击查看 免费下载 本篇技术指南围绕「刷穿 LeetCode」系列第 611 题展开,…

2026/10/10 5:10:27 阅读更多 →
AnyPS5实战:从零打造PS5远程游戏串流与网络优化方案

AnyPS5实战:从零打造PS5远程游戏串流与网络优化方案

看到“AnyPS5”这个项目名,第一反应是这群玩家真会起名字:字面意思是“任意一台PS5”,实际干的事是让任何一台PS5都能脱离客厅的束缚——手机、平板、笔记本、旧电脑,甚至异地另一台主机,都能随时接过来继续玩。我不是…

2026/10/10 5:10:27 阅读更多 →
linux操作系统进程概念

linux操作系统进程概念

1 概述一个已经加载到内存中的程序windows的进程2 PCB2.1概述PCB(程序控制块),一种描述进程属性的结构体对象。linux 下被称为task_struct在Linux中可以去/proc系统文件查看进程,或使用ps axj命令查看2.2 task_struct大概内容标示…

2026/10/10 5:10:27 阅读更多 →
NYU-DLSP20 自监督学习(一):从 ImageNet 标注瓶颈到 Pretext 任务——相对位置、旋转预测、Shuffle  Learn 与 Jigsaw 拼图

NYU-DLSP20 自监督学习(一):从 ImageNet 标注瓶颈到 Pretext 任务——相对位置、旋转预测、Shuffle Learn 与 Jigsaw 拼图

示例工程 【免费下载链接】NYU-DLSP20 NYU Deep Learning Spring 2020 项目地址: https://gitcode.com/gh_mirrors/pyt/pytorch-Deep-Learning 点击查看 免费下载 本文基于 NYU-DLSP20(NYU 2020 春季深度学习课程)第 10 周讲义 A「Self-Supervised Learning - Pret…

2026/10/10 5:09:27 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →