Java设计模式速通:场景+实战,快速掌握核心模式

不是每一行代码都值得背下来,但设计模式是少数值得花时间想清楚的东西。尤其是Java生态里,框架源码、中间件、业务系统到处都嵌着这些模式,看不懂它们,读源码就像看天书;看懂了,重构和扩展的底气完全不一样。

这篇文章是我自己总结的一套速通路径,目标是让有基础Java语法能力的人,用尽量短的时间建立起设计模式的完整框架,并且能直接在项目里用上。我会把二十多个模式按类别拆开,讲核心思路、贴可运行的最小示例、说清楚每个模式解决什么问题,最后再用一个综合场景把它们串起来。适合准备面试、准备读源码、或者刚接手一个中大型项目的同学。

1. 速通前的思路准备

1.1 先搞清楚设计模式到底在解决什么问题

很多初学者把设计模式当成一种“高级写法”,觉得背下类图、记住UML就是学会了。实际上设计模式解决的是一个非常朴素的问题:代码在变化面前如何保持稳定。

业务不停变,需求不停加,如果你的代码把“会变的东西”和“不变的东西”焊死在一起,那每次需求变动都要动一大片代码,改一处崩三处。设计模式的核心价值,就是帮你在“变”与“不变”之间画出清晰的边界,把变化点封装起来,让扩展发生在新增代码上,而不是修改旧代码上。

举个例子,一个订单系统一开始只有普通订单,你写了一个OrderService,里面直接new了一个NormalOrder。后来要加会员订单、企业订单,每次加一种都要去改OrderService,改着改着你就会发现这个类越来越肿。工厂模式解决的就是这个问题:把“创建哪种订单”的逻辑从业务代码里挪出去,业务代码只面向抽象接口编程。

所以学设计模式,脑子里始终要有这根弦:这个模式把什么封装起来了?它保护哪个不变点?它让什么样的扩展变得简单?

1.2 速通的正确姿势:不是背类图,而是记“场景”

二十多个GoF模式,逐个背下来确实痛苦,而且背完就忘。我的经验是换个思路,把每个模式压缩成一句话的“场景-方案”对应关系:

  • 某个类只能有一个实例?用单例。
  • 创建对象逻辑复杂,而且有多种分支?用工厂。
  • 构造对象时参数太多、组合太多?用建造者。
  • 给已有对象动态加功能,又不想改原类?用装饰器。
  • 新旧接口不匹配,又改不了旧代码?用适配器。
  • 不想让调用方直接接触真实对象?用代理。
  • 同一套算法有多种实现,要能随时切换?用策略。
  • 一个对象状态变了,一堆对象要跟着响应?用观察者。
  • 算法骨架固定,但某些步骤要子类自己实现?用模板方法。

把模式还原成“遇到什么坑,用什么招”,比背类图有用十倍。你不需要记住每个模式的所有细节,只需要在看到一段代码的时候,能识别出“哦,这里用的是策略模式,所以新增一种计费方式只需要加一个实现类”。

后面我会按照创建型、结构型、行为型三个大类逐个过,每个模式都会配一个最小可运行的Java示例,建议你边看边敲,亲手跑一遍比看十遍都管用。

2. 创建型模式速通:怎么优雅地“造对象”

创建型模式解决的是“对象怎么创建”的问题。它们的共同点是把创建逻辑从使用逻辑中剥离出来,让调用方不关心对象是怎么new出来的、内部有哪些依赖。

2.1 单例模式:全局只有一个实例

单例应该是面试出现率最高的模式,没有之一。它保证一个类在整个JVM进程中只有一个实例,通常用于全局配置、线程池、数据库连接池这类资源。

最标准的写法是双重检查锁:

public class ConfigManager { private static volatile ConfigManager instance; private ConfigManager() { // 私有构造,禁止外部new } public static ConfigManager getInstance() { if (instance == null) { // 第一次检查,避免不必要的同步 synchronized (ConfigManager.class) { if (instance == null) { // 第二次检查,防止多个线程同时创建 instance = new ConfigManager(); } } } return instance; } }

这里有一个关键细节:instance必须用volatile修饰。原因是new ConfigManager()不是原子操作,它分为分配内存、初始化对象、把引用指向内存三步,编译器可能重排序,导致另一个线程拿到一个“还没初始化完成”的半成品对象。volatile能禁止这种重排序。

不过说实话,现在生产环境我更推荐用枚举实现单例,代码简洁到令人发指,还能天然防止反射和序列化破坏单例:

public enum ConfigManager { INSTANCE; private String configPath = "/etc/myapp/config.yml"; public String getConfigPath() { return configPath; } }

枚举单例的缺点是看起来不像“正经单例”,团队里有人不熟悉会一脸懵。所以我的建议是:自己的小项目、工具类可以用枚举,团队大项目用双重检查锁,注释写清楚为什么。

2.2 工厂模式:把“new”收拢到一个地方

工厂模式分三种:简单工厂、工厂方法、抽象工厂。很多人一上来就被这三个概念绕晕,我提供一个简单的理解方式:它们在解决“对象创建逻辑复杂”的问题,只是封装的粒度不同。

简单工厂是最朴素的写法,用一个静态方法根据参数返回不同对象,但违反开闭原则——加一种新产品就要改工厂方法。

工厂方法把“创建对象”这件事下放到子类,每个产品对应一个工厂类。调用方依赖的是抽象工厂和抽象产品,新增产品时只需要新增两个类,不用改旧代码。

抽象工厂则是“创建一族产品”,解决的是产品之间有配套关系、不能混搭的场景,比如一套UI组件,按钮、输入框、对话框必须来自同一个主题体系。

实际业务里最常见的是简单工厂和工厂方法。我给你一个真实场景:订单处理系统里要根据订单类型创建不同的处理器。

public interface OrderHandler { void handle(Order order); } public class NormalOrderHandler implements OrderHandler { public void handle(Order order) { // 普通订单处理逻辑 } } public class VipOrderHandler implements OrderHandler { public void handle(Order order) { // VIP订单处理逻辑 } } public class OrderHandlerFactory { public static OrderHandler createHandler(OrderType type) { switch (type) { case NORMAL: return new NormalOrderHandler(); case VIP: return new VipOrderHandler(); default: throw new IllegalArgumentException("未知订单类型"); } } }

这样业务代码里拿到OrderType之后,直接OrderHandlerFactory.createHandler(type).handle(order),完全不需要关心具体是哪个实现类。

如果你用的是Spring,工厂模式还有一个更优雅的替代方案:把每个处理器注册成Bean,用Map<String, OrderHandler>按类型名自动注入,连工厂类都省了。这算是框架时代对传统工厂模式的一种演进。

2.3 建造者模式:参数太多时的救星

当一个类有七八个字段,其中一半还有默认值、几个是可选的,直接用构造函数去new会非常痛苦。要么写一堆重载构造函数,要么调用方必须记住参数的顺序。

建造者模式的思路是把“构造过程”和“对象本身”分开,用一个Builder对象分步设置属性,最后build()出目标对象。Java里最经典的例子就是StringBuilder,以及Lombok的@Builder注解。

手写核心结构大概是这样的:

public class HttpClient { private final String baseUrl; private final int timeout; private final boolean retryEnabled; private HttpClient(Builder builder) { this.baseUrl = builder.baseUrl; this.timeout = builder.timeout; this.retryEnabled = builder.retryEnabled; } public static class Builder { private String baseUrl; private int timeout = 3000; // 默认值 private boolean retryEnabled = false; public Builder baseUrl(String baseUrl) { this.baseUrl = baseUrl; return this; } public Builder timeout(int timeout) { this.timeout = timeout; return this; } public Builder retryEnabled(boolean retryEnabled) { this.retryEnabled = retryEnabled; return this; } public HttpClient build() { // 可以在build时做参数校验 if (baseUrl == null || baseUrl.isEmpty()) { throw new IllegalStateException("baseUrl不能为空"); } return new HttpClient(this); } } }

调用方写起来就很舒服:

HttpClient client = new HttpClient.Builder() .baseUrl("https://api.example.com") .timeout(5000) .retryEnabled(true) .build();

这里注意,建造者模式适合“参数多且大部分可选”的场景,如果对象就两三个必填字段,直接构造函数反而更清晰,没必要硬套。

2.4 原型模式:用克隆代替重新创建

原型模式在Java里就是Cloneable接口加clone()方法,适合创建成本高的对象,直接用现有实例拷贝一份新的。

实际这个模式用得不算多,因为深拷贝的处理比较麻烦。这里提醒一个坑:Java默认的clone()是浅拷贝,如果对象里有可变引用类型的字段,两个对象会共享同一份内部数据,改一个另一个也变。要实现深拷贝,要么手动层层复制,要么序列化之后反序列化,要么用第三方工具。大多数业务场景下,直接new一个对象可能比折腾深拷贝更省心。

3. 结构型模式速通:怎么组装对象

结构型模式关注的是“类和对象怎么组合成更大的结构”。它们的核心思路是:通过组合、委派、包装,而不是继承,来实现功能的灵活扩展。

3.1 适配器模式:让不兼容的接口一起工作

适配器模式解决的是“接口不匹配”的问题。你有一个旧接口的实现,新系统要求另一个接口,你又改不了旧代码,那就写一个适配器把旧接口包装成新接口。

我举个很常见的例子。项目里引了一个第三方短信SDK,它的接口是这样的:

public class ThirdPartySmsSender { public int sendSms(String mobile, String content) { // 返回0表示成功,非0表示失败 } }

而你的系统里定义了自己的消息发送接口:

public interface MessageSender { boolean send(String phone, String text); }

直接塞进去肯定不行,需要写一个适配器:

public class SmsSenderAdapter implements MessageSender { private final ThirdPartySmsSender thirdPartySmsSender; public SmsSenderAdapter(ThirdPartySmsSender thirdPartySmsSender) { this.thirdPartySmsSender = thirdPartySmsSender; } @Override public boolean send(String phone, String text) { return thirdPartySmsSender.sendSms(phone, text) == 0; } }

这样业务代码永远只依赖自己的MessageSender,哪天换掉第三方SDK,只需要换适配器实现,业务代码一行不用动。

适配器模式特别好认:如果一个类的名字里带Adapter,而且它做的事情只是“翻译”另一个类的接口,那基本就是适配器。

3.2 装饰器模式:动态添加功能,不动原类

装饰器模式和适配器模式长得有点像,但意图完全不同:适配器是为了“让接口匹配”,装饰器是为了“给对象加功能”。

经典例子是Java IO流,BufferedInputStream装饰FileInputStream,给它加缓冲功能;DataInputStream装饰InputStream,给它加读基本类型的功能。

自己写一个装饰器,核心是继承抽象类并持有同类型引用:

public interface DataSource { void writeData(String data); String readData(); } public class FileDataSource implements DataSource { // 基础实现,读写文件 } // 加密装饰器 public class EncryptDataSource implements DataSource { private final DataSource wrapper; public EncryptDataSource(DataSource wrapper) { this.wrapper = wrapper; } @Override public void writeData(String data) { String encrypted = encrypt(data); // 先加密 wrapper.writeData(encrypted); // 再写入 } @Override public String readData() { String data = wrapper.readData(); // 先读取 return decrypt(data); // 再解密 } }

使用的时候可以层层嵌套:

DataSource source = new FileDataSource(); source = new EncryptDataSource(source); // 加密 source = new CompressDataSource(source); // 再压缩

每加一层功能,就是一次嵌套。这个模式最牛的地方是:功能可以自由组合,你不想加密就不套那一层,完全不用改原有类的代码。

我在实际项目中用它给上报数据加过“加密+压缩+限流”三层功能,每层一个装饰器,组合起来非常干净,后来要去掉限流,直接去掉那一行嵌套就行。

3.3 代理模式:控制访问,做额外的拦截

代理模式跟装饰器结构几乎一样,但意图是“控制访问”。代理可以在调用真正对象之前或之后做权限检查、日志记录、性能统计、延迟加载等事情。

Spring AOP的底层,以及MyBatis的Mapper代理,都是代理模式的典型应用。手动实现一个静态代理很直观:

public interface UserService { void deleteUser(Long id); } public class UserServiceImpl implements UserService { public void deleteUser(Long id) { // 真正删除逻辑 } } public class UserServiceProxy implements UserService { private final UserService target; private final User currentUser; public UserServiceProxy(UserService target, User currentUser) { this.target = target; this.currentUser = currentUser; } @Override public void deleteUser(Long id) { if (!currentUser.isAdmin()) { throw new SecurityException("只有管理员才能删除用户"); } long start = System.currentTimeMillis(); target.deleteUser(id); System.out.println("删除用户耗时: " + (System.currentTimeMillis() - start) + "ms"); } }

调用方只依赖UserService接口,实际拿到的是代理对象,权限校验和性能日志这些横切逻辑全部集中在代理里,业务代码非常干净。

Java里代理还有动态代理(JDK的Proxy和CGLIB),可以在运行时动态生成代理类,Spring AOP就是靠这个实现的。速通阶段先理解静态代理的意图,动态代理的语法细节用到时再查,不耽误事。

3.4 外观模式:给复杂系统提供一个简单入口

外观模式可能是所有设计模式里最好理解的一个:一堆复杂的子系统,你不想让调用方一个个去碰,就提供一个统一的门面类,把常用操作组合起来。

比如一个视频处理流程,需要加载文件、解码、转码、加字幕、编码、输出,六个步骤,调用方如果每个都要亲自调用,代码会又臭又长。写一个VideoProcessor外观类,把六步封装成一个process(file)方法,调用方一行代码搞定。

这个模式本身不改变任何子系统的功能,只是把使用复杂度收敛了。但它对代码可维护性的提升非常大——调用方和被调用的子系统之间彻底解耦,子系统内部随便重构,只要外观方法签名不变,调用方毫无感知。

4. 行为型模式速通:怎么设计对象间的协作

行为型模式关注的是“对象之间怎么分配职责、怎么通信”。这一大类模式数量最多,但真正高频使用的其实也就那么几个。

4.1 策略模式:算法可以随时替换

策略模式解决的是“同一个行为有多个算法实现,且要能动态切换”的问题。它的做法是把算法封装成独立的策略类,让它们实现同一个接口,上下文类持有策略接口的引用。

最常见的业务场景是各种计费规则、优惠计算、排序逻辑。比如一个电商系统计算订单折扣:

public interface DiscountStrategy { BigDecimal calculate(BigDecimal amount); } public class NoDiscount implements DiscountStrategy { public BigDecimal calculate(BigDecimal amount) { return amount; } } public class PercentageDiscount implements DiscountStrategy { private final BigDecimal rate; public PercentageDiscount(BigDecimal rate) { this.rate = rate; } public BigDecimal calculate(BigDecimal amount) { return amount.multiply(rate); } } public class FullReductionDiscount implements DiscountStrategy { private final BigDecimal threshold; private final BigDecimal reduction; public FullReductionDiscount(BigDecimal threshold, BigDecimal reduction) { this.threshold = threshold; this.reduction = reduction; } public BigDecimal calculate(BigDecimal amount) { return amount.compareTo(threshold) >= 0 ? amount.subtract(reduction) : amount; } }

然后上下文类或者调用方根据条件选择策略:

DiscountStrategy strategy; if (vipLevel >= 3) { strategy = new PercentageDiscount(new BigDecimal("0.8")); } else if (amount.compareTo(new BigDecimal("1000")) >= 0) { strategy = new FullReductionDiscount(new BigDecimal("1000"), new BigDecimal("100")); } else { strategy = new NoDiscount(); } BigDecimal finalAmount = strategy.calculate(amount);

以后要加“双十一五折”“新人立减”,就各加一个策略类,其他地方不用动。这就是策略模式最核心的价值:算法和上下文分离,扩展靠加类而不是改逻辑。

在实际项目中,策略类经常配合工厂或者Spring的依赖注入来使用,把“选择哪个策略”的逻辑也收敛起来,调用方甚至只需要传一个策略标识。

4.2 观察者模式:状态变了,主动通知

观察者模式解决的是“一对多”的依赖问题:一个对象状态变化,所有依赖它的对象都要被通知并更新。Java里最典型的是监听器机制,比如按钮点击、事件监听。

手写一个简单的事件发布订阅:

public interface OrderEventListener { void onOrderCreated(Order order); } public class OrderService { private final List<OrderEventListener> listeners = new ArrayList<>(); public void addListener(OrderEventListener listener) { listeners.add(listener); } public void removeListener(OrderEventListener listener) { listeners.remove(listener); } public void createOrder(Order order) { // 创建订单业务逻辑 // 通知所有监听者 for (OrderEventListener listener : listeners) { listener.onOrderCreated(order); } } }

不同业务往OrderService上挂不同监听器,有做短信通知的、有做库存扣减的、有做积分发放的,各自互不干扰。新增一种通知方式,只需要多注册一个监听器,OrderService的代码完全不用改。

这个模式在分布式系统里的“事件驱动”架构中也是基础思想,虽然实现上会换成消息队列,但核心的“发布-订阅”心智模型是完全一致的。

4.3 模板方法模式:骨架固定,步骤可变

模板方法模式很适合处理“流程固定,但流程中某几步不一样”的场景。父类定义好算法的骨架,把某些步骤抽象成方法,交给子类去实现。

比如一个数据导入流程,固定步骤是:读取文件、解析数据、校验数据、入库、记录日志。其中读取和入库基本通用,但不同格式文件的解析、校验逻辑不一样。

public abstract class DataImporter { // 模板方法,final防止子类修改流程 public final void importData(String filePath) { String rawData = readFile(filePath); List<Record> records = parse(rawData); List<Record> validRecords = validate(records); save(validRecords); log(filePath, validRecords.size()); } private String readFile(String filePath) { // 通用读取逻辑 } protected abstract List<Record> parse(String rawData); protected List<Record> validate(List<Record> records) { // 默认校验,子类可以覆盖增强 return records; } private void save(List<Record> records) { // 通用保存逻辑 } private void log(String filePath, int count) { // 通用日志逻辑 } }

子类只需要实现parse和可选的validate,流程骨架由父类锁死,想改流程顺序?改不了,因为父类方法是final的。这在某些场景是优点,保证所有子类的流程一致;但在另一些场景也是局限,如果流程本身经常调整,模板方法用起来就比较僵硬。

用模板方法的一个判断标准是:流程是否确实稳定。稳定就用,不稳定就用策略模式把每个步骤都变成可替换的。

4.4 责任链模式:请求一层层传递处理

责任链模式把多个处理器串成一条链,请求从链头进入,每个处理器决定自己处理还是传给下一个。典型的应用是Servlet的Filter、Spring的Interceptor、以及审批流系统。

一个非常直观的例子是订单风控校验,需要依次检查用户黑名单、订单金额、收货地址:

public abstract class RiskHandler { protected RiskHandler next; public void setNext(RiskHandler next) { this.next = next; } public abstract void handle(Order order); protected void passToNext(Order order) { if (next != null) { next.handle(order); } } } public class BlacklistHandler extends RiskHandler { public void handle(Order order) { if (order.getUser().isBlacklisted()) { throw new RiskException("用户在黑名单中"); } passToNext(order); } } public class AmountHandler extends RiskHandler { public void handle(Order order) { if (order.getAmount() > 100000) { throw new RiskException("订单金额异常"); } passToNext(order); } }

组装链的时候按顺序setNext即可。新增一种风控规则,就新增一个RiskHandler子类插进链里,原有处理器完全不用动。这个模式处理“多个互不相关的检查/处理步骤,且顺序可变”非常顺手。

5. 综合实战:用设计模式重构一个订单模块

说了一堆理论,我们用一个小场景串一遍。假设你现在要写一个下单流程,包含如下需求:

  • 订单分为普通订单、秒杀订单、企业采购订单三种类型;
  • 每种订单的创建逻辑不同;
  • 下单成功后需要发短信通知、更新库存、赠送积分;
  • 订单金额需要计算折扣,不同用户等级不同折扣规则;
  • 下单前要做风控校验;
  • 未来大概率会增加新订单类型、新通知方式、新折扣规则。

用设计模式来设计这套系统:

第一,订单创建用工厂方法。定义一个OrderCreator抽象类和三个子类,分别处理三种订单的创建细节。

第二,折扣计算用策略模式。DiscountStrategy接口加若干实现类,用户等级和优惠活动决定选哪个策略。

第三,下单成功后的通知用观察者模式。OrderCreationEvent发布出去,SmsListener负责短信、StockListener负责库存、PointListener负责积分。以后要加“推送App通知”,新增一个监听器注册进来就行。

第四,风控校验用责任链模式。黑名单检查、金额检查、频次检查串成链,规则可以灵活增删。

第五,如果想记录每次下单的耗时和日志,可以用代理模式包装OrderCreator,在真实创建前后做横切操作。

你发现没有,整个设计里几乎没有任何一个类是“把所有逻辑写在一坨”的。每个模式都在做同一件事:把变化点隔离出来,让未来的扩展只发生在新增文件上,而不是修改已有文件上。

这套设计在需求少的时候看起来“过度设计”,但一旦需求开始膨胀,尤其是订单类型、优惠规则、通知方式这三类变化频繁叠加的时候,它的优势就完全体现出来了。我在实际项目里的体会是:判断要不要用设计模式,就看这个模块的变化频率和变化维度,维度多、频率高,就值得投入成本做模式化设计。

6. 常见误区与避坑指南

6.1 为了用模式而用模式

这是新手最容易犯的问题。一个简单的if-else能解决的逻辑,硬套上策略模式,写出五个类、三个接口,最后代码比原来还难读。设计模式是工具,不是目的,能用三行代码清晰解决的问题,就不要为了展示技术搞出三十行。

判断标准很简单:加了这个模式,代码是变得更简单还是更复杂?如果只是类变多了、理解变难了,那这个模式就不该上。

6.2 单例在Spring环境下的误用

Spring默认的Bean就是单例的,如果你的类已经交给了Spring管理,再手写一套单例模式,就是重复造轮子,还可能引发混乱。在Spring项目里,单例模式一般只用于那些不在Spring容器管理范围内的组件,或者静态工具类。

6.3 观察者模式忘了考虑异常隔离

观察者模式里,如果某个监听器抛了异常,默认会中断整个通知循环,导致后面的监听器全部收不到事件,还会把异常抛给发布方。生产环境里这个坑特别隐蔽。

解决方法有两个:要么在监听器内部自己捕获异常,要么在通知循环里加try-catch,保证一个监听器挂了不影响其他监听器。我个人倾向于后者,在循环里catch住每个监听器的异常并记录下来,至少保证核心流程不被打断。

6.4 深拷贝的坑

原型模式里浅拷贝导致的数据共享问题前面已经说过,这里再补充一个场景:如果对象里有List、Map这类容器字段,浅拷贝下两个对象共享同一个容器引用,某个线程往里面塞了一个元素,另一个线程也能看到,这在并发场景下会出大问题。如果要真正复制对象,务必确认所有可变引用字段都被深度复制了。

6.5 适配器和装饰器分不清

两个模式代码结构很像,区别在意图上:适配器是“接口不匹配,做翻译”;装饰器是“功能不够,做增强”。理解意图比记住结构重要得多,面试的时候如果能把这两个模式的差异讲清楚,比背出十个模式的类图更能说明你真的理解了。

6.6 学习顺序的调整

很多人的学习路径是从创建型到结构型再到行为型,每个模式都试图记住UML图。我更推荐按“使用频率”排序:先学单例、工厂、策略、观察者、模板方法、装饰器、代理这几个高频模式,然后在读框架源码和写业务的过程中反复识别它们。低频模式比如备忘录、中介者、解释器,可以放到有具体需要的时候再回头看,强行背下来不用,很快就忘了。

我的实操体会

速通设计模式这件事,最后拼的不是记忆力,而是“识别力”。我把二十多个模式过完一遍之后,真正留下来的是几个高频模式的心智模型,其他低频模式都只留了个印象,等真遇到场景再翻书也来得及。

如果你正在准备面试,我建议每个模式都准备一个“生活化例子+代码片段+使用场景”的组合,自己能流利讲明白这三件事,基本就过关了。如果你是为了读源码,那重点放在策略、代理、模板方法、观察者、责任链这几个上,Spring、MyBatis、Netty这些框架里密密麻麻都是这些模式的影子。

最后再分享一个小技巧:学任何一个模式,都问自己三个问题——没有这个模式代码会烂在哪里?这个模式把变化点藏到了哪里?未来如果需求变化,我只需要动哪几个文件?想清楚这三件事,比盯着类图发呆有用得多。

相关新闻

zzcms8.3建站系统实战:环境搭建、代码审计与二次开发改造指南

zzcms8.3建站系统实战:环境搭建、代码审计与二次开发改造指南

简介&#xff1a;ZZCMS 8.3 是一套开源内容管理系统源码&#xff0c;面向希望入门代码审计与 PHP 架构的开发者、安全学习者及建站人员。它既可用于搭建动态网站&#xff0c;也是一份可动手剖析的实战样本&#xff0c;帮助读者在真实项目中理解安全编码与设计模式。压缩包为 zi…

2026/10/22 11:01:28 阅读更多 →
EVE新手挖坟逃生指南:反跳、扰频、微曲与泡泡全解析

EVE新手挖坟逃生指南:反跳、扰频、微曲与泡泡全解析

简介&#xff1a;这是一份面向EVE新手玩家的挖坟逃生实操指南&#xff0c;作者结合多年实战经验&#xff0c;系统梳理了遗迹破译与逃生环节最容易翻车的细节。内容从破译箱子时的隐身快捷键设置、环绕距离把握讲起&#xff0c;逐步展开过星门遇泡泡的脱身路线规划、微曲与隐身技…

2026/10/22 10:41:58 阅读更多 →
8款降AI率工具实测:按改写策略选型,告别机器味

8款降AI率工具实测:按改写策略选型,告别机器味

先交代一个背景&#xff0c;免得后面大家觉得我立场有问题。这些年我做内容排版、自媒体写作、也帮一些商科方向的学生改过案例分析报告&#xff0c;见过太多人卡在同一个环节&#xff1a;AI辅助写完初稿&#xff0c;速度确实快&#xff0c;但读完总感觉"缺了人味"&a…

2026/10/22 10:41:46 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年&#xff0c;我大部分时间都在跟浏览器标签页打交道&#xff0c;直到第一次把桌面应用跑起来&#xff0c;才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词&#xff0c;最开始是在某段时间频繁出现在同事的讨论里&#xff0c;一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档&#xff0c;主要面向智能锁安装人员、终端用户及售后维护者&#xff0c;帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件&#xff0c;大小4.37MB&#xff0c;内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统&#xff0c;整车要求空载跑到8m/s&#xff0c;电机转速已经拉到额定点&#xff0c;驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令&#xff0c;转速纹丝不动&#xff0c;三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年&#xff0c;用它写过嵌入式驱动、做过游戏服务端&#xff0c;也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词&#xff0c;我其实挺感慨的——这门语言的难点从来不是语法多&#xff0c;而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书以PDF格式发布&#xff0c;适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开&#xff0c;先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能&#xff0c;再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历&#xff1a;翻开源码注释、论文摘要或者一份专业报告&#xff0c;每个字都认识&#xff0c;连在一起却像天书。想找人聊聊&#xff0c;身边要么没人懂&#xff0c;要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型&#xff0c;几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

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

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

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

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

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

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

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

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

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

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 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/21 21:50:56 阅读更多 →
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/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练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/21 16:24:48 阅读更多 →