编程的两端:靠近机器与靠近业务的平衡之道
刚入行的时候我一度觉得编程世界里只有两种人一种盯着内存地址和 CPU 占用率聊几句就蹦出“栈溢出”“缓存命中率”另一种整天对着需求文档画流程图嘴里全是“业务闭环”“用户痛点”。这两类人坐在一起开会经常鸡同鸭讲。后来带团队、做技术方案、排查线上故障才慢慢意识到这种撕裂感是真实存在的。编程确实有“两端”——一端靠近机器一端靠近业务。绝大多数工程问题本质上都是这两端没有对齐造成的。本文想把这“两端”拆开讲清楚它们各自关注什么、需要什么能力、为什么程序员必须同时理解它们以及在日常开发中如何把两端串起来。不管你是刚学编程的在校生还是已经写了三五年业务的开发这篇文章都值得读完。它不会教某个具体框架的 API但会帮你重新审视自己每天写代码时到底站在哪一端。1. 编程的两端到底在说什么1.1 两端不是“低级”和“高级”很多人说起“底层”潜意识里会把它等同于“更高级的技术”觉得会写 C、会看汇编、能搞定操作系统的人就比写 Java 业务代码的人厉害。这个认知很常见但也很容易把人带偏。“编程的两端”与其说是水平高低不如说是关注半径不同。一端是靠近机器的一端。这一端关心的是代码最终怎么变成指令、数据如何在内存和磁盘之间流动、一个循环为什么慢、并发到一定程度为什么吞吐量上不去。它是计算机体系结构、操作系统、网络协议、编译原理等知识交汇的地方。另一端是靠近业务的一端。这一端关心的是需求怎么拆分、领域模型怎么建立、接口怎么设计才能让团队高效协作、系统怎么演进才能支撑不断变化的产品逻辑。它是需求分析、架构设计、领域建模、工程规范等能力的集合体。两者没有高低之分但它们对“什么是好代码”的判断标准往往不一样。靠近机器的开发者看到一段代码第一反应是它的时间复杂度和内存占用靠近业务的开发者看到同一段代码第一反应是它能不能被下一个需求复用、别人能不能轻松看懂。1.2 两种典型的开发者画像在真实项目里你会看到两种非常典型的开发者。第一种可以叫“系统型开发者”。他们往往对技术本身有强烈的兴趣喜欢读源码、研究框架底层的实现原理。遇到问题下意识地往深处挖。线上接口变慢了他们第一反应是看 GC 日志、抓线程 dump、检查数据库连接池配置。这类开发者价值很高因为很多疑难杂症只有这种深挖能力才能解决。第二种可以叫“业务型开发者”。他们对业务逻辑有很强的敏感度能快速把产品需求翻译成技术方案善于用合理的抽象降低重复代码知道一个功能在哪里扩展最方便。业务型开发者在需求评审会上往往最有话语权因为他们能提前发现需求里的逻辑漏洞。但这里有个残酷的现实只站在一端的人越往后走越吃力。只懂系统不懂业务的开发者容易做出技术上很完美、但根本不解决业务问题的方案。把简单需求做成微服务架构、过度设计缓存体系归根结底是只看到了技术这一端。只懂业务不懂系统的开发者容易写出“能跑但经不起推敲”的代码。功能确实做出来了但一遇到流量波动就各种超时日志里全是报错却不知道从哪里下手排查。代码不是写完就结束了它跑在真实的机器和网络上。1.3 为什么必须同时理解两端编程是一件很特殊的事它是唯一一个需要同时跟“机器逻辑”和“人的需求”打交道的工程活动。机器逻辑是确定的、严谨的CPU 不会骗你内存不会跟你讨价还价。人的需求是模糊的、变化的用户今天说想要 A明天可能就改成 B。编程工作就是在这两者之间搭桥。如果只理解机器你确实能把一段代码压榨到极致但你可能在解决一个根本不存在的问题。如果只理解业务你能画出很漂亮的架构图但代码一上线性能问题就会把设计打回原形。真正优秀的工程师不是站在某一端而是站在中间。他们知道业务需求需要什么样的技术支撑也知道技术方案会受到哪些现实条件的约束。他们不会为了技术而技术也不会为了业务而牺牲掉最基本的工程底线。2. 靠近机器的一端从代码到指令2.1 这一端关注的核心问题靠近机器的一端本质上是在回答一个问题一段代码写出来之后计算机会怎么执行它这个问题可以拆成很多层代码经过编译或解释之后变成了什么样的中间表示数据在内存里是怎么布局的对象是分配在堆上还是栈上一个 for 循环为什么比另一个 for 循环慢是分支预测的问题还是缓存局部性的问题网络请求从一台机器发出经过哪些节点最终到达另一台机器多个线程同时操作同一个变量CPU 的缓存一致性协议是怎么协调的听起来都是计算机基础课的内容但它们在真实开发中每天都在发生。最常见的例子就是接口性能优化。你拿到一个慢接口先看代码再查数据库最后用 profiler 一通分析发现瓶颈竟然不在业务逻辑本身而是一个不起眼的循环里频繁拼接字符串导致内存分配过多GC 压力变大。这种问题靠业务思维是看不出来的。业务上它完全正确逻辑上挑不出毛病但它跑在真实的机器上就是要慢。这时候你需要的是“靠近机器”的思维能力。2.2 一个性能对比实例先来看一个非常典型的例子。假设我们要把一个列表里的数字拼接成一个字符串对于 Python 来说很多人会本能地写出下面这段代码# 文件路径examples/string_concat_slow.py def build_string_slow(items): result for item in items: result str(item) return result这段代码的逻辑没有任何问题。但它的性能隐患在于字符串是不可变对象每次执行result str(item)都会创建一个新的字符串对象然后把旧内容复制一遍。当列表元素很多时复制开销会急剧放大。换一种写法用join来做# 文件路径examples/string_concat_fast.py def build_string_fast(items): return .join(str(item) for item in items)join会先计算出最终字符串的总长度然后一次性分配足够的内存避免了循环中反复创建中间对象。我们可以用timeit实际验证一下两者的差距# 文件路径examples/compare_concat.py import timeit items list(range(100000)) slow_time timeit.timeit( build_string_slow(items), setupfrom string_concat_slow import build_string_slow; items list(range(100000)), number10 ) fast_time timeit.timeit( build_string_fast(items), setupfrom string_concat_fast import build_string_fast; items list(range(100000)), number10 ) print(fslow: {slow_time:.4f}s) print(ffast: {fast_time:.4f}s) print(ffast is {slow_time / fast_time:.1f}x faster)在我本机的 Python 3.10 环境下前者的耗时大约是后者的几十倍。这个结果并不夸张字符串拼接的差异在数据量上去之后就是指数级的体现。这个例子想说明的是同样的业务逻辑站在机器一端看执行效率可能天差地别。这不是什么冷门技巧而是每个语言里都在发生的日常。理解这一端不是为了炫技而是为了在性能问题出现时能迅速判断出问题方向。2.3 为什么底层思维影响上层代码有人可能会说现在的业务系统瓶颈不都在数据库和网络 IO 上吗在代码里扣字符串拼接有什么意义这话只对了一半。数据库慢、网络慢确实是绝大多数业务系统的真实瓶颈。但恰恰因为如此代码层面的无谓开销才更不该被忽视。一个一万行的服务如果你能确认热点集中在某一个循环里优化这个循环带来的收益可能比换个数据库连接池更明显。更重要的是底层思维会改变你写代码时的习惯。有了底层思维你会下意识地避开明显有性能陷阱的写法不是因为你背过规则而是因为你理解它为什么慢。你会在设计接口时考虑数据量级而不是只在压力测试失败之后才回来补救。你会更重视日志和监控因为你知道线上系统的行为是复杂、动态的没有观测数据的优化都是盲人摸象。而且底层思维在故障排查时的价值无法替代。一个 CPU 飙高的问题业务代码看起来一切正常但用top看到某个线程占用异常再用jstack抓一下线程栈立刻就能定位到是哪个方法的死循环或频繁 GC——这些能力本质上是“靠近机器的一端”给你的。3. 靠近业务的一端从需求到系统3.1 这一端关注的核心问题另一端离用户最近的一端关心的是一个完全不同的主题如何把不确定的、持续变化的需求变成稳定可维护的系统。这一端要回答的问题包括需求文档里这句话背后的真实场景是什么用户是真的需要这个功能还是只是想解决另一个问题这个业务领域里核心实体是什么它们之间的关系怎么建模如果产品下个月要增加一种新的支付渠道代码改动量应该是 1 个文件还是 20 个文件多个开发同时在一个模块上工作怎么设计接口才能减少冲突这个系统要支撑五年的演进现在设计的边界能包住未来的变化吗这些问题没有标准答案但它们决定了系统的长期命运。一个业务系统刚开始功能少的时候怎么设计都行。三个接口、两张表怎么折腾都不会太乱。真正拉开差距的是半年之后、一年之后当需求翻了两倍、团队从两个人变成十个人系统的可维护性才真正开始说话。靠近业务的一端拼的不是谁更懂某个中间件而是谁能把“复杂业务”拆解成“清晰的模块”。3.2 一个业务抽象实例来看一个非常经典的业务场景支付渠道对接。假设我们的系统需要支持支付宝、微信、银行卡三种支付方式。最常见的第一版代码是这样写的// 文件路径src/main/java/com/example/pay/PayServiceV1.java public class PayServiceV1 { public String pay(String channel, double amount, String orderId) { if (alipay.equals(channel)) { return alipayPay(amount, orderId); } else if (wechat.equals(channel)) { return wechatPay(amount, orderId); } else if (bankcard.equals(channel)) { return bankcardPay(amount, orderId); } throw new IllegalArgumentException(unsupported channel: channel); } private String alipayPay(double amount, String orderId) { // 调用支付宝 SDK省略具体实现 return alipay: orderId; } private String wechatPay(double amount, String orderId) { // 调用微信支付 SDK省略具体实现 return wechat: orderId; } private String bankcardPay(double amount, String orderId) { // 调用银行接口省略具体实现 return bankcard: orderId; } }这段代码的问题在第一个版本里并不明显。但如果下个月要接银联后面还要接 PayPal每个渠道的接入方式、回调处理、对账逻辑都不一样这个if-else会越来越庞大。修改一个渠道可能影响另外几个渠道这是典型的“面向修改开放”的坏味道。稍微做一层抽象引入策略模式// 文件路径src/main/java/com/example/pay/PayChannel.java public interface PayChannel { boolean supports(String channel); String pay(double amount, String orderId); String callback(String params); }// 文件路径src/main/java/com/example/pay/AlipayChannel.java Component public class AlipayChannel implements PayChannel { Override public boolean supports(String channel) { return alipay.equals(channel); } Override public String pay(double amount, String orderId) { // 调用支付宝 SDK省略具体实现 return alipay: orderId; } Override public String callback(String params) { // 支付宝回调处理 return callback ok; } }再用一个路由器统一处理// 文件路径src/main/java/com/example/pay/PayServiceV2.java Service public class PayServiceV2 { private final ListPayChannel channels; public PayServiceV2(ListPayChannel channels) { this.channels channels; } public String pay(String channel, double amount, String orderId) { return channels.stream() .filter(c - c.supports(channel)) .findFirst() .map(c - c.pay(amount, orderId)) .orElseThrow(() - new IllegalArgumentException(unsupported channel: channel)); } }改造之后新增一种支付渠道只需要新增一个实现了PayChannel的类不需要改动现有的支付核心流程。这就是“对扩展开放、对修改关闭”的实际体现。这个例子本身就是“靠近业务一端”的思维方式流程是稳定的变化的地方是“渠道接入”这一维把稳定和变化分开让变化的地方独立扩展。3.3 为什么抽象能力决定系统上限写代码谁都会但把系统设计得“改一个需求不用伤筋动骨”是需要刻意练习的。业务端的核心能力就是判断什么地方会变、什么地方不变然后基于这个判断做边界划分。这个判断错了系统最初看起来再漂亮后续也会被需求变化推倒重来。所以业务型开发者日常做得最多的不是写新功能而是“重构重构再重构”——把第一次没看清的边界调整到更合理的位置。这不是失败而是业务开发的常态。认识到“第一次设计可能不完美”这件事本身就是靠近业务这一端的重要心态。4. 两端的核心能力对比4.1 知识结构对比下面一张表可以比较清楚地展示两端开发者的核心差异维度靠近机器的一端靠近业务的一端核心知识操作系统、计算机网络、数据结构、编译原理、数据库引擎需求分析、领域建模、架构设计、接口规范、项目管理常用工具profiler、GDB、tcpdump、Wireshark、arthas、JFR白板、UML 图、PRD 文档、原型工具、Swagger关注指标CPU、内存、GC、延迟、吞吐量、错误率需求覆盖率、交付周期、模块复用率、变更影响面日常输出性能优化方案、故障报告、底层组件、监控告警规则系统设计方案、代码架构、接口文档、业务模块划分最容易出的问题过度设计、脱离业务、为了性能牺牲可维护性只重实现不重原理、线上故障束手无策、代码“能跑就行”这个表格只是为了辅助理解。真实情况中任何一个优秀的开发者都会同时具备两端的部分能力只是擅长程度不同、偏好不同。4.2 两种思维模型的不同靠近机器的一端的思维可以叫“因果链思维”每一步执行都有确定的输入和输出一个问题发生必然可以沿着调用链一路追下去直到某个确定的原因。这种思维在排故障时价值巨大因为它不允许你说“不知道怎么回事可能就是运气不好”——系统不会无缘无故出问题。靠近业务的一端的思维可以叫“系统设计思维”面对模糊需求先做分解把一个大问题拆成若干可独立解决的问题再定边界让每个模块的职责清晰然后做抽象让变化的部分可以被扩展。这种思维在面对混乱时价值巨大。有意思的是这两种思维并不能完全互相替代。因果链思维遇到混沌的业务需求会不知所措系统设计思维遇到诡异的内存问题也会没有抓手。但它们是可以互相启发的底层问题的排查方法可以迁移到业务问题的定位上业务边界的定义方式也可以帮助理解一个复杂系统的分层结构。4.3 工作节奏与协作方式工作节奏也很不一样。靠近机器的优化和排障工作是“即时反馈”型。问题就摆在那里定位到、修掉效果立竿见影。这种快反馈让人上瘾也是很多程序员偏爱技术深度的心理原因——每天都有确定的产出确定性带来安全感。靠近业务的设计工作是“延迟反馈”型。你做的抽象设计可能半年之后才能验证是否合理你定义的模块边界可能要到下个需求来临时才知道是否好用。这种不确定性让人焦虑但也正是业务开发的魅力所在你的每一次设计判断都会在未来某个时刻得到验证或打脸。在实际团队里这两种角色需要互相配合。系统型开发者要接受业务才是系统存在的理由技术只是手段。业务型开发者要接受没有扎实的系统认知做底座任何漂亮的架构设计都可能在线上故障面前碎成一地。5. 日常工作中如何同时修炼两端5.1 从业务代码往底层深挖大多数程序员的工作日常是写业务代码这是不可避免的。但同样是在写业务代码一个人的成长速度可以完全不同。关键区别在于遇到问题的时候你是停在“调通为止”还是继续往下挖一层。举个例子一个接口偶发超时。大多数人会加日志、加大超时时间、或者直接重试一把。但如果你继续挖超时时连接池的状态是什么样的数据库当时的活跃会话数是多少GC 有没有发生网络重传率是否异常你就是在用业务问题牵引自己往机器的一端走。这种“由业务触发、往底层深挖”的学习方式比单纯看书效率高得多。因为你有真实的问题背景、有复现路径、有验证方法学到的每一个知识点都是能落地应用的。5.2 从底层能力往业务迁移反过来如果你是偏系统型的开发者要刻意训练自己从业务视角看问题。一个很实用的方法是每次做完一个技术方案多问自己一个问题——“这个方案给业务带来了什么实际价值”如果答案是“没什么直接价值就是技术上更优雅了”那大概率是过度设计。另一个方法是尝试做业务需求的“翻译者”。产品经理说“用户想更快地看到订单状态”技术上的选项很多前端轮询、后端推送、长连接、消息队列。你要能在几个方案里结合开发成本、运维复杂度、性能收益给出一个合适的建议。这种能力只能靠刻意思考练出来。5.3 用可量化的指标串联两端“两端”之间最好的桥梁就是可量化的指标。顶层看业务日活、转化率、订单量、用户投诉率、新功能上线速度。底层看系统QPS、TP99 延迟、错误率、CPU 使用率、内存水位、GC 频率。这两组指标是天然联动的。用户投诉变多了去查某个接口的 TP99 延迟是不是突然飙高新功能上线速度变慢了去看代码结构的耦合度是不是阻碍了并行开发。每一个业务指标的恶化几乎都能在系统指标上找到先兆每一个系统指标的异常最终也会反映到业务结果上。所以成熟的工程师写日报时不会只写“今天修了一个 bug”而会写“解决了某某场景下接口超时的问题接口 TP99 从 800ms 下降到 200ms预期将降低用户操作等待反馈率”。把两端串起来工作价值才真正可见。5.4 推荐的学习路径如果想系统地修炼两端可以参照这个顺序先打好靠近机器的地基认真学一遍数据结构与算法不要求刷几千道题但至少要知道不同数据结构的时间复杂度差异补一下操作系统的基础概念进程、线程、内存、IO你写的每个程序都逃不开这些了解网络协议的基本分层TCP/IP、HTTP 这些是你排查问题的基础。然后建立靠近业务的框架学习领域建模的基本方法理解实体、值对象、聚合这些概念实践设计原则SOLID、DRY、KISS重点不是背名字而是能在代码里识别出坏味道熟悉常见架构模式分层架构、事件驱动、微服务但要明白它们各自适合的场景。最后用真实的项目把两端连接起来。去处理一个线上的慢接口从日志、监控、profiler 一路查到代码、数据库再回头提出优化方案或者把一个杂乱的旧模块重构出清晰的边界让下一个需求可以低成本接入。6. 两端失衡的典型问题与排查思路6.1 常见问题与表现在实际团队里两端失衡的现象非常普遍下面是一些典型表现问题现象可能原因解决思路技术方案很炫但业务不买账过于关注技术端没有理解业务实际诉求方案评审前先明确业务目标和验收标准线上接口偶发超时无人能排查团队普遍缺少系统端能力只会写业务逻辑补充监控告警建立故障演练机制培养排障能力代码扩展性差每加一个需求都要动核心流程业务端抽象不足模块边界设计不合理梳理需求历史识别稳定与变化重构模块边界动不动就做“性能优化”但优化后收益不明显用系统端的惯性处理业务问题属于盲目优化先用 profiling 确认热点用数据证明优化价值团队成员各写各的代码风格混乱过度偏重个人技术偏好缺少团队工程规范统一代码规范推行 Code Review 制度6.2 如何判断自己当前偏科这里可以做一个简单的自我检查问自己几个问题。你看到一个接口性能不佳第一反应是想改代码还是先看监控数据如果你习惯于立刻改代码你可能有点偏“直觉型”缺少系统端的证据意识。你拿到一个新的产品需求第一时间想到的是“这个需求要改哪几个表”还是“这个需求反映了什么业务场景”如果只想着改表你大概率偏业务实现端缺少一点领域思维。你写代码时是优先保证别人能看懂还是优先保证自己写得爽代码是要给团队维护的过度追求个人炫技本质上是只看到了自己这一端。你遇到线上故障是从日志和监控开始排查还是先猜测“可能是缓存的问题”靠猜测排障定位问题的速度会慢很多。如果你发现自己好几个答案都偏向某一侧就要有意识地在另一边补课了。6.3 团队中如何实现两端互补在团队层面不需要每个人都是全栈全能的“六边形战士”但需要确保团队整体同时具备两端的能力。比较务实的做法是让偏系统端的同学负责技术底座、性能优化、故障排查体系让偏业务端的同学负责需求拆解、模块设计、核心领域逻辑。两类人在同一个需求上必须共同参与评审而不是各做各的。同时团队应该建立知识共享机制。系统端的同学排查完一个诡异故障要沉淀成文档或分享把排查思路讲给业务端的同学听业务端的同学做完一次大的重构也要把设计决策的背景和取舍讲清楚让系统端的同学理解为什么边界画在这里。这样一来个体的偏科不会成为团队的短板因为两端能力通过协作被连接起来了。7. 工程实践建议7.1 性能优化三步走在“靠近机器的一端”做任何性能优化都要遵循一个基本顺序先测量再定位最后优化。这个顺序能避免浪费大量时间去优化一个根本不存在的瓶颈。测量最基础的工具就是性能分析器。还是以 Python 为例标准库里的cProfile可以帮你定位到函数级别的耗时分布# 文件路径examples/profile_demo.py import cProfile import pstats def demo_task(): data list(range(1000000)) total sum(data) new_list [x * 2 for x in data if x % 2 0] return total, len(new_list) if __name__ __main__: profiler cProfile.Profile() profiler.enable() demo_task() profiler.disable() stats pstats.Stats(profiler) stats.sort_stats(cumulative).print_stats(10)运行之后你会得到一个按累计耗时排序的函数调用统计能清楚地看到时间花在哪里。有了这个数据你才有资格说“这个循环是热点”。优化的常见策略包括减少循环内的重复计算、用更高效的数据结构、减少对象的重复创建、利用缓存、合理使用多线程或多进程。每条策略都要在 profiling 数据的指引下进行优化完之后再重新压测对比用数字说话。7.2 代码可读性与性能的平衡在“靠近业务的一端”最重要的工程原则是可读性优先于微优化。一句话值得刻在工位上——“代码是写给人看的只是顺便能被机器执行。”绝大多数业务代码优先保证的是清晰、简单、易于修改而不是快那零点几毫秒。但如果性能确实成为问题定位到热点之后再针对性地优化那一小段代码也不迟。在这个原则下你不会在普通业务方法里加上一堆位运算或手工内联因为那会让后来维护的人看得一头雾水。性能优化要写在正确的位置。数据库慢就优化 SQL 和索引循环里频繁创建对象就调整对象生命周期网络请求太多就考虑批量接口。真正值得在代码层面“抠”的地方比例通常很小。7.3 日志与监控是连接两端的桥梁系统端和业务端能顺畅对话靠的是数据。而数据的第一来源就是日志和监控。日志不能只记“操作成功”“操作失败”要包含关键上下文订单号、用户标识、耗时、错误堆栈、上下游调用链标识。没有上下文的日志排障时基本等于没有日志。监控项要覆盖两端业务侧要有核心接口调用量、成功率、耗时分位数系统侧要有 CPU、内存、GC、线程池状态、数据库连接数。两端指标关联起来才能构成完整的可观测性体系。一个比较实用的建议是每次线上故障处理完之后补一条监控告警规则。确保同样的问题下次能第一时间发现而不是又等到用户投诉才被动排查。7.4 学习新技术时保持两端对照面对一门新技术可以同时从两端追问它到底“新”在哪里。从系统端问它的底层实现有什么创新是数据结构更高效了还是利用了新的硬件特性它在高并发、高负载下表现如何有没有已知的性能边界从业务端问它解决了什么业务场景下的痛点引入它会增加多少运维成本团队现有成员能否掌握它和我们已有系统的边界怎么划两个问题都得到答案之后再决定是否引入会稳妥得多。盲目追逐热点往往是只看到了技术端的一面忽略了它落地的真实成本。8. 总结“Two Ends of Programming”不是一个学术概念而是一个每天都在发生的工程现实。靠近机器的一端给你确定性代码最终会怎么执行你的系统能扛住多大的压力。靠近业务的一端给你方向感系统为什么存在它要解决谁的什么问题。对个人成长来说不必强求自己在两端都成为专家但至少要有一只在另一端的“手电筒”——当问题发生的时候你知道该往哪个方向照一照。如果现在只能做一件事我的建议是把手头系统的一个线上问题从头到尾完整排查一遍。从用户反馈或监控告警开始顺着日志、指标、代码、底层调用一路追下去直到定位根因并提出修复方案。这个过程做好一次比读十篇理论文章都有用。因为它会强迫你同时睁开两端的眼睛一边理解业务场景一边理解系统行为。编程的乐趣和深度往往就藏在这两者交会的地方。

相关新闻

VC++通过USB直接驱动GT800打印机:ZPL指令与USB通信实战

VC++通过USB直接驱动GT800打印机:ZPL指令与USB通信实战

简介:本资源面向使用VC进行Windows桌面开发的工程师,聚焦通过USB接口驱动斑马GT800打印机、以ZPL语言输出条形码标签这一具体场景。包内共24个文件,以cpp与h源码、vcxproj工程文件、sln解决方案为主,辅以suo、ipch等VS调试缓存及l…

2026/10/17 7:02:02 阅读更多 →
单图生成3D房间世界模型:部署、编辑与API调用实战

单图生成3D房间世界模型:部署、编辑与API调用实战

这次要说的不是“又一个生图模型”,而是一类更直接的场景生成模型:给它一张房间照片,它能把静态的 2D 图像变成可进入、可编辑的 3D 空间,并且桌椅、摆件这类物体可以单独选中、随意更换。换句话说,用户不再只是“看一…

2026/10/17 7:02:02 阅读更多 →
AI应用下半场:从模型能力到上下文工程与工具调用的系统化实践

AI应用下半场:从模型能力到上下文工程与工具调用的系统化实践

2024 年,做一个能对话的 AI 聊天 Demo,还值得发一篇技术博客;2025 年,再发同样的 Demo,评论区大概率会问:然后呢?这不是开发者变挑剔了,而是 AI 应用开发的叙事真的变了。过去一年多…

2026/10/17 7:02:02 阅读更多 →

最新新闻

Termexo v0.9.0体验:AI编程CLI的安装、状态监控与Diff审查实战

Termexo v0.9.0体验:AI编程CLI的安装、状态监控与Diff审查实战

我在过去半年里,陆陆续续在本地开发环境里接入了三款AI编程CLI,从最早折腾Codex安装到后来用上Claude Code,再到把Gemini CLI加进日常工作流。本来觉得差不多了,结果看到Termexo v0.9.0发布的时候,还是没忍住又试了一把…

2026/10/17 9:48:45 阅读更多 →
2026年AI编程工具全景:六大类33款主流工具选型指南

2026年AI编程工具全景:六大类33款主流工具选型指南

我2026年初重新梳理自己团队的工具链时,才发现手边已经陆陆续续用了不下20种AI编程工具,还有一堆躺在收藏夹里没来得及试的。这个领域的变化速度已经不能用“月更”来形容,几周不关注,可能就会冒出一个新的Agent框架、一个新的云I…

2026/10/17 9:48:45 阅读更多 →
Claude Code 深度配置指南:把终端 AI 代理变成你的 AI 工程团队

Claude Code 深度配置指南:把终端 AI 代理变成你的 AI 工程团队

如果你最近刷技术社区,大概率已经看到不少人在聊 Claude Code。我的感受是,这玩意儿和一个普通聊天网页最大的区别在于:它不是“你问一句、它答一句”的问答工具,而是能真正落进工程流程里、替你把活干完的那个执行者。简单一句话…

2026/10/17 9:48:45 阅读更多 →
2026年AI编程工具全盘点:33款主流工具五大阵营详解

2026年AI编程工具全盘点:33款主流工具五大阵营详解

2026年再聊AI编程工具,已经不是"要不要用"的问题,而是"到底该把哪几个装进自己的工作流"。我从补全时代一路用到现在,最大的感受是:这三年工具迭代的速度,比过去十年加起来都快,而且20…

2026/10/17 9:48:45 阅读更多 →
MP2642GR-Z与PIC32MZ实现双节锂电池主动均衡设计

MP2642GR-Z与PIC32MZ实现双节锂电池主动均衡设计

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

2026/10/17 9:48:45 阅读更多 →
用OpenCV解构视觉错觉:从jagarikin图像提取四大数字指纹

用OpenCV解构视觉错觉:从jagarikin图像提取四大数字指纹

1. 为什么一张静态图能让眼睛“上当”——从jagarikin作品切入视觉错觉的底层机制你有没有在刷社交媒体时,突然被一张图钉住:明明是静止的,却感觉它在旋转;明明线条都是直的,却像波浪一样起伏;明明图案完全…

2026/10/17 9:47:45 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →