Java网络接口工具类:多网卡IP选择与MAC地址获取实战

1. 为什么“获取网络接口信息”这件事值得单独写一个工具类

很多做Java后端或者中间件开发的朋友,第一次接触NetworkInterface这个类,大概率是在排查线上问题时——比如服务注册到注册中心,结果注册了一个127.0.0.1,或者一台机器上跑了多个网卡,程序却选错了出口IP。这时候你去翻JDK文档,会发现java.net.NetworkInterface这个类其实从Java 1.4就存在了,API也不算复杂,但真正要用它写出一段“在任何环境下都能拿到正确结果”的代码,坑比想象中多得多。

我自己在好几个项目里都封装过网络接口工具类,从最早只会NetworkInterface.getNetworkInterfaces()一把梭,到后来要考虑虚拟网卡、Docker网桥、IPv6、网卡状态、MTU、MAC地址格式化、多网卡优先级排序等等问题,前后迭代了不下五版。这篇就把我这些年积累下来的完整思路和代码实现摊开讲清楚,目标是让你看完之后,直接复制过去就能用,不用再自己去踩一遍。

这个工具类适合谁?一是做服务注册与发现、RPC框架、分布式任务调度的同学,你们需要准确拿到本机可对外通信的IP;二是做运维监控、资产采集、设备管理的同学,你们需要枚举所有网卡的详细信息;三是做网络编程教学或者想系统梳理Java网络API的同学,这篇可以当作一个完整的实战案例来读。核心关键词就几个:NetworkInterface、网卡枚举、IP地址获取、MAC地址、本机IP选择策略。

下面我会先讲清楚JDK原生API的能力边界,然后给出一个完整的工具类设计,再逐个拆解每个方法背后的取舍逻辑,最后重点讲那些“文档里不会写、但线上一定会遇到”的坑。

2. NetworkInterface原生API到底能给你什么

2.1 三个核心入口方法的关系

NetworkInterface这个类提供的静态方法不多,但每一个的用途和返回结果差异很大,很多人混着用,结果就是拿到的数据时对时错。

第一个是NetworkInterface.getNetworkInterfaces(),返回一个Enumeration<NetworkInterface>,也就是当前JVM所在操作系统能看到的所有网络接口。注意这里的措辞是“所有”,包括物理网卡、虚拟网卡、回环接口、Docker创建的网桥、虚拟机宿主创建的虚拟适配器等等。这个方法是你做全量枚举的唯一入口。

第二个是NetworkInterface.getByName(String name),根据网卡名称精确查找,比如Linux上的eth0、ens33,Windows上的以太网、WLAN。这个方法在你知道目标网卡名称时非常有用,但跨平台时名称差异极大,不能硬编码。

第三个是NetworkInterface.getByInetAddress(InetAddress addr),根据一个IP地址反查它属于哪个网卡。这个方法在判断“某个IP是不是本机地址”时特别方便。

这三个方法的关系可以这样理解:getNetworkInterfaces()是全集,另外两个是在全集里做条件筛选的快捷方式。实际工具类里,我们通常以第一个方法为主干,后两个作为辅助判断。

2.2 每个NetworkInterface对象携带的信息维度

拿到一个NetworkInterface实例之后,它能告诉你的信息比很多人以为的要多。我把它分成四类:

身份标识类:getName()返回网卡名称,getDisplayName()返回更友好的显示名(在Windows上尤其明显,可能是“Intel(R) Ethernet Connection”这种),getIndex()返回系统分配的索引号。

状态与能力类:isUp()表示网卡是否已启用并处于工作状态,isLoopback()判断是否回环接口,isVirtual()判断是否虚拟接口,isPointToPoint()判断是否点对点连接,supportsMulticast()判断是否支持多播,getMTU()返回最大传输单元。

硬件地址类:getHardwareAddress()返回一个byte[],就是MAC地址的原始字节,长度通常是6字节,需要自己格式化成XX:XX:XX:XX:XX:XX的形式。

IP地址类:getInetAddresses()返回一个Enumeration<InetAddress>,注意一个网卡可以同时绑定多个IP,包括IPv4和IPv6,所以这里必须遍历。另外还有getInterfaceAddresses()返回List<InterfaceAddress>,比前者多了子网掩码和广播地址信息。

理解这四个维度之后,你就能明白为什么简单的getInetAddresses().nextElement()是危险的——它可能返回一个IPv6的本地链路地址,也可能返回一个已经失效的地址,顺序完全不可控。

2.3 原生API的三个天然局限

用久了你会发现,JDK这套API有三个绕不开的局限,这也是为什么必须封装工具类的原因。

第一,没有过滤能力。它把所有接口一股脑给你,包括那些你根本不关心的回环、虚拟、未启用接口。你得自己写过滤逻辑。

第二,没有优先级概念。一台机器有多个可用网卡时,哪个IP最适合对外通信?API不告诉你,你得自己定策略。

第三,异常处理粗糙。getNetworkInterfaces()会抛SocketException,getHardwareAddress()也会抛,而且在某些系统上,访问某些虚拟网卡的信息会直接抛异常导致整个遍历中断。如果不做逐个try-catch,一个坏网卡就能让你的工具类全军覆没。

提示:getNetworkInterfaces()返回的Enumeration在遍历过程中,如果系统网络状态发生变化,行为是未定义的。生产环境建议一次性遍历完并缓存快照,不要边遍历边做耗时操作。

3. 一个能直接落地的网络接口工具类完整实现

3.1 整体设计思路与对外方法规划

我在设计这个工具类时,遵循一个原则:对外方法要少而明确,对内实现要细而健壮。对外暴露的方法控制在六个以内,每个方法解决一个明确的场景问题。

我规划的对外方法如下:

  • getAllNetworkInterfaces():返回所有网卡的原始列表,不过滤,给需要全量信息的场景用。
  • getActiveNetworkInterfaces():只返回已启用、非回环的网卡,日常最常用。
  • getLocalIpAddresses():返回本机所有可用的IPv4地址列表。
  • getFirstNonLoopbackIp():返回第一个非回环IPv4地址,适合快速取一个可用IP。
  • getMacAddress(String interfaceName):根据网卡名获取格式化后的MAC地址。
  • getNetworkInterfaceInfo():返回一个结构化的信息对象列表,包含名称、IP、MAC、MTU、状态等全部字段。

内部实现上,我会把“遍历+过滤+异常隔离”这三件事做成一个私有方法,所有对外方法都基于它来构建。这样逻辑只有一份,维护成本最低。

3.2 核心遍历与异常隔离的实现细节

先看最关键的遍历逻辑。很多人写的是这样:

Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); while (en.hasMoreElements()) { NetworkInterface ni = en.nextElement(); // 直接操作 ni }

这段代码的问题在于,一旦某个网卡的某个属性访问抛异常,整个循环就挂了。正确的做法是把每个网卡的处理包在独立的try-catch里:

public static List<NetworkInterface> getAllNetworkInterfaces() { List<NetworkInterface> result = new ArrayList<>(); try { Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); while (en.hasMoreElements()) { try { NetworkInterface ni = en.nextElement(); if (ni != null) { result.add(ni); } } catch (Exception e) { // 单个网卡获取失败,跳过,不影响整体 continue; } } } catch (SocketException e) { // 整体获取失败,返回空列表 return Collections.emptyList(); } return result; }

这里有个细节值得说:en.nextElement()本身也可能抛异常,所以try要包在它外面。另外返回空列表而不是null,是为了让调用方少写判空逻辑,这是工具类设计的一个基本素养。

3.3 IP地址提取与IPv4/IPv6的区分处理

从网卡里提取IP,核心是遍历getInetAddresses(),然后按类型分流。判断IPv4还是IPv6,最稳妥的方式是看InetAddress的实际类型:

for (InetAddress addr : Collections.list(ni.getInetAddresses())) { if (addr instanceof Inet4Address) { // IPv4 处理 } else if (addr instanceof Inet6Address) { // IPv6 处理 } }

注意这里用了Collections.list()把Enumeration转成List,方便后续操作。为什么不直接用instanceof Inet4Address而不用字符串判断?因为字符串判断容易出错,比如IPv6里也可能包含点分十进制格式的嵌入地址,用类型判断是唯一可靠的方式。

还有一个坑:IPv6地址里有一类是链路本地地址(以fe80:开头),这类地址只在本地链路有效,不能用于跨网段通信。如果你在筛选可用IP,必须把这类排除掉。判断方式是addr.isLinkLocalAddress()。

3.4 MAC地址格式化与空值防御

getHardwareAddress()返回的是byte[],直接toString()出来是类似[B@1b6d3586的东西,必须自己格式化。标准格式是每字节转两位十六进制,用冒号连接:

byte[] mac = ni.getHardwareAddress(); if (mac != null && mac.length > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < mac.length; i++) { sb.append(String.format("%02X", mac[i])); if (i < mac.length - 1) { sb.append(":"); } } return sb.toString(); }

这里有两个防御点:一是mac可能为null,回环接口和某些虚拟接口就没有MAC;二是mac.length可能为0。另外%02X保证单个字节不足两位时前面补零,这是格式规范的要求。

注意:某些虚拟网卡的MAC地址是随机生成的,每次系统重启都会变。如果你的业务依赖MAC做唯一标识,一定要先判断网卡类型,别拿虚拟网卡的MAC当真。

4. 多网卡环境下“选哪个IP”的策略拆解

4.1 为什么不能简单取第一个非回环地址

这是最容易被低估的问题。一台典型的Linux服务器,getNetworkInterfaces()返回的列表里可能有:lo(回环)、eth0(物理网卡)、docker0(Docker网桥)、br-xxxx(自定义网桥)、vethxxxx(容器虚拟网卡)。如果你只是简单地取第一个isUp() && !isLoopback()的地址,很可能拿到的是docker0的172.17.0.1,而不是真正对外的eth0地址。

这个错误的后果很严重:服务注册到注册中心后,其他节点拿着172.17.0.1根本连不上,因为那是Docker内部网段。我见过不止一个团队在这个问题上排查了大半天。

4.2 基于网卡名称的优先级排序策略

一个实用的策略是:优先选择名称符合常见物理网卡命名规则的接口。Linux上物理网卡通常是eth、ens、enp、eno开头,Windows上通常是“以太网”“WLAN”这类。我们可以给网卡名称打一个优先级分数:

网卡名称特征优先级分数说明
eth0 / ens33 / enp0s3100典型物理网卡
eth开头其他90物理网卡变体
wlan / wlp80无线网卡
以太网 / WLAN(中文)80Windows常见命名
docker / br- / veth10容器相关,低优先级
lo / 回环0直接排除

实现上就是遍历时给每个网卡算一个分数,最后按分数降序取第一个。这个策略不是万能的,但覆盖了绝大多数场景,比“取第一个”靠谱得多。

4.3 基于路由表思路的补充判断

如果追求更精确,可以结合“默认路由”的思路来判断。Java本身拿不到路由表,但有一个取巧的办法:尝试建立一个到公网地址的Socket连接(不实际发送数据),然后通过socket.getLocalAddress()拿到系统选择的出口IP。这个方法的原理是让操作系统自己按路由规则选路,结果最准确。

try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress("8.8.8.8", 53), 1000); return socket.getLocalAddress().getHostAddress(); } catch (Exception e) { // 连接失败,回退到网卡遍历策略 }

这个方法的局限是:需要网络可达,且在某些受限网络环境下会超时。所以我的做法是优先用这个方法,失败后再回退到网卡名称优先级策略,两者结合,准确率和可用性都能兼顾。

提示:上面这个“连一下公网地址看出口IP”的技巧,本质是利用操作系统的路由决策,不涉及任何数据传输,超时时间设短一点(比如1秒)即可,不要设太长影响启动速度。

4.4 缓存与刷新时机的权衡

网络接口信息在运行期是可能变化的——插拔网线、切换WiFi、容器网络重建都会导致变化。但每次调用都重新遍历一遍,在频繁调用的场景下(比如每次RPC请求都取一次)性能开销不小。

我的建议是:工具类内部维护一个带过期时间的缓存,默认缓存30秒。取的时候先看缓存是否有效,有效就直接返回,无效才重新遍历。30秒这个值是我根据经验定的,既能覆盖绝大多数“网络状态稳定”的场景,又能在网络变化后半分钟内自动感知。

如果业务对实时性要求极高,可以提供一个refresh()方法手动清缓存。但不要设成每次调用都刷新,那样等于没缓存。

5. 那些线上真实踩过的坑与排查过程

5.1 虚拟网卡导致的SocketException连锁反应

有一次在某个客户的服务器上,工具类直接抛了SocketException,日志显示是在遍历过程中某个网卡上出的问题。但奇怪的是,单独用ifconfig看所有网卡都正常。

排查过程是这样的:我先在代码里把每个网卡的名称和异常信息都打出来,发现是一个名字很长的虚拟网卡,访问它的getHardwareAddress()时抛了SocketException: Device not configured。这个网卡是某个软件安装时创建的,处于半启用状态,系统层面能看到,但底层驱动没完全就绪。

修复方案就是我前面说的异常隔离——把每个网卡的处理包在独立try-catch里,单个失败不影响整体。这个改动之后,工具类在几十台不同环境的机器上再没出过整体失败的情况。

5.2 IPv6地址混入导致的连接超时

另一个坑是:某次服务注册后,其他节点连接超时。排查发现注册上去的IP是一个fe80:开头的IPv6链路本地地址。原因是工具类在筛选时只判断了!isLoopback(),没排除链路本地地址,而恰好那台机器上IPv6地址排在IPv4前面。

修复就是加上!addr.isLinkLocalAddress()和!addr.isAnyLocalAddress()两个判断。isAnyLocalAddress()对应的是0.0.0.0这种通配地址,同样不能用于对外通信。

这个坑给我的教训是:筛选可用IP时,排除条件要写全,回环、链路本地、通配、多播,这四类都要排除。

5.3 容器环境下网卡名称不符合预期的处理

在容器里跑的时候,网卡名称往往是eth0,看起来正常,但有时候会是随机字符串。我遇到过一次,容器网络插件把网卡命名成了类似veth3a2b的形式,导致基于名称前缀的优先级策略失效,取到了一个错误的IP。

解决办法是增加一层兜底:如果按名称优先级排完序后,最高分的网卡IP仍然不可用(比如尝试连接失败),就回退到“连公网看出口IP”的方法。两层策略叠加,容器环境下的成功率大幅提升。

5.4 频繁调用引发的性能问题与缓存改造

最早这个工具类没有缓存,有个服务在每次处理请求时都调一次getFirstNonLoopbackIp()。压测时发现QPS上不去,用火焰图一看,大量时间花在getNetworkInterfaces()上——这个调用在Linux上会去读/proc/net/dev和/sys/class/net,开销比想象中大。

加上30秒缓存后,这个热点直接消失。所以我的经验是:任何涉及系统调用的工具方法,只要结果不是必须实时,都应该加缓存。

6. 把工具类用对:几个容易被忽略的实践建议

6.1 日志里打印网卡信息要克制

排查问题时打印网卡信息很有用,但不要在生产环境每次调用都打全量信息。一台机器可能有十几个网卡,每个网卡多个IP,全打出来日志量很大。我的做法是:只在首次初始化和缓存刷新且结果发生变化时打日志,平时静默。

6.2 单元测试要覆盖边界场景

这个工具类的单元测试不好写,因为它依赖真实系统环境。我的做法是:把“过滤逻辑”和“优先级排序逻辑”抽成纯函数,这部分用Mock数据做单元测试;而“实际获取”部分做集成测试,在CI环境里跑,断言至少能拿到一个非回环IP。

6.3 跨平台差异要心里有数

Windows和Linux在网卡信息上有几个明显差异:Windows的getDisplayName()返回的是带厂商信息的友好名称,Linux返回的通常和getName()一样;Windows上回环接口的名称是“Loopback Pseudo-Interface 1”,Linux上是lo;MAC地址格式两者一致,但虚拟网卡的表现不同。写工具类时不要假设某个平台的行为,所有判断都基于API返回值本身。

6.4 安全软件可能干扰网卡枚举

某些安全软件会创建自己的虚拟网卡用于流量监控,这些网卡有时会返回异常数据。如果你的工具类在特定机器上表现异常,可以先看看是不是有这类网卡存在。处理方式还是那句话:异常隔离,单个失败不影响整体。

7. 关于这个工具类后续可以怎么扩展

目前这个版本覆盖了绝大多数场景,但如果你的业务更特殊,还有几个扩展方向可以考虑。

一是增加网卡流量统计。Java标准库拿不到网卡的收发字节数,但可以通过读取/proc/net/dev(Linux)或者调用系统命令来补充。这个适合做监控采集的场景。

二是支持网卡热插拔监听。目前是缓存过期后被动刷新,如果要做实时感知,可以起一个后台线程定期检查网卡列表变化,变化时主动清缓存并触发回调。

三是增加IP可用性探测。拿到IP后,可以尝试ping一下网关或者做一次TCP握手,确认这个IP真的能对外通信,再返回给调用方。这个会增加耗时,适合对准确性要求极高的场景。

我自己在实际项目里,最常用的还是getFirstNonLoopbackIp()配合缓存这一套,简单可靠。工具类这东西,不是功能越多越好,而是在你需要的场景下足够稳。上面这些代码和策略,你直接拿去改改就能用,遇到新坑再往里加防御就行。

相关新闻

电赛C题无线传输信号模拟系统省一方案:考点拆解与实战调试指南

电赛C题无线传输信号模拟系统省一方案:考点拆解与实战调试指南

简介&#xff1a;本资源为2024年全国大学生电子设计竞赛C题「无线传输信号模拟系统」江苏省第一名完整方案&#xff0c;面向备战电赛的本科生、研究生及信号处理方向学习者&#xff0c;帮助理解多径与直达信号模拟的系统级实现思路。方案以STM32F407ZGT6为主控&#xff0c;通过…

2026/10/21 4:22:45 阅读更多 →
TCP三次握手与四次挥手:从状态机到生产环境故障排查

TCP三次握手与四次挥手:从状态机到生产环境故障排查

提到TCP三次握手和四次挥手&#xff0c;我相信很多读者第一反应是&#xff1a;流程图我早背下来了。真正去了生产环境&#xff0c;服务器上积了一堆TIME_WAIT&#xff0c;客户端莫名其妙卡在SYN_SENT&#xff0c;或者服务端一直CLOSE_WAIT不掉——这时候再回头看教科书上的状态…

2026/10/21 4:21:45 阅读更多 →
内存屏障:多线程并发中看不见的守护者

内存屏障:多线程并发中看不见的守护者

1. 一次线上Bug引出的问题&#xff1a;代码顺序不等于执行顺序1.1 一段"怎么看都没问题"却翻车的代码接手过一个状态机同步模块&#xff0c;核心逻辑精简之后大概是下面这个场景。线程A负责把任务状态从 INIT 推进到 RUNNING&#xff0c;再记录一个开始时间&#xff…

2026/10/21 4:21:45 阅读更多 →

最新新闻

手写JSON解析器:从词法分析到语法树的编译原理实战

手写JSON解析器:从词法分析到语法树的编译原理实战

1. 从一段JSON文本到内存对象&#xff1a;解析器到底在做什么很多人第一次接触编译原理&#xff0c;都是从"写一个JSON解析器"开始的。这个选择很聪明——JSON的语法足够简单&#xff0c;简单到一页纸就能写完文法&#xff1b;但它又足够完整&#xff0c;完整到能覆盖…

2026/10/21 5:11:04 阅读更多 →
Java俄罗斯方块源码解析:游戏主循环、碰撞检测与消行实现

Java俄罗斯方块源码解析:游戏主循环、碰撞检测与消行实现

简介&#xff1a;这是一份面向Java初学者与游戏编程爱好者的俄罗斯方块完整源码&#xff0c;以Java语言实现&#xff0c;适合用来理解经典游戏的核心逻辑与面向对象设计。源码围绕游戏主面板、方块形状、流程控制器与程序入口等关键类展开&#xff0c;涵盖游戏循环、方块生成与…

2026/10/21 5:11:04 阅读更多 →
NLP与无人船:从自然语言指令到自主靠泊的完整技术链路

NLP与无人船:从自然语言指令到自主靠泊的完整技术链路

去年我带着组里的几位同学把一个挺有意思的项目从零做到了仿真验证——给一艘无人船加一套自然语言操控链路&#xff0c;让操作员可以直接说“慢速驶向测试场北侧码头&#xff0c;左舷靠泊”或者“绕开右前方漂浮物&#xff0c;停到A区泊位”&#xff0c;船载系统自己去完成意图…

2026/10/21 5:11:04 阅读更多 →
鸿蒙+Flutter跨平台实战:桌面图标焕新方案全解析

鸿蒙+Flutter跨平台实战:桌面图标焕新方案全解析

桌面图标焕新大师这个名字&#xff0c;听起来像某个手机美化App的宣传语&#xff0c;但它本质上是一个很典型的跨平台实战项目&#xff1a;把视觉设计、资源管理、系统桌面机制和Flutter渲染能力串在一起&#xff0c;最终在鸿蒙设备上完成“一键切换桌面图标风格”的完整闭环。…

2026/10/21 5:11:04 阅读更多 →
从ReAct到龙虾架构:AI Agent编排演进与工程实践

从ReAct到龙虾架构:AI Agent编排演进与工程实践

这两年AI Agent架构的文章我看了不下几十篇&#xff0c;名字一个比一个唬人&#xff1a;ReAct、Plan-and-Execute、Reflexion、多Agent系统、图式编排、龙虾架构……但真能把“从A到B是怎么一步步走出来”讲明白的&#xff0c;确实不多。尤其对小程序员来说&#xff0c;最痛苦的…

2026/10/21 5:11:04 阅读更多 →
AI原生知识库重构:从传统检索到语义网络的实践解析

AI原生知识库重构:从传统检索到语义网络的实践解析

做了三年传统知识库&#xff0c;我一直在琢磨一个问题&#xff1a;资料越存越多&#xff0c;知识却越来越难找&#xff0c;团队知道的东西永远比系统记录的多。传统知识库的把式——目录分类、关键词搜索、标签管理——本质上是在用二维平面的方式梳理立体复杂的真实知识&#…

2026/10/21 5:10:03 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →