13、(行为型设计模式)Java 模板方法模式深度学习指南

开源至上:java前端框架排行 java基础 1.1java的8种基本数据类型装箱拆箱 1.2重写重载封装继承多态 1.3 Stack Queue 1.7 Concurrent包 1.8面向对象 1.9 String StringBuffer StringBuilder hashcode equ 1.10 java文件读取 1.11 Java反射 1.12 JDK NDK JRE JNI 1.13 static和final的区别 1.14 map, list, set区别 1.16 Session和COOKIE 1.19 10 NIO B 阅读详情

以下是为你精心撰写的 《Java 模板方法模式深度学习指南》,专为 Java 后端开发者打造,内容涵盖:定义、作用、与策略模式的深度对比、真实业务场景、实现方式、Spring 集成、避坑指南、最佳实践、面试高频题,所有示例均含中文注释,可直接用于项目重构、订单流程、审批流、数据导入导出、报表生成等核心场景。


📘 Java 模板方法模式深度学习指南

—— 从“重复流程”到“固定骨架,灵活实现”的架构升华

作者:Java 后端架构实战导师
适用对象:Java 后端开发者(Spring Boot / 微服务 / 订单系统 / 审批流 / 数据处理)
目标:彻底掌握“定义算法骨架,让子类重写具体步骤”的经典设计模式,告别“复制粘贴”和“流程混乱”
核心原则:“我规定你必须按这个流程走,但每一步你怎么干,你说了算。”


✅ 一、什么是模板方法模式?

📌 定义:

模板方法模式(Template Method Pattern) 是一种行为型设计模式,它定义了一个算法的骨架(即固定的执行流程),并将一些具体步骤延迟到子类中实现。子类可以重写这些步骤,但不改变算法的整体结构。

🔍 核心思想:

  • 把一个固定流程(如:下单 → 扣库存 → 支付 → 发货 → 通知)封装在父类中
  • 将流程中可变的部分(如:支付方式、通知方式)定义为抽象方法或钩子方法
  • 子类继承父类,重写具体步骤,实现自己的业务逻辑
  • 客户端调用父类的模板方法,自动执行完整流程

💡 一句话记忆:
“我给你一个标准流程,你按这个顺序做,但每一步怎么做,你自己决定。”

🆚 模板方法模式 vs 策略模式(极易混淆)

维度模板方法模式策略模式
目的固定流程,灵活步骤固定接口,灵活算法
控制权父类控制流程,子类控制步骤客户端控制选择哪个算法
实现方式继承(Is-A)组合(Has-A)
调用方式客户端调用父类方法客户端调用策略对象
是否可变流程❌ 流程固定✅ 算法可变,流程可换
典型场景订单流程、审批流、数据导入支付方式、排序算法、折扣计算
类比做饭流程:洗菜 → 切菜 → 炒菜 → 装盘(你决定炒什么菜)你选择用锅炒、用电饭锅煮、用微波炉热

✅ 关键区别:

  • 模板方法:“你必须按我的流程走,但每一步你自由发挥”
  • 策略模式:“你可以选不同的流程,但每个流程的接口是一样的”

✅ 经典比喻:
你去餐厅吃饭:

  • 模板方法:餐厅规定“先点菜 → 等待上菜 → 吃饭 → 结账”,但“吃什么菜”你决定
  • 策略模式:你可以选“中餐”、“西餐”、“日料”三种不同流程

✅ 二、模板方法模式有什么作用?(Why Use Template Method?)

作用说明
✅ 避免代码重复公共流程只写一次,子类复用
✅ 强制流程规范确保所有子类都按统一顺序执行关键步骤
✅ 提高可维护性修改流程只需改父类,影响所有子类
✅ 支持开闭原则新增流程变体只需新增子类,不改父类
✅ 增强可读性流程结构清晰,一目了然
✅ 支持钩子方法子类可选择性覆盖某些步骤,实现灵活扩展
✅ 便于测试可对父类流程做集成测试,对子类步骤做单元测试
✅ Spring 集成基础Spring 的 AbstractApplicationContext、JdbcTemplate 都是模板方法模式

💡 经典名言:
“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.”
——《Design Patterns: Elements of Reusable Object-Oriented Software》


✅ 三、模板方法模式的典型使用场景(Java 后端真实案例)

场景说明是否推荐使用模板方法模式
✅ 订单创建流程校验 → 扣库存 → 支付 → 生成物流 → 发送通知✅ 强烈推荐
✅ 用户注册流程验证邮箱 → 发送验证码 → 创建账户 → 绑定手机号 → 发送欢迎邮件✅ 强烈推荐
✅ 审批流程提交 → 部门审核 → 财务审核 → 总监审批 → 归档✅ 强烈推荐
✅ 数据导入读取文件 → 校验格式 → 解析数据 → 验证业务规则 → 批量入库 → 生成报告✅ 推荐
✅ 数据导出查询数据 → 格式化 → 生成文件 → 发送邮件/下载✅ 推荐
✅ 报表生成连接数据库 → 查询数据 → 计算指标 → 生成图表 → 输出PDF/Excel✅ 推荐
✅ 任务调度准备资源 → 执行任务 → 检查结果 → 记录日志 → 发送通知✅ 推荐
✅ 缓存预热加载配置 → 初始化连接 → 预加载数据 → 启动定时任务✅ 推荐
✅ 微服务启动加载配置 → 初始化组件 → 注册服务 → 开启端口 → 启动健康检查✅ 推荐
❌ 支付方式选择支付宝、微信、银联,只是算法不同❌ 用策略模式
❌ 排序算法快排、冒泡、归并❌ 用策略模式
❌ 单一操作只有“保存用户”一个动作❌ 直接写方法

✅ 判断标准:
“有一个固定流程,包含多个步骤,其中部分步骤的实现因业务而异?”
→ 是 → 用模板方法模式!


✅ 四、模板方法模式的三种实现方式详解(含中文注释)

我们从基础结构到Spring 模板类,逐步深入。


🔹 1. 基础结构:抽象类 + 抽象方法 + 钩子方法

/**
 * 【1】抽象模板类:定义算法骨架
 */
public abstract class OrderProcessTemplate {

    /**
     * 【核心模板方法】:定义固定流程,final 防止被重写
     */
    public final void processOrder(String orderId) {
        System.out.println("📦 开始处理订单:" + orderId);
        validateOrder(orderId);       // 步骤1:校验订单
        calculateTotal(orderId);      // 步骤2:计算金额
        applyDiscount(orderId);       // 步骤3:应用折扣(子类实现)
        saveOrder(orderId);           // 步骤4:保存订单
        notifyUser(orderId);          // 步骤5:通知用户
        System.out.println("✅ 订单处理完成\n");
    }

    /**
     * 【公共方法】:所有子类共享的逻辑
     */
    protected void validateOrder(String orderId) {
        System.out.println("🔧 步骤1:校验订单是否存在");
    }

    protected void calculateTotal(String orderId) {
        System.out.println("💰 步骤2:计算订单总金额");
    }

    /**
     * 【抽象方法】:子类必须实现(强制步骤)
     */
    protected abstract void applyDiscount(String orderId);

    /**
     * 【公共方法】:通用逻辑
     */
    protected void saveOrder(String orderId) {
        System.out.println("💾 步骤4:保存订单到数据库");
    }

    /**
     * 【钩子方法】:子类可选择性重写(非强制)
     */
    protected void notifyUser(String orderId) {
        System.out.println("📢 步骤5:发送短信通知用户");
    }

    // 可添加更多钩子方法
    protected boolean isExpressDelivery(String orderId) {
        return false; // 默认不加急
    }
}

/**
 * 【2】具体子类1:普通订单
 */
class RegularOrderProcess extends OrderProcessTemplate {
    @Override
    protected void applyDiscount(String orderId) {
        System.out.println("📉 步骤3:普通订单无折扣");
        // 不打折
    }

    // 可选择性重写钩子方法
    @Override
    protected boolean isExpressDelivery(String orderId) {
        return true; // 普通订单也加急
    }

    @Override
    protected void notifyUser(String orderId) {
        System.out.println("📱 步骤5:发送短信 + 邮件通知用户");
    }
}

/**
 * 【3】具体子类2:VIP订单
 */
class VIPOrderProcess extends OrderProcessTemplate {
    @Override
    protected void applyDiscount(String orderId) {
        System.out.println("🎁 步骤3:VIP订单享受9折优惠");
        // 9折
    }

    // 不重写钩子方法,使用默认实现
}

/**
 * 【4】客户端:调用模板方法
 */
public class TemplateMethodDemo {
    public static void main(String[] args) {
        // 创建普通订单流程
        OrderProcessTemplate regular = new RegularOrderProcess();
        regular.processOrder("ORD001");

        // 创建VIP订单流程
        OrderProcessTemplate vip = new VIPOrderProcess();
        vip.processOrder("ORD002");
    }
}
✅ 输出结果:
📦 开始处理订单:ORD001
🔧 步骤1:校验订单是否存在
💰 步骤2:计算订单总金额
📉 步骤3:普通订单无折扣
💾 步骤4:保存订单到数据库
📱 步骤5:发送短信 + 邮件通知用户
✅ 订单处理完成

📦 开始处理订单:ORD002
🔧 步骤1:校验订单是否存在
💰 步骤2:计算订单总金额
🎁 步骤3:VIP订单享受9折优惠
💾 步骤4:保存订单到数据库
📢 步骤5:发送短信通知用户
✅ 订单处理完成
✅ 优点:
  • 流程固定:保证所有订单都走“校验 → 计算 → 折扣 → 保存 → 通知”流程
  • 可扩展:新增“企业订单”只需新建子类
  • 复用性强:公共逻辑(validate、save)只写一次
  • 钩子灵活:isExpressDelivery() 可选重写,不强制
⚠️ 注意:
  • 模板方法必须是 final,防止子类修改流程顺序
  • 抽象方法必须由子类实现
  • 钩子方法有默认实现,子类可选覆盖

🔹 2. 模板方法模式 + Spring 模板类(企业级实战)

Spring 的 JdbcTemplate、RestTemplate、TransactionTemplate 都是模板方法模式的典范!

/**
 * 【1】抽象模板类:模拟 JdbcTemplate
 */
public abstract class DatabaseTemplate {

    /**
     * 模板方法:执行数据库操作
     */
    public final <T> T execute(String sql, RowMapper<T> rowMapper) {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            // 1. 获取连接
            conn = getConnection();
            System.out.println("🔌 获取数据库连接");

            // 2. 准备语句
            stmt = conn.prepareStatement(sql);
            System.out.println("📝 准备SQL语句:" + sql);

            // 3. 执行查询
            rs = stmt.executeQuery();
            System.out.println("🔍 执行查询");

            // 4. 映射结果(交给子类实现)
            T result = mapRow(rs, rowMapper);
            System.out.println("📊 映射结果");

            return result;

        } catch (Exception e) {
            System.err.println("❌ 数据库操作失败:" + e.getMessage());
            throw new RuntimeException("数据库异常", e);
        } finally {
            // 5. 关闭资源(固定清理)
            closeResources(conn, stmt, rs);
            System.out.println("🗑️ 关闭数据库连接");
        }
    }

    /**
     * 【抽象方法】:子类负责映射结果
     */
    protected abstract <T> T mapRow(ResultSet rs, RowMapper<T> rowMapper);

    /**
     * 【公共方法】:获取连接
     */
    protected Connection getConnection() {
        // 实际项目中:从连接池获取
        return new Connection() { // 模拟
            @Override
            public PreparedStatement prepareStatement(String sql) {
                return new PreparedStatement() {
                    @Override
                    public ResultSet executeQuery() {
                        // 模拟返回结果集
                        return new ResultSet() {
                            @Override
                            public boolean next() {
                                return true; // 有数据
                            }

                            @Override
                            public String getString(String columnLabel) {
                                return "张三";
                            }
                        };
                    }
                };
            }
        };
    }

    /**
     * 【公共方法】:关闭资源
     */
    protected void closeResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
        // 真实项目中:try-with-resources 或工具类关闭
    }
}

/**
 * 【2】结果映射器接口
 */
interface RowMapper<T> {
    T mapRow(ResultSet rs) throws SQLException;
}

/**
 * 【3】具体实现:用户查询模板
 */
class UserQueryTemplate extends DatabaseTemplate {

    @Override
    protected <T> T mapRow(ResultSet rs, RowMapper<T> rowMapper) {
        // 调用传入的 RowMapper
        return (T) rowMapper.mapRow(rs);
    }

    /**
     * 提供便捷方法:查询单个用户
     */
    public User findUserById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return execute(sql, rs -> {
            if (rs.next()) {
                return new User(rs.getLong("id"), rs.getString("name"), rs.getString("email"));
            }
            return null;
        });
    }
}

/**
 * 【4】数据对象
 */
record User(Long id, String name, String email) {}

/**
 * 【5】客户端使用
 */
public class SpringTemplateDemo {
    public static void main(String[] args) {
        UserQueryTemplate template = new UserQueryTemplate();

        // ✅ 客户端只关心“我要查什么”,不关心连接、关闭、异常
        User user = template.findUserById(1L);
        System.out.println("👤 查询结果:" + user);
        // 输出:
        // 🔌 获取数据库连接
        // 📝 准备SQL语句:SELECT * FROM users WHERE id = ?
        // 🔍 执行查询
        // 📊 映射结果
        // 🗑️ 关闭数据库连接
        // 👤 查询结果:User[id=1, name=张三, email=zhangsan@xx.com]
    }
}
✅ 优点:
  • 完全解耦:客户端只写 SQL 和映射逻辑
  • 资源安全:连接自动关闭,防止泄漏
  • 异常统一:所有异常包装为 RuntimeException
  • Spring 模板类:JdbcTemplate、RestTemplate、TransactionTemplate 都是这样设计的!

🔹 3. 模板方法模式 + Spring Boot 自动配置(高级实战)

在 Spring Boot 中,自动配置类 就是模板方法模式的体现!

/**
 * 【1】抽象模板:定义数据导入流程
 */
public abstract class DataImportTemplate {

    /**
     * 模板方法:固定导入流程
     */
    public final void importData(String filePath) {
        System.out.println("📥 开始导入数据文件:" + filePath);

        // 步骤1:读取文件
        List<String> lines = readFile(filePath);
        System.out.println("📄 读取文件行数:" + lines.size());

        // 步骤2:解析每一行(子类实现)
        List<DataRecord> records = parseLines(lines);
        System.out.println("🧩 解析数据记录数:" + records.size());

        // 步骤3:校验数据(子类实现)
        validateRecords(records);
        System.out.println("✅ 数据校验通过");

        // 步骤4:批量保存(子类实现)
        saveRecords(records);
        System.out.println("💾 批量保存成功");

        // 步骤5:发送通知(钩子方法)
        sendNotification(records.size());
        System.out.println("📢 通知发送完成");

        System.out.println("🎉 数据导入完成\n");
    }

    // 公共方法:读取文件(固定)
    protected List<String> readFile(String filePath) {
        // 模拟读取
        return List.of("张三,13800138000,zhangsan@xx.com", "李四,13900139000,lisi@xx.com");
    }

    // 抽象方法:子类实现解析逻辑
    protected abstract List<DataRecord> parseLines(List<String> lines);

    // 抽象方法:子类实现校验逻辑
    protected abstract void validateRecords(List<DataRecord> records);

    // 抽象方法:子类实现保存逻辑
    protected abstract void saveRecords(List<DataRecord> records);

    // 钩子方法:可选重写
    protected void sendNotification(int count) {
        System.out.println("📧 发送邮件通知:成功导入 " + count + " 条记录");
    }
}

/**
 * 【2】数据记录对象
 */
record DataRecord(String name, String phone, String email) {}

/**
 * 【3】具体实现1:导入用户数据
 */
@Component
public class UserImportTemplate extends DataImportTemplate {

    @Autowired
    private UserService userService;

    @Override
    protected List<DataRecord> parseLines(List<String> lines) {
        return lines.stream()
                .map(line -> {
                    String[] parts = line.split(",");
                    return new DataRecord(parts[0], parts[1], parts[2]);
                })
                .toList();
    }

    @Override
    protected void validateRecords(List<DataRecord> records) {
        for (DataRecord record : records) {
            if (record.name().isEmpty() || record.phone().isEmpty()) {
                throw new IllegalArgumentException("用户信息不完整:" + record);
            }
        }
    }

    @Override
    protected void saveRecords(List<DataRecord> records) {
        records.forEach(record -> {
            userService.createUser(record.name(), record.phone(), record.email());
        });
    }

    // 重写钩子方法:发送短信通知
    @Override
    protected void sendNotification(int count) {
        System.out.println("📱 发送短信通知:成功导入 " + count + " 个用户");
    }
}

/**
 * 【4】用户服务
 */
@Service
class UserService {
    public void createUser(String name, String phone, String email) {
        System.out.println("👤 创建用户:" + name + ", 手机:" + phone + ", 邮箱:" + email);
    }
}

/**
 * 【5】启动类
 */
@SpringBootApplication
public class TemplateBootDemo implements CommandLineRunner {

    @Autowired
    private UserImportTemplate userImportTemplate;

    public static void main(String[] args) {
        SpringApplication.run(TemplateBootDemo.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        userImportTemplate.importData("users.csv");
    }
}
✅ 输出:
📥 开始导入数据文件:users.csv
📄 读取文件行数:2
🧩 解析数据记录数:2
✅ 数据校验通过
👤 创建用户:张三, 手机:13800138000, 邮箱:zhangsan@xx.com
👤 创建用户:李四, 手机:13900139000, 邮箱:lisi@xx.com
💾 批量保存成功
📱 发送短信通知:成功导入 2 个用户
📢 通知发送完成
🎉 数据导入完成
✅ 优点:
  • 可插拔:新增“商品导入”只需新建 ProductImportTemplate
  • Spring 管理:自动注入 UserService
  • 配置驱动:可通过 @Profile 控制不同环境使用不同模板

✅ 五、模板方法模式 vs 策略模式 对比总结表

维度模板方法模式策略模式
目的固定流程,灵活步骤固定接口,灵活算法
实现方式继承(Is-A)组合(Has-A)
控制权父类控制流程,子类控制步骤客户端控制选择哪个策略
调用方式客户端调用父类模板方法客户端调用策略对象的方法
灵活性流程固定,步骤可变流程可换,算法固定
典型场景订单流程、审批流、数据导入支付方式、排序算法、折扣策略
Spring 实现JdbcTemplate、TransactionTemplateComparator、MessageConverter

✅ 一句话区分:

  • 模板方法:“你必须按这个流程走,但每一步你自由发挥”
  • 策略模式:“你可以选不同的流程,但每个流程的接口是一样的”

✅ 六、模板方法模式的避坑指南(Java 后端高频踩坑)

问题原因解决方案
❌ 模板方法不是 final子类重写流程顺序✅ 所有模板方法必须声明为 final
❌ 抽象方法写成具体方法子类无法重写✅ 需要子类实现的必须是 abstract
❌ 钩子方法没有默认实现子类必须实现✅ 钩子方法应有默认空实现
❌ 在模板方法中调用子类的非抽象方法可能调用未初始化对象✅ 只调用 final、abstract、protected 方法
❌ 模板方法中包含业务逻辑违反单一职责✅ 模板方法只控制流程,业务逻辑放子类
❌ 使用模板方法做“单一操作”过度设计✅ 至少 3 个步骤,且有可变部分才用

✅ 七、学习建议与进阶路径

阶段建议
📚 第一周将你项目中的“用户注册流程”重构为模板方法(校验 → 发验证码 → 创建账户 → 发欢迎邮件)
📚 第二周用模板方法实现“数据导入”流程(读取 → 解析 → 校验 → 保存 → 通知)
📚 第三周阅读 Spring 源码:JdbcTemplate.execute()、TransactionTemplate.execute() 如何实现?
📚 第四周在 Spring Boot 中,创建一个 DataImportTemplate,支持不同数据格式(CSV、Excel)
📚 面试准备准备回答:

“你项目中哪里用了模板方法?”
“模板方法和策略模式区别?”
“Spring 中的 JdbcTemplate 是模板方法吗?”
“钩子方法有什么用?” |


✅ 八、模板方法模式面试高频题(附答案)

Q1:模板方法模式解决了什么问题?

A:解决了“多个子类有相同流程,但部分步骤不同”的问题,避免代码重复,强制流程规范。

Q2:模板方法模式和策略模式的区别?

A:

  • 模板方法:继承 + 固定流程,子类实现步骤
  • 策略模式:组合 + 固定接口,客户端选择算法
    → 一个是“你必须按我的流程做”,一个是“你可以选不同的流程”

Q3:Spring 中的 JdbcTemplate 是模板方法模式吗?

A:是的!JdbcTemplate.execute() 是模板方法,RowMapper.mapRow() 是抽象方法,客户端只需实现映射逻辑。

Q4:什么是钩子方法?

A:钩子方法(Hook Method)是模板方法中有默认实现的 protected 方法,子类可选择性重写,用于扩展功能而不改变流程。

Q5:为什么模板方法要声明为 final?

A:防止子类重写整个流程,破坏算法结构,确保流程的完整性。


✅ 九、总结:模板方法模式选型决策树

graph TD
    A[是否有多个子类共享相同流程?] --> B{流程固定,但部分步骤可变?}
    B -->|是| C[使用模板方法模式]
    B -->|否| D[使用策略模式或直接写方法]

✅ 最终推荐:

  • 流程固定、步骤可变 → ✅ 模板方法模式(最标准)
  • 算法可变、流程可换 → ✅ 策略模式
  • 流程简单、无变化 → ❌ 不用模式,直接写方法

✅ 十、结语:真正的高手,不教别人怎么做,只告诉他们必须按这个顺序做

你不是在学“模板方法模式”,你是在学“如何为复杂流程建立标准化、可复用、可扩展的框架”。

✅ 当你看到 JdbcTemplate 只让你写 SQL 和映射,连接、关闭、异常、事务全由它管理时,你已经掌握了 Spring 的灵魂。
✅ 当你用一个 OrderProcessTemplate 统一管理所有订单流程,新增“企业订单”只需一个类时,你已经是架构师了。

不要为了“用模式”而用模式,
要为了“系统可维护、可扩展、可规范”而选择它。


Geant4 案例分析(一): B1 本文是对Geant4 B1的案例分析,其中特定的功能不做介绍,而注重于各个文件的主要功能,以及它们组织的方式。 阅读详情

相关推荐

OpenWrt路由开启DDNS+端口转发进行外网访问

OpenWrt路由开启DDNS+端口转发进行外网访问(LuCI界面实现)--开篇一、准备工作二、开机!三、连接--结尾 –开篇 本篇适用于一切装有OpenWrt系统的路由器/软路由,只要你保证有WAN接口和一个光猫,甚至你不需要有LAN接口(当然前提是你能连接路由器的WIFI进后台,不然你只能通过LAN进后台咯)。所有的配置过程都是基于LuCI界面来的,当然大神们一般都通过SSH登陆路由使用命令配置,但我也不会啊,只能给个有GUI界面的教程了。 一、准备工作 一个装有OpenWrt系统的路由器/软路由并

秋之颂的博客 9万+

JAVA设计模式类第一博主,用这份文档覆盖GOF研磨这23种设计模式(2)

由于关于设计的知识过于博大精深,因此本书“集中火力”,重点讲述GoF著作中涉及的23个设计模式本身,以及和这些设计模式相关的应用内容。本书的示例虽然大都来自实际应用,但是经过相当的删除简化和重新组合:另外一点,为了突出设计模式这个主题,因此代码并不是按照实际应用那样来严格要求,很多例外处理、数据检测等都没有做,逻辑也未见得那么严密:还有一点, 在实际的开发中,很可能是多个模式组合来实现某个功能,但是本书为了示例某个模式,让重点突出而避免读者迷惑,会选择重点示例某个模式的用法,而简化或去掉其他模式。

2401_84910888的博客 900

基于PLC的图书馆机器人设计与仿真

本文设计了一种基于PLC的图书馆机器人系统,该系统能提升图书馆自动化管理水平,选用西门子S7-1200系列PLC作为核心控制单元,结合电机驱动、传感器采集以及超声波避障等技术,设计出机器人行走、图书识别与分拣的功能模块,系统借助条形码扫描模块获取图书信息,将其分析后与设定的存放位置做对比,精准达成图书的存取和归还。仿真结果显示,机器人执行任务时运动控制响应时间是0.35秒,避障成功率为98.3%,图书识别准确率高达99.4%,在控制系统方面,运用STEP7-MICRO/WIN软件编程,结合WINCC设计组态

weixin_44553616的博客 1924

深度学习!刚毕业2年就拿到阿里的offer,分享我的阿里4面面经!

一点心里话 如果你今天还在问我“程序员为什么需要深度学习?”,那么这只是意味着你对开发的兴趣并不高,你对编程的热情并不够,你对自己的职业发展也没有一个清晰的规划。 作为开发人员来说,不说要求自己成为业内顶尖,但也要保证自己不被市场所淘汰,学习对于程序员来说是最基本的事情。 一面 1.自我介绍,包括做过项目。 2.有看过哪些JDK源码,了解哪些常用库。 3.集合框架HashMap的扩容机制,ConcurrnetHashMap的原理 4.jvm内存模型与gc内存回收机制 5.classloader结构,是否可以

weixin_53170684的博客 315

【小宁学习日记6 PCB】电路原理图

本文系统讲解了电子硬件设计中原理图的阅读与绘制技巧。首先剖析原理图的四大核心要素(元件符号、连接线、结点、注释),强调注释对可读性的重要性。然后提出三步读懂法:查看图纸信息、分模块分析、结合芯片手册验证,并列举5个典型芯片案例(CH224K、CH343P等)进行实战解析。最后给出6条绘制规范:模块化布局、详细标注、规范命名、信号流布局、符号封装匹配、版本管理。文章指出原理图是电子设计的"地基",掌握规范阅读与绘制方法能大幅提升设计效率,避免常见错误。新手应从开源项目分析和简单电路绘制入手

qq_74376834的博客 2350

RK-XCKU5P RoCEv2 传感器桥工程分析报告

烧入后这块 FPGA 就是一个固定身份(CA:FE:C0:FF:EE:00 / 192.168.0.2 / 无 FEC 100G)的RoCEv2 UC 端点,每秒在 UDP 12267 广播自报家门;对端 CX5 只要关 FEC、配 192.168.0.101 +MTU 4200,就能 ping 通它、用 UDP 8192 读写它的全部寄存器、再按"ECB 旁路交换 QPN/rkey"的方式建立 UC RDMA 通道收发数据。

eloudy的专栏 243

Android13 热点默认5G频道配置修改_android 系统 wifi ap热点功能配置方式

跳槽季整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。

2401_84563734的博客 1832

【笔记】1.1 拉伸力-伸长(延伸)曲线和应力-应变曲线

过了B点后,由于颈缩导致的截面半径迅速减小,导致真应力迅速上升,切线斜率明显提高。假设试样原长为ε,在力的作用下伸长了dε,那么根据应变的定义,瞬时的应变为dε/ε,总的应变为瞬时应变的累计,假设在瞬时的条件下,试样受载荷变化量为 ΔF ,变化的截面积为 ΔA ,而且ΔA→0,那么瞬时的。由于原始的截面积和原始的标距长度为常数,故得到的曲线长相和拉伸力-伸长(延伸)曲线没啥区别。因为用的都是原始的截面积和原始的标距长度,故称为公称应力和公称应变。如果拉伸力→应力,伸长长度→应变,就会得到应力-应变曲线。

m0_73676887的博客 5269

淘系技术联合承办GAITC 2024专题论坛即将召开,就深度学习议题展开讨论(2)

搞定算法,面试字节再不怕,有需要文章中分享的这些最后再分享一份在乐观派看来,深度学习在自然语言处理、语音识别、计算机视觉、图像处理等诸多实用领域广泛应用,已经从实验室走向工厂和城市,在实践过程中会不断被优化、提升。深度学习活力不减不论是悲观派还是乐观派,两种不同观点的目标却是一致的,那就是在挑战不断升级的情况下,深度学习需要大的突破,还有诸多问题有待解决。事实上,在大数据技术的作用下,深度学习的价值在不断被放大,不断有更多的学者和从业者加入深度学习队伍,这也证实了深度学习的无限潜力。

2401_84692429的博客 988

【SystemVerilog基础】SystemVerilog Assertion 概述

断言主要是描述复杂的设计行为;是传统验证方法学一个很好的补充,可以检查到电路内部细节,相当于一种白盒验证,传统的验证方法学是纯粹的黑盒验证!property跟上面的sequence差别不大,唯一有差别可能多了两个implication(|->,|=>)注意,当有前置条件时,不满足前置条件不会fail,而是伪真!上面这个因为没有前置条件,每个周期都会去检查!注意:当没有前置条件时,不满足条件会直接fail!

MoorePlus的博客 331

点云去噪:基于点云拟合的方法

点云处理是计算机视觉中的重要任务之一,而点云去噪是点云处理的关键步骤之一。在实际应用中,由于采集设备的噪声、运动估计误差或者环境干扰等因素,点云数据中常常包含有噪声点,这些噪声点会对后续的点云分析和处理造成不良影响。一种简单的方法是计算点到拟合曲面的距离,并将距离超过某个阈值的点定义为噪声点,进行过滤。一种简单的方法是计算点到拟合曲面的距离,并将距离超过某个阈值的点定义为噪声点,进行过滤。该方法通过拟合点云数据的曲面模型,对噪声点进行识别和过滤,从而得到更加干净的点云数据。

AuSwift的博客 638

GitHub上非常实用的40个开源JAVA项目_java开源项目

29.spring-projects/spring-loaded:spring开源的一个热替换插件,运行时监听class文件的变更并执行transform。40.weixin-java-tools:可能是目前最好最全的微信Java开发工具包,支持包括微信支付、开放平台、小程序、企业号和公众号等的开发。9.socketio/socket.io-client-java:http://Socket.IO的Netty实现(做聊天室可以用)。

2401_87252283的博客 2231

【教程4>第6章>第3节】LS信道估计与均衡系统MATLAB仿真实现

1]姬国伟,葛利嘉,龙秀虹.基于LS信道估计的SC-FDE系统性能研究[J].军事通信技术, 2010(1):6.DOI:CNKI:SUN:JSTY.0.2010-01-013.在无线通信中,信号在空间传播时,随着传输距离增加,能量会逐渐扩散,导致信号幅度减小,即发生衰减。第四个图表示的是提取的信道估计值,可以看到,在不插值的前提下,得到的信道估计值基本接近真实的信道h。从第五个图可知,通过信道估计,对接收信号进行了校正和补偿。信道模型,先通过awgn加入噪声,然后乘以hreal,模拟通过信道。

FPGA/MATLAB学习教程/源码/项目合作开发 386

Java面试题内容聚合,2024年最新java开发面试常问到的问题最新

其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

2401_84104809的博客 614

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java学习笔记、10T资料、200+java实战项目分享

文档类笔记 学习视频类资料 思维导图部分: java集合类思维导图 操作系统思维导图 设计模式思维导图 线程相关思维导图 这里就不逐一列举截图了,思维导图可以帮助大家系统全面的建立起知识网络,方便 大家理解和记忆,对求职面试非常重要,可以做到事半功倍。思维导图包括: 计算机网络思维导图 多线程相关思维导图 操作系统相关知识思维导图...

我的博客 1109

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java学习路线总结(书籍、视频推荐篇)_亿级流量java高并发与网络编程实战pdf下载(1)

附上我的书架,《Java编程思想》读了两遍,《深入理解Java虚拟机》读了一遍,《Head First设计模式》读了一遍,《Java并发编程实战》读了一遍,《重构》读了一遍,《Spring实战》没看进去,《Effective Java》读了一遍,《软技能 代码之外的生存指南》读了一遍,《深入理解Java虚拟机第三版》,《微服务实战》《算法4》,《亿级流量Java高并发与网络编程实战》,《JavaScript高级程序设计》,《HTTP权威指南》,《Java性能优化实践》还没开封。

2401_84573307的博客 1289

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

程序员必须深度学习!我仅一年工作经验就拿到了美团offer,分享我的深度学习经验

前言 人与人存在很大的不同,我们都拥有各自的目标,在一线城市漂泊的我偶尔也会羡慕在老家踏踏实实开开心心养老的人,但是我深刻知道自己想要的是一年比一年有进步。 美团一面 1.自我介绍 2.TCP的特点有哪些? 3.详细介绍一下三次握手和四次挥手 4.为什么是三次握手?挥手为什么有四次? 5.四次挥手中,处于time_wait的连接太多该怎么解决 6.介绍操作系统内存管理?逻辑地址和物理地址以及直接使用物理地址会存在什么问题? 7.JVM垃圾回收 8.mysql事务特性?隔离级别?解决了哪些问题? 9.Inno

weixin_53184798的博客 239

Java最全Java基础13 面向对象~static关键字和单例模式,java初级程序员面试题目

为了应付面试也刷了很多的面试题与资料,现在就分享给有需要的读者朋友,资料我只截取出来一部分哦静态属性的调用:类名.属性名也可以使用:对象名.属性一般推荐使用类名调用静态成员静态属性和非静态属性的区别int count;t1.count++;t2.count++;t3.count++;输出结果都是1,如果将count定义为static的,输出结果为3,为什么?总结:静态的属性保存在方法区中,每个对象都共享这一个静态属性。非静态的属性是由每个对象都有一个独立的副本。

2401_84689394的博客 1020

Java 设计模式—构建者模式简单使用

构建者模式中,用一个构建者类负责定义用于构建复杂对象的方法。这些方法通常是添加复杂对象的各个部分的方法。然后,有一个指挥者类负责调用构建者类的方法来构建复杂对象。

龚小帅的博客 583

程序员为什么需要一直深度学习?我用我的阿里四面告诉你答案(本人已offer)

前言 首先作为开发人员来说,不说要求自己成为业内顶尖,但也要保证自己不被市场所淘汰,学习对于程序员来说是最基本的事情。我个人认为,程序员就是一个需要不断深度学习的职业,下面是我根据我的面试总结出来的一点经验和面试真题,希望对你们有帮助! 阿里一面 1 ,自我介绍 2,说说有哪几种数据结构,每一种具体说说在哪能用到 3,说说进程和线程的区别 4,说说进程之间通信,每一种具体说说 5,说说进程的死锁条件,如何解决死锁 6,说说数据库的事物7,事物的隔离级别 8,了解redis 么 9,mysql 的两种引擎 1

欢迎您访问我的公众号【前程有光】 783

2024年阿里+头条+腾讯大厂Android笔试真题,37岁程序员被裁

自我介绍一下,小编13年北京科技大学毕业,曾经在字节跳动待过,也去过vivo、小米等大厂,18年进入华为一直到现在。小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担,能在岗位上再创辉煌,步步高升!!。

2401_84898679的博客 1087

设计模式之 监听者模式 (Java代码演示)

Subject:监听者容器SubjectHandler:监听者容器的实现类Thread1、Thread2 测试对象模拟两个线程对数据库操作,若Threa1执行时出异常了,那么终止所有线程并对其回滚。

a1901149的博客 1151

GitHub上非常实用的40个开源JAVA项目

1.biezhi/blade:一款轻量级、高性能、简洁优雅的MVC框架。 GitHub:http://h5ip.cn/O975 2.scribejava/scribejava:一个简单的 Java 实现的 OAuth/OAuth2 库。 GitHub:http://h5ip.cn/0pNf 3.winterbe/java8-tutorial:绝对值得一看的Java8指南、教程。 GitHub:http://h5ip.cn/W6du 4.javaee-samples/javaee...

【优快云】 1427

火爆豆瓣,GitHub 10,java校招面试经验

谈到面试,其实说白了就是刷题刷题刷题,天天作死的刷。。。。。为了准备这个“金三银四”的春招,狂刷一个月的题,狂补超多的漏洞知识,像这次美团面试问的算法、数据库、Redis、设计模式等这些题目都是我刷到过的并且我也将自己刷的题全部整理成了PDF或者Word文档(含详细答案解析)66个Java面试知识点架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)算法刷题(PDF)

2401_84435885的博客 572

从数学到深度学习的学习资料及教程合集

教程合集

诸神缄默不语的博客 5047

Java程序员必看经典书籍,助你早日打通任督二脉

很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

2401_84048935的博客 404
上一篇: 11、(结构型设计模式)Java 外观模式深度学习指南
下一篇: 14、(行为型设计模式)Java 观察者模式深度学习指南
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值