news 2026/10/20 13:59:04

若依V4.7+集成Mybatis-Plus代码生成器实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
若依V4.7+集成Mybatis-Plus代码生成器实战指南

简介:本资源是面向Java全栈开发者与若依平台二次开发者的工程实践包,聚焦于在若依前后端分离版中深度集成Mybatis-Plus代码生成器,解决重复编写CRUD基础代码、数据库变更后手动同步效率低等典型痛点。资源共2010个文件,主体为1605份Markdown文档(含环境配置说明、生成策略详解、避坑指南)、251个Java类(覆盖Entity/Controller/Service/Mapper全层生成代码)、101个JS前端适配脚本及31个XML映射配置,压缩包大小71.55MB,结构完整、开箱即用。已有540人学习下载,适合中高级开发者快速搭建标准化后端骨架、理解若依+Mybatis-Plus协同机制,并复用其生成逻辑支撑多模块迭代。包内含《若依环境使用手册.docx》等实操指引,结合大量.ds_store占位文件可推断其源自真实开发环境导出,目录层级清晰,便于按模块定位生成规则与自定义扩展点。

1. 若依前后端分离版集成Mybatis-Plus代码生成器:为什么不是“装上就用”,而是要重写模板、改三处配置、手动同步DTO?

你手头正跑着若依(RuoYi-Vue)前后端分离版,数据库刚建好12张表,想用Mybatis-Plus的代码生成器一键产出Controller、Service、Mapper、Entity、VO、DTO——结果发现:官方生成器吐出来的代码,和若依的包结构、注解风格、分页逻辑、全局异常处理、统一返回格式全都不兼容。Controller里没加@Validated,DTO没继承BaseEntity,ServiceImpl里没注入IService泛型接口,连@Api文档注解都缺字段说明。这不是省时间,是埋雷。这套方案专为「已在用若依V4.7.0+、需高频增删业务表、又不愿每次手写六层代码」的场景而生。它不替换若依原有架构,而是在其规范内做最小侵入式增强:复用若依的菜单权限体系、日志拦截、数据权限过滤;生成代码直接进ruoyi-system模块,开箱即配Swagger文档,支持Lombok+Jackson注解自动对齐,连@TableField(fill = FieldFill.INSERT)这种细节都按若依实体字段规则预置。适合毕设快速搭后台、课设交完整CRUD链路、中小项目迭代期提效——不是教你怎么写生成器,是给你一套能当天集成、次日交付、答辩时能现场演示“新增一张订单表→点生成→刷新页面就能增删改查”的完整落地方案。

2. 总体架构设计:三层嵌套结构与四个核心改造点的职责划分

若依原生未提供代码生成能力,Mybatis-Plus官方生成器又与若依工程强耦合不足。本方案采用“外挂式集成”策略:在ruoyi-generator独立模块中构建生成引擎,通过Maven依赖方式接入主工程,避免修改若依核心源码。整体为三层结构:配置层(yml驱动)→ 模板层(Freemarker定制)→ 执行层(Java API触发)。关键不在“能不能生成”,而在“生成的代码是否符合若依语义”——这要求四点精准对齐:包路径映射(如com.ruoyi.system.domain对应Entity)、注解体系(@Data+@TableName+@ApiModel三级嵌套)、DTO/VO字段校验规则(@NotBlank位置、@DateTimeFormat格式)、以及Service层的若依特有方法(如selectPageByQuery封装了数据权限SQL拼接)。所有改造均基于若依V4.7.2源码反推,不依赖任何第三方插件或IDEA扩展,纯Java实现,可打包为jar供多项目复用。

2.1 配置层:application.yml中定义生成策略与若依环境绑定

生成器行为由generator-config.yml控制,该文件必须放在ruoyi-generator/src/main/resources/下。关键参数非简单开关,而是与若依运行时深度绑定:

# generator-config.yml generator: # 【必填】若依主模块路径,用于计算相对包名(避免硬编码) base-package: com.ruoyi.system # 【必填】前端Vue组件存放路径,生成后自动写入路由(适配若依菜单管理) vue-path: src/views/system/order # 【策略】字段映射规则:若依要求create_time字段必须映射为createTime且带@TableField(fill=INSERT) field-strategy: create_time: { javaName: createTime, fill: INSERT } update_time: { javaName: updateTime, fill: UPDATE } remark: { javaName: remark, comment: "备注信息" } # 【安全】禁用敏感表生成(如sys_user、sys_menu),防止覆盖核心权限表 exclude-tables: [sys_user, sys_role, sys_menu, sys_dict_data]

提示:base-package值必须与ruoyi-system模块的pom.xml中<groupId>一致,否则生成的Mapper XML路径会错位到target/classes/mapper/xxxMapper.xml而非target/classes/mapper/system/xxxMapper.xml,导致启动报Invalid bound statement。

2.2 模板层:Freemarker模板的若依化改造清单

Mybatis-Plus默认模板输出的是通用Spring Boot结构,需重写5个核心模板文件(全部位于ruoyi-generator/src/main/resources/templates/):

模板文件改造重点若依适配说明
entity.java.ftl增加@TableName("sys_order")、@Data、@EqualsAndHashCode(callSuper = true)、继承BaseEntity若依所有Domain类均继承BaseEntity(含createBy/updateBy等审计字段)
mapper.java.ftl接口声明改为public interface OrderMapper extends BaseMapper<Order>,增加@Mapper注解若依使用@MapperScan("com.ruoyi.*.mapper"),必须显式标注@Mapper才能被扫描
service.java.ftl方法签名改为public interface IOrderService extends IService<Order>若依Service层强制要求IxxxService接口继承IService<T>,便于AOP切面统一处理
controller.java.ftl添加@Validated、@Api、@ApiOperation、@ApiImplicitParam,返回类型统一为AjaxResult若依全局返回封装为AjaxResult,Swagger文档需@Api系列注解才显示在http://localhost:80/
vue/index.vue.ftl生成<el-table>列时,自动识别create_time字段并渲染为{{ scope.row.createTime | parseTime('{y}-{m}-{d}') }}若依前端工具函数parseTime要求后端字段名为驼峰,不能直接用下划线

模板中所有包名、注解、方法名均从generator-config.yml动态读取,例如:

// entity.java.ftl 片段 package ${cfg.basePackage}.domain; import com.baomidou.mybatisplus.annotation.*; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; /** * ${table.comment!}对象 ${table.convertName} */ @Data @EqualsAndHashCode(callSuper = true) @TableName("${table.name}") public class ${entity} extends BaseEntity { <#list table.fields as field> /** ${field.comment!} */ <#if field.keyFlag> @TableId(value = "${field.name}", type = IdType.AUTO) <#else> @TableField("<#if field.fill??>fill = FieldFill.${field.fill}, </#if>value = \"${field.name}\") </#if> private ${field.propertyType} ${field.propertyName}; </#list> }

2.3 执行层:Java API触发生成与若依菜单自动注册联动

生成动作不通过命令行,而是封装为GeneratorService类,提供generateByTableName(String tableName)方法。调用时自动完成三件事:

  1. 代码生成:调用Mybatis-PlusAutoGenerator执行模板渲染;
  2. 菜单注入:向若依sys_menu表插入新菜单记录(menuName=订单管理、perms=system:order:list);
  3. 路由注册:将/system/order路径写入ruoyi-admin/src/router/index.js(追加{ path: '/system/order', component: () => import('@/views/system/order/index') })。

关键代码如下(GeneratorService.java):

@Service public class GeneratorService { @Autowired private MenuService menuService; // 若依原生MenuService,用于插入菜单 public void generateByTableName(String tableName) { // 1. 构建Mybatis-Plus生成器 AutoGenerator mpg = new AutoGenerator(); GlobalConfig gc = new GlobalConfig(); gc.setOutputDir("ruoyi-system/src/main/java"); // 输出到若依主模块 gc.setAuthor("generator"); gc.setOpen(false); gc.setSwagger2(true); // 启用Swagger注解 mpg.setGlobalConfig(gc); // 2. 数据源配置(复用若依application.yml中的spring.datasource) DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 3. 包配置:严格对齐若依目录结构 PackageConfig pc = new PackageConfig(); pc.setParent("com.ruoyi.system"); // 对应ruoyi-system模块 pc.setModuleName("order"); // 模块名,决定子包路径 pc.setEntity("domain"); // Entity放domain包 pc.setMapper("mapper"); pc.setService("service"); pc.setServiceImpl("service.impl"); pc.setController("controller"); mpg.setPackageInfo(pc); // 4. 模板配置:指定自定义模板路径 TemplateConfig templateConfig = new TemplateConfig(); templateConfig.setEntity("templates/entity.java.ftl"); templateConfig.setMapper("templates/mapper.java.ftl"); templateConfig.setService("templates/service.java.ftl"); templateConfig.setServiceImpl("templates/serviceImpl.java.ftl"); templateConfig.setController("templates/controller.java.ftl"); templateConfig.setXml("templates/mapper.xml.ftl"); mpg.setTemplate(templateConfig); // 5. 策略配置:表名转驼峰、字段过滤 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); // 下划线转驼峰 strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); strategy.setInclude(tableName); // 只生成指定表 mpg.setStrategy(strategy); // 6. 执行生成 mpg.execute(); // 7. 【若依特有】自动注册菜单(复用若依Menu实体和Service) SysMenu menu = new SysMenu(); menu.setMenuName(tableNameToChinese(tableName)); // 如order→订单管理 menu.setPath("/" + pc.getModuleName() + "/" + pc.getModuleName()); menu.setComponent("system/" + pc.getModuleName() + "/index"); menu.setPerms("system:" + pc.getModuleName() + ":list"); menu.setOrderNum(99); menu.setMenuType("C"); // C=菜单 menu.setStatus("0"); menuService.insertMenu(menu); // 调用若依原生方法插入 } private String tableNameToChinese(String tableName) { // 简单映射表名到中文(实际项目中建议查字典表或人工维护) Map<String, String> map = Map.of("order", "订单管理", "product", "商品管理", "user", "用户管理"); return map.getOrDefault(tableName, tableName); } }

此方法可被Web接口调用(如/gen/table),也可在单元测试中直接执行,确保生成过程可重复、可验证。

3. 核心模块实现:从数据库逆向解析到若依风格代码落地的全流程

生成器的核心价值不在“生成”,而在“生成得像若依”。本模块聚焦三个技术断点:表结构解析如何保留若依字段语义、DTO与VO分离如何满足若依前后端约定、分页查询如何无缝接入若依的PageDomain机制。每个环节都需绕过Mybatis-Plus默认逻辑,注入若依特有规则。

3.1 表结构解析:字段注释提取与若依审计字段自动识别

若依要求所有业务表必须包含create_by、create_time、update_by、update_time、remark五字段,且在Entity中需特殊处理。Mybatis-Plus默认仅解析字段名和类型,本方案在StrategyConfig中注入自定义TableFill策略:

// 在StrategyConfig配置中添加 strategy.setTableFillList(Arrays.asList( new TableFill("create_by", FieldFill.INSERT), new TableFill("create_time", FieldFill.INSERT), new TableFill("update_by", FieldFill.UPDATE), new TableFill("update_time", FieldFill.UPDATE), new TableFill("remark", FieldFill.DEFAULT) ));

但仅此不够——若依前端列表页需显示create_time的格式化时间,而数据库存的是datetime类型。因此在entity.java.ftl模板中,对create_time字段做特殊判断:

<#list table.fields as field> <#if field.name == "create_time"> /** 创建时间 */ @TableField(fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; <#else> /** ${field.comment!} */ <#if field.keyFlag> @TableId(value = "${field.name}", type = IdType.AUTO) <#else> @TableField(value = "${field.name}") </#if> private ${field.propertyType} ${field.propertyName}; </#if> </#list>

注意:@JsonFormat和@DateTimeFormat必须同时存在,前者控制JSON序列化(后端返回给前端),后者控制表单提交反序列化(前端传参给后端)。若依的@RequestBody和@RequestParam混合场景下,缺一不可。

3.2 DTO与VO分离:若依前后端字段约束的双向映射

若依严格区分DTO(Data Transfer Object,用于接收前端参数)和VO(View Object,用于返回前端数据)。DTO需校验,VO需脱敏。Mybatis-Plus默认只生成Entity,本方案在模板中拆分为两个文件:

  • dto/${entity}DTO.java.ftl:含@NotBlank、@Min(1)等校验注解,字段名与Entity一致,但不继承BaseEntity;
  • vo/${entity}VO.java.ftl:含@ApiModelProperty,字段名与Entity一致,但移除所有审计字段(createBy/updateBy等),仅保留业务字段。

例如订单DTO模板关键片段:

package ${cfg.basePackage}.dto; import io.swagger.annotations.ApiModelProperty; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; /** * ${table.comment!}DTO */ public class ${entity}DTO { /** ${table.pkColumn.comment!} */ @ApiModelProperty("主键") private Long ${table.pkColumn.propertyName}; /** ${table.columns[1].comment!} */ @NotBlank(message = "${table.columns[1].comment!}不能为空") @Length(max = 64, message = "${table.columns[1].comment!}长度不能超过64个字符") @ApiModelProperty("${table.columns[1].comment!}") private String ${table.columns[1].propertyName}; /** ${table.columns[2].comment!} */ @NotNull(message = "${table.columns[2].comment!}不能为空") @ApiModelProperty("${table.columns[2].comment!}") private Integer ${table.columns[2].propertyName}; }

VO模板则过滤掉createBy、updateBy等字段:

<#list table.fields as field> <#if !["create_by","update_by","create_time","update_time","remark"].contains(field.name)> /** ${field.comment!} */ @ApiModelProperty("${field.comment!}") private ${field.propertyType} ${field.propertyName}; </#if> </#list>

3.3 分页查询集成:若依PageDomain与Mybatis-PlusPage的桥接

若依前端分页参数固定为pageNum/pageSize,后端封装为PageDomain对象,并在SysController中统一转换为Mybatis-Plus的Page对象。生成器需确保Controller方法签名与若依一致:

// 生成的Controller方法(非Mybatis-Plus默认的IPage<T>) @GetMapping("/list") @ApiOperation("查询${table.comment!}列表") public AjaxResult list(PageDomain pageDomain, ${entity}VO vo) { startPage(pageDomain); // 若依工具类,将PageDomain转为ThreadLocal Page List<${entity}VO> list = ${table.lowerName}Service.select${entity}List(vo); return AjaxResult.success(list); }

其中startPage()是若依com.ruoyi.common.utils.PageUtils中的静态方法,内部调用PageHelper.startPage()。而select${entity}List()方法在Service中需返回List<${entity}VO>,其SQL需在Mapper XML中手动编写(因若依要求复杂条件查询走XML,而非LambdaQueryWrapper):

<!-- ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml --> <select id="selectOrderList" resultType="com.ruoyi.system.vo.OrderVO"> SELECT order_id AS orderId, order_no AS orderNo, product_name AS productName, status, create_time AS createTime FROM sys_order <where> <if test="productName != null and productName != ''"> AND product_name LIKE CONCAT('%', #{productName}, '%') </if> <if test="status != null"> AND status = #{status} </if> </where> ORDER BY create_time DESC </select>

提示:resultType必须指向VO类,且字段别名(AS orderId)必须与VO中属性名完全一致,否则Mybatis无法自动映射。这是若依XML风格与Mybatis-Plus注解风格的关键分水岭。

4. 避坑指南:若依+Mybatis-Plus生成器集成中最容易翻车的5个点

集成过程看似简单,实则处处是若依框架的隐性约定。以下5个问题,是某高校课程设计组、某公司毕设团队、某外包项目组在真实落地时踩过的坑,按发生频率排序,每条给出可立即验证的解决步骤。

4.1 现象:生成的Mapper XML文件未被Spring Boot加载,启动时报Invalid bound statement (com.ruoyi.system.mapper.OrderMapper.selectOrderList)

原因:Mybatis-Plus生成器默认将XML输出到resources/mapper/OrderMapper.xml,但若依的mybatis-plus配置指定了mapper-locations: classpath*:mapper/system/*.xml,要求XML必须在mapper/system/子目录下。
解决:修改GeneratorService中AutoGenerator的PackageConfig,强制设置XML输出路径:

// 在PackageConfig配置后添加 pc.setXml("mapper/system"); // 关键!让XML生成到mapper/system/目录 // 同时在TemplateConfig中指定xml模板路径 templateConfig.setXml("templates/mapper.xml.ftl"); mpg.setTemplate(templateConfig);

验证:启动后检查target/classes/mapper/system/OrderMapper.xml是否存在,且内容正确。

4.2 现象:前端调用/gen/table接口生成代码后,刷新页面找不到新菜单,或点击菜单报404

原因:菜单插入成功,但ruoyi-admin前端路由未热更新。若依前端路由由src/router/index.js静态定义,生成器写入文件后需重启前端服务,或手动F5强制刷新。
解决:生成器执行完菜单插入后,自动触发前端路由文件追加(见2.3节代码),但必须确保ruoyi-admin/src/router/index.js末尾有export default new Router({ routes: constantRoutes.concat(asyncRoutes) });结构,且asyncRoutes数组存在。若项目已删掉asyncRoutes,需在router/index.js中补上:

// ruoyi-admin/src/router/index.js 末尾 export const asyncRoutes = [ // 此处会被生成器自动追加 ]; export default new Router({ mode: 'history', scrollBehavior: () => ({ y: 0 }), routes: constantRoutes.concat(asyncRoutes) });

验证:生成后打开ruoyi-admin/src/router/index.js,确认末尾新增了{ path: '/system/order', component: () => import('@/views/system/order/index') }。

4.3 现象:生成的DTO校验不生效,@NotBlank注解被忽略,空字符串仍能提交成功

原因:若依Controller方法参数未加@Validated,或@Validated位置错误(如加在VO上而非DTO上)。
解决:检查生成的Controller方法签名,确保@Validated标注在DTO参数前:

@PostMapping @ApiOperation("新增${table.comment!}") public AjaxResult add(@Validated @RequestBody ${entity}DTO dto) // ✅ 正确 { return toAjax(${table.lowerName}Service.insert${entity}(dto)); }

若误写为@Validated @RequestBody ${entity}VO vo则无效,因VO不参与校验。
验证:用Postman发送{"orderNo": ""},应返回400 Bad Request及orderNo不能为空提示。

4.4 现象:生成的Entity中create_time字段在JSON响应中为null,但数据库有值

原因:缺少@JsonFormat注解,或pattern格式与数据库类型不匹配(如MySQLdatetime需yyyy-MM-dd HH:mm:ss,而timestamp需yyyy-MM-dd HH:mm:ss.SSS)。
解决:在entity.java.ftl中为时间字段显式添加注解:

<#if field.type == "DATE" || field.type == "DATETIME" || field.type == "TIMESTAMP"> @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") </#if>

验证:调用/order/list接口,检查响应中createTime字段是否为"2023-10-01 12:00:00"格式字符串。

4.5 现象:生成的ServiceImpl类编译报错,提示cannot find symbol: method getBaseMapper()

原因:Mybatis-Plus 3.4.0+版本中ServiceImpl类不再提供getBaseMapper()方法,而若依V4.7.x依赖此方法获取Mapper实例。
解决:降级Mybatis-Plus版本至3.3.2,并在ruoyi-generator/pom.xml中强制指定:

<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>3.3.2</version> </dependency>

同时在ServiceImpl模板中改用this.baseMapper:

@Override public int insert${entity}(${entity}DTO dto) { ${entity} entity = new ${entity}(); BeanUtils.copyProperties(dto, entity); return this.baseMapper.insert(entity); // ✅ 替换getBaseMapper().insert(entity) }

验证:编译ruoyi-system模块,确认无getBaseMapper相关报错。

5. 验收与答辩:用三步法验证生成质量,答辩时让老师当场看到“新增表→生成→运行”全过程

验收不是看代码有没有、功能能不能跑,而是验证生成的代码是否“像若依的人写的”。我带过三届毕设,学生常犯的错是:生成后只测了增删改查,却没验证与若依原有模块的兼容性。这里给出一套可量化的验收清单,以及答辩时最有效的演示节奏。

5.1 生成质量四维验收表(满分100分,≥90分视为合格)

维度检查项合格标准分值验证方式
结构合规性包路径Entity在com.ruoyi.system.domain,Mapper在com.ruoyi.system.mapper,Controller在com.ruoyi.system.controller20查看生成的Java文件首行package声明
注解完备性Swagger注解Controller类有@Api,方法有@ApiOperation,DTO字段有@ApiModelProperty20在Swagger UI(http://localhost:80/swagger-ui.html)中查看接口文档是否完整显示字段说明
若依特性审计字段处理Entity中create_time有@TableField(fill=INSERT)、@JsonFormat、@DateTimeFormat25检查生成的Entity.java文件,确认三注解共存
运行稳定性异常兜底新增一条数据后,update_time字段自动更新;删除时触发若依delFlag='2'软删除逻辑35手动执行SQLSELECT * FROM sys_order WHERE del_flag='2',确认软删除生效;修改数据库update_time为NULL,再调用编辑接口,检查是否自动填充

提示:答辩前务必用这张表逐项打分。曾有学生生成后忘了改delFlag逻辑,在答辩时老师随手删了一条数据,发现数据库记录被物理删除(而非del_flag=2),当场扣掉35分。

5.2 答辩演示黄金三分钟脚本(老师最关注的其实是“你懂不懂若依”)

不要一上来就讲原理,直接进入操作。我一般这样设计演示流:

  1. 第一分钟:建立信任感
    “老师好,我现在用若依V4.7.2最新版,演示一个真实业务场景:我们刚接到需求,要为‘客户反馈’模块新建一张表。请看,这是我在Navicat里创建的sys_feedback表,包含feedback_id、content、contact、status四个字段,其中status是字典类型。”(打开数据库,展示建表SQL)

  2. 第二分钟:突出你的工作量
    “接下来,我点击若依后台的‘代码生成’菜单,输入表名sys_feedback,勾选‘生成DTO/VO’,点击‘生成’。注意看控制台——它不仅生成了7个Java文件,还自动在sys_menu表插入了菜单记录,并向ruoyi-admin/src/router/index.js追加了路由。现在,我刷新前端页面……(等待2秒)您看,左侧菜单栏已出现‘客户反馈管理’,点击进入,就是标准的若依列表页。”(全程录屏,重点圈出菜单出现瞬间)

  3. 第三分钟:验证深度集成
    “最后验证关键点:我新增一条反馈,内容填‘系统登录慢’,联系方式填‘test@demo.com’,状态选‘待处理’。提交后,后端自动填充了create_by(当前登录人)、create_time(精确到秒),前端列表页显示格式化时间。再点击‘编辑’,修改内容为‘已优化’,此时update_by和update_time自动更新。整个过程,没改一行若依源码,所有生成代码都符合若依包结构、注解风格、分页机制。”(现场操作,截图对比生成前后代码)

从那以后我每次带毕设,都强制学生在答辩前用这个三分钟脚本自己演练5遍,重点练“刷新菜单后停顿半秒再点击”的自然感——老师不会看你代码多漂亮,但一定会记住你演示时那个菜单弹出来的瞬间。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 13:58:58

AI芯片软硬件协同设计:从架构到编译器的全链路实战指南

在AI芯片这个圈子里待久了&#xff0c;你会慢慢发现一个规律&#xff1a;每次一颗芯片流片回来&#xff0c;硬件团队最担心的不是功能bug&#xff0c;而是上面跑的模型达不到预期性能——要么速度上不去&#xff0c;要么精度掉点。这个问题的根子&#xff0c;往往不是单一模块设…

作者头像 李华
网站建设 2026/10/20 13:58:57

AI Infra全景地图:七层架构、GPU调度与分布式训练实战笔记

做AI Infra这块&#xff0c;最头疼的其实不是某个具体技术学不会&#xff0c;而是知识太散。今天看了篇分布式训练的博客&#xff0c;明天刷到个GPU调优的视频&#xff0c;后天又碰到个数据管线的分享&#xff0c;每样都似懂非懂&#xff0c;真到自己搭环境、调性能的时候&…

作者头像 李华
网站建设 2026/10/20 13:58:56

rsync远程同步实战:从增量原理到定时备份与daemon部署

搞运维的人&#xff0c;迟早都会撞上“数据同步”这道坎。不管是把代码推到多台机器上&#xff0c;还是把日志定期归档到备份机&#xff0c;甚至是给客户做异地灾备&#xff0c;这几个场景里最常被拉出来干活的工具&#xff0c;就是rsync。rsync这名字乍看像“远程同步”的缩写…

作者头像 李华
网站建设 2026/10/20 13:58:46

Web前端加密参数逆向分析:从抓包定位到签名还原实战

1. 项目概述与需求拆解我前阵子参与了一个模拟后台管理系统的安全评估任务&#xff0c;任务是分析其中几个可疑的加密参数。整个系统本身是一个典型的Web管理平台&#xff0c;登录、列表查询、数据提交这几个模块都有额外的参数加密逻辑。用户提交普通数据时&#xff0c;会用固…

作者头像 李华
网站建设 2026/10/20 13:58:16

Electron CDP协议:桌面应用的底层控制总线

1. 项目概述&#xff1a;CDP协议不是“浏览器调试工具”&#xff0c;而是Electron应用的底层操作总线“CDP协议实现Agent高效操作Electron桌面应用”——这个标题里藏着一个被大量开发者低估的关键事实&#xff1a;CDP&#xff08;Chrome DevTools Protocol&#xff09;在Elect…

作者头像 李华
网站建设 2026/10/20 13:57:41

AI辅助视频剪辑实操:把3小时剪片压缩到45分钟的时间账单

经常有人问我&#xff1a;“为什么我剪一条视频要两三个小时&#xff0c;别人半小时就搞定了&#xff1f;”我一般不会直接回答&#xff0c;而是反过来问一句&#xff1a;“你剪视频的时候&#xff0c;是不是一直在手动做字幕&#xff1f;”对方往往一愣&#xff0c;然后陷进沉…

作者头像 李华