news 2026/10/19 1:04:04

微信小程序+SpringBoot线上超市管理系统:从数据库设计到并发处理全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序+SpringBoot线上超市管理系统:从数据库设计到并发处理全解析

做课程设计或毕业设计的时候,最怕选的题目看上去高大上,实际做起来需求满天飞、边界又不清晰。今天想和你聊的这个选题——基于微信小程序+SpringBoot的线上超市管理系统,是我这几年带学生项目过程中见到的容错率很高、又特别容易做出完整度的一套方案。它不追求什么花哨算法,整个系统的核心就是一套围绕“商品→购物车→订单→库存”的业务闭环,前端用微信小程序做展示和交互,后端用SpringBoot提供接口,数据库设计再跟上,源码、数据库、设计文档三件套都能顺理成章地凑齐。下面我把从选题逻辑到答辩演示的完整思路拆给你看。

1. 为什么这个选题在课程设计中“性价比”很高

1.1 超市场景天然自带完整业务闭环

线上超市这个场景和外卖点餐、二手交易相比,最大的优势是“人人都懂”。进店、逛分类、加购物车、下单、支付、查订单、确认收货,这七步是我们每个人都有过的线下体验。需求分析阶段不需要编造生僻规则,答辩时也不用费劲解释“为什么这个模块要存在”,评委一听就明白,沟通成本直接降下来了。

另一个好处是角色对称性很强。系统只需要两种角色:普通用户(小程序端)和后台管理员(管理端)。用户做的事是注册登录、浏览商品、搜索、加购、下单、模拟支付、查看订单状态;管理员做的事是商品分类维护、商品上下架、库存修改、订单发货。角色少而功能分工明确,权限控制不会做得特别复杂,但又能完整展示“不同角色访问不同功能”的设计思路——这一点在评分细则里通常占不少权重。

业务闭环方面,超市天然有状态流转。一个订单从待支付到已支付,再到已发货、已完成,或者被取消,不是设计者凭空拍脑袋想出来的,而是现实业务本身就要求这样。用这种真实存在的状态机制去设计数据库和接口,比强行构造业务更有说服力,写文档时也更容易把“为什么这样设计”讲清楚。

1.2 前后端技术栈覆盖面广且难度可控

“微信小程序+SpringBoot”这个组合覆盖了移动端UI、服务端接口、关系型数据库的完整链路,对课程设计而言覆盖面已经非常充分。小程序端会涉及页面布局、组件通信、网络请求封装、本地缓存、登录授权这些移动开发常见能力;SpringBoot端则能完整体现Controller、Service、Mapper的三层架构,这正是课程里反复强调的核心概念。数据库层面,MySQL加MyBatis是当下最主流的搭配,SQL写在XML或注解里一目了然,后期改需求时直接改映射语句就行,排查问题也很方便,网上能搜到的资料特别多。

如果你非要问这个题目有什么坎,那主要集中在两处:一是订单和库存环节的并发处理,这属于业务流程里的硬骨头;二是文件上传和静态资源访问的设置,容易在部署阶段卡住。不过这两块恰恰是体现项目深度的地方,后面我会单独花篇幅把方案讲透。整体来说,这个选题的难度曲线是平滑的——大部分功能属于“照着常规套路就能实现”的级别,留给你的时间足以去打磨少数几个亮点。

2. 数据库设计:写代码前先定好表和字段

2.1 角色与功能矩阵先行

动手写任何代码之前,我强烈建议先把“角色-功能”矩阵列出来,哪怕只是在文档里画个表。用户端功能大概有:注册登录、首页展示、商品搜索、分类浏览、商品详情、购物车增删改查、订单提交、模拟支付、订单列表、取消订单、确认收货。管理端功能大概有:管理员登录、分类管理、商品管理、库存管理、订单管理、发货操作。这个矩阵一旦确定,后面的页面设计、接口定义、数据表字段都会变得非常清晰,不会再出现“功能做着做着发现缺字段”的情况。

2.2 商品、分类、轮播图三张表的分工

我第一次做类似项目的时候,把商品信息一股脑塞进一张表,结果后期要加轮播图推荐位、加商品排序,字段不知道该往哪里放。后来总结的经验是:分类单独一张表,商品一张表,轮播图配置单独一张表。这样每张表的职责单一,改起来互不牵制。

商品表的大致结构可以按下面这个方向设计:

CREATE TABLE goods ( id BIGINT PRIMARY KEY AUTO_INCREMENT, category_id BIGINT NOT NULL, name VARCHAR(100) NOT NULL, subtitle VARCHAR(200), main_image VARCHAR(255), detail TEXT, price DECIMAL(10,2) NOT NULL, stock INT NOT NULL DEFAULT 0, sales INT NOT NULL DEFAULT 0, status TINYINT DEFAULT 1 COMMENT '1上架 0下架', create_time DATETIME DEFAULT CURRENT_TIMESTAMP );

有几个字段建议你特别留意。sales也就是销量字段,虽然它可以通过订单明细统计出来,但单独冗余一个字段,商品列表按销量排序时调用会非常方便,管理端做数据展示也直观。status字段同样是必须的,商品下架本质是状态置为0,而不是删记录,这一点在数据库设计阶段就要想明白。main_image只存一个主图路径就好,不要试图把图片的二进制内容直接存进数据库字段里,那会让表体积暴增,访问速度也会受影响。

2.3 订单主表与明细表的快照设计

订单是整个系统里最核心的表,设计时要注意拆成主表和明细表两层。主表存订单编号、下单用户、总价、状态、支付时间、发货时间、完成时间;明细表存每个商品的名称、单价、数量、小图地址、商品ID。很多人会疑惑:明细表为什么还要冗余一份商品名称和价格?直接关联商品表的id不就行了吗?答案在于快照。

举个例子,用户下单时某商品叫“香辣味薯片”,过了两个月管理员把商品改名为“薯片(香辣)”,如果订单明细只存goods_id,用户打开历史订单看到的就是改名后的信息;更极端的情况是商品被下架或者删除,历史订单里这只商品可能直接显示不出来了。订单明细里保存一份下单时刻的商品名称、单价、图片路径,就是给历史订单做一份“现场快照”,保证过去的记录永远可信。这个点写进项目文档里,是非常实在的业务考虑。

CREATE TABLE order_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT NOT NULL, goods_id BIGINT, goods_name VARCHAR(100) NOT NULL, goods_image VARCHAR(255), price DECIMAL(10,2) NOT NULL, quantity INT NOT NULL, subtotal DECIMAL(10,2) NOT NULL );

订单主表的编号建议用独立字段order_no生成,不要直接用自增主键当订单号。因为订单号需要展示给用户,也涉及时间戳或随机因子,一般可以用“时间戳+随机数”或者“日期+自增ID”的方式生成,同时加上唯一索引。直接暴露自增ID,一方面容易被人遍历接口,另一方面用户也不容易辨认。

2.4 索引和状态字段的提前规划

建表的时候顺手把索引想好,后面能少走很多弯路。我建议至少考虑这几个查询场景:用户按状态查自己的订单列表,对应的索引组合是order表上的(user_id, status);管理员按状态筛选订单,对应的是(status, create_time);用户按分类浏览商品,对应的是goods表上的(category_id, status)。这些字段组合在查询时非常频繁,一次性能建好索引,好过数据量大了之后再去补。答辩时如果被问到索引设计,可以脱口而出“我根据页面查询条件预先设计了组合索引”,这就是个加分项。

状态字段的数值定义也建议用常量表或枚举类统一管理,不要散落SQL里到处写1和0。比如订单状态0待支付、1已支付、2已发货、3已完成、4已取消,在Java代码里定义一个OrderStatusEnum,数据库里写COMMENT,这样前后端沟通成本会低很多。

3. 微信小程序端:从页面拆解到登录与购物车

3.1 页面目录与tab导航的规划

小程序端的页面我习惯拆成四个主导航tab:首页、分类、购物车、我的,再额外挂载商品详情、订单列表、订单详情、登录等二级页面。tab数量控制在5个以内,这既是小程序官方的硬性限制,也符合用户的操作习惯。页面多了会让整个项目显得杂乱,少了又装不下业务模块,四主tab是个比较稳妥的配比。

目录结构可以按这个思路组织:

miniprogram/ ├── pages/ │ ├── index/ // 首页 │ ├── category/ // 分类页 │ ├── goods-detail/ // 商品详情 │ ├── cart/ // 购物车 │ ├── order-list/ // 订单列表 │ ├── order-detail/ // 订单详情 │ └── user/ // 我的 ├── components/ // 通用组件 ├── utils/ │ ├── request.js // 统一请求封装 │ └── auth.js // 登录相关 └── app.js

3.2 微信登录流程与token管理

微信小程序的登录流程跟传统Web登录差异很大,很多第一次接触的人会在这里卡住。核心只有一句话:wx.login拿到的是临时code,这个code必须交给后端,由后端调用微信的接口换取openid,再生成业务token返回给小程序端。小程序端不能直接拿code去换用户信息,也不应该接触任何敏感参数。

// utils/auth.js 登录示例 function login() { return new Promise((resolve, reject) => { wx.login({ success: async (res) => { if (res.code) { const loginRes = await request({ url: '/api/auth/login', method: 'POST', data: { code: res.code } }); wx.setStorageSync('token', loginRes.data.token); resolve(loginRes.data); } else { reject(res); } }, fail: reject }); }); }

这里的常见理解误区是:小程序端要直接请求微信接口去换openid。实际应该是后端把换取的openid作为业务数据入库,再发给小程序端一个自定义token。把token保存在本地缓存,之后每次请求都带上。这个设计既规范又安全,答辩时主动讲出“openid由后端换取,避免前端暴露敏感参数”,效果会很好。

3.3 首页、商品列表和购物车的实现细节

首页不用做得过分复杂,一般就是顶部搜索框、轮播图、分类入口、推荐商品列表四块就够了。轮播图建议从后台的配置表读取,这样后续想换活动图不用发布新版本小程序,只需要改数据库里的图片路径。分类页建议左侧是分类列表、右侧展示该分类下的商品,这种左右联动的布局在电商类小程序里非常常见,实现也不难,商品列表记得用分页加载,pageNum从1开始,pageSize固定10条,返回结果里带一个total字段,前端判断是否继续上拉加载。

购物车页面的核心原则是“本地计算、服务端确认”。用户可以勾选、修改数量、删除商品,页面展示金额时先用本地数据算出来显示,点击结算后把商品Id和数量列表发给后端,后端重新计算价格并校验商品状态。为什么不能直接信任前端传来的总价?因为用户完全可以改请求参数。一个安全性意识足够强的项目,后端必须对所有关键金额做二次计算,这一点写进设计文档里会显著提升专业度。

3.4 提交订单时的前端校验与后端确认

用户点击结算按钮后,前端不要急着跳转支付页,应该先检查购物车里是否有选中商品、数量是否异常,再调后端创建订单接口。创建订单接口设计成POST /api/order/create,请求体里传一个包含商品Id和数量的数组。后端要做的事情包括:检查每个商品是否存在且处于上架状态、计算实时总价、检查库存是否足够、创建订单主表和明细表、把购物车里对应的商品移除。整个过程涉及多张表的写操作,必须包在事务里。

课程设计阶段,支付通常不用真的接微信支付,因为个人小程序没有支付权限,企业主体申请流程也复杂。我的建议是做成模拟支付页面,提供“模拟微信支付”“模拟余额支付”等选项,点击后直接调后端的支付接口,把订单状态从未支付改成已支付。这个方案既完整展示了支付流程的闭环,又避免被支付资质卡住进度。

4. SpringBoot后端:三层架构与核心业务闭环

4.1 Controller-Service-Mapper分层与统一返回体

后端部分我强烈建议严格按三个层次组织:Controller负责接收参数和返回结果,Service负责业务逻辑,Mapper负责SQL交互。哪怕项目规模不大,也要刻意坚持这个分层。答辩时被问“分层体现在哪里”,如果你能实际指出某个请求从Controller进Service进Mapper的完整调用路径,这个答案会很扎实。

与之配套的是一套统一返回结构。所有接口无论成功失败都返回同样的JSON格式,前端请求封装就只需要判断code字段,不需要每个页面单独写一套错误处理。下面是一个最简单的结构:

public class Result<T> { private Integer code; private String message; private T data; public static <T> Result<T> ok(T data) { Result<T> r = new Result<>(); r.setCode(200); r.setMessage("success"); r.setData(data); return r; } public static <T> Result<T> error(Integer code, String message) { Result<T> r = new Result<>(); r.setCode(code); r.setMessage(message); return r; } }

这个结构看着简单,但在整个项目里能省下大量重复代码。为了配合它,后端还需要一个全局异常处理器,把参数校验异常、业务异常、数据库异常分别转成对应的code和message,而不是把堆栈信息直接返回给前端。

4.2 登录鉴权拦截器与接口白名单

用户登录后,后端需要生成一个token。课程设计阶段推荐用JWT,主要原因就是无状态、实现简单、好讲。生成token时把userId放进去,之后拦截器从请求头里解析token,把userId放到请求上下文里,Service层需要当前登录用户时直接取。

@Component public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); Long userId = JwtUtil.parseToken(token); if (userId == null) { response.setStatus(401); return false; } UserContext.set(userId); return true; } @Override public void afterCompletion(...) { UserContext.clear(); } }

这里有一个特别容易踩的坑:拦截器的白名单问题。登录接口、商品查询接口、商品详情接口、首页数据接口这些在用户未登录时也要能访问;购物车、下单、订单查询、个人中心这些必须登录。如果图省事把所有接口都拦上,小程序端未登录状态下加载首页就会全挂。我第一次做的时候就是没配白名单,首页一直401,排查了快两个小时才意识到是拦截器把所有请求都拦截了。所以配置拦截器时要预留一个excludePathPatterns数组,把不需要登录就能访问的接口路径放进去。

4.3 订单状态机、超时关闭与定时任务

订单状态不能乱跳。我建议在文档里画一张状态迁移表,开发时严格照着走:

当前状态可触发操作后置状态
待支付用户支付已支付
待支付用户取消已取消
已支付管理员发货已发货
已发货用户确认收货已完成
已支付系统超时关闭已取消

为什么要这么严?因为很多业务bug,比如重复发货、重复取消、取消已支付订单,都是因为状态没有加限制,导致并发操作都能通过。比如用户同时请求两次取消接口,如果没有状态判断,两个请求可能都执行成功,一个待支付订单就被取消两次,第二天一看数据乱了,再逐条排查就很痛苦。

超时关单用Spring的@Scheduled定时任务就能解决。每30秒扫一次,把创建时间超过30分钟且状态为待支付的订单关掉,同时把扣减的库存加回去。注意这里要保证“关单”和“库存回补”在同一事务里执行,否则断了一环数据就不一致。

4.4 库存扣减防超卖:一个SQL解决并发问题

库存扣减是线上超市里最需要讲清楚的部分,也是体现你“懂并发”的关键点。最直观但错误的写法是:先查库存,判断库存足够,再执行更新。这在并发场景下会出大问题:两个请求同时查出库存为1,同时判断足够,然后同时扣减,结果都下单成功,库存变成了负数。这就是超卖。

正确的思路是把“判断库存是否足够”和“扣减库存”合并成一个原子SQL操作,再用受影响的行数判断是否成功。Mapper层可以这样写:

@Mapper public interface GoodsMapper { @Update("UPDATE goods SET stock = stock - #{num}, sales = sales + #{num} " + "WHERE id = #{goodsId} AND stock >= #{num}") int deductStock(@Param("goodsId") Long goodsId, @Param("num") Integer num); }

调用方配合事务:

@Transactional public Long createOrder(CreateOrderReq req) { // 1. 遍历购物车商品 // 2. 对每个商品调用 deductStock,如果返回值是0,说明库存不足或并发冲突 // throw new BizException("库存不足") // 3. 创建订单主表,得到orderId // 4. 批量创建订单明细 // 5. 清空购物车对应条目 // 6. 返回orderId }

这个方案可以把库存判断和扣减变成一次行级原子操作,数据库的行锁天然保证了不会两个请求同时扣减同一件商品的最后一件库存。需要注意:事务必须打开,因为一旦订单创建失败,之前扣减的库存必须回滚。我在实际测试里对比过,这个写法在压测时非常稳定,也没有出现超卖。如果做毕业设计想加一个亮点,可以再提一下“乐观锁/唯一订单号防重复提交”的思路,但最关键的是把上面这个SQL讲清楚。

5. 容易被忽视却影响评分的高分细节

5.1 图片上传、静态资源映射和保存位置

商品系统必然涉及图片上传。后端需要一个上传接口,接收MultipartFile,把文件保存到磁盘某个固定目录,再把访问URL返回给前端。这里有一个坑:不要把图片保存到项目的resources目录下,因为项目打成jar包后这个目录是只读的,运行时无法写入。建议把上传目录配置成一个外部绝对路径,比如项目根目录下的upload/文件夹,然后在SpringBoot里配置静态资源映射:

spring: mvc: static-path-pattern: /upload/** web: resources: static-locations: file:${user.dir}/upload/

这个配置的意思是:URL里凡是/upload/**的请求,都去项目启动目录下的upload/文件夹里找对应文件。配置好之后,图片上传返回的URL就能通过外网访问了。小程序端上传图片走的是wx.uploadFile,注意请求头和普通wx.request不一样,后端接收文件的接口也不用加application/json的Content-Type,这一点容易搞混。

5.2 全局异常处理与参数校验

接口之前我们说了统一返回结构,那异常怎么处理?写一个@RestControllerAdvice全局异常处理器,拦截三类异常:业务异常、参数校验异常、系统异常。业务异常对应我们主动抛出的错误,比如库存不足、订单状态错误;参数校验异常对应@Valid注解校验失败的场景;系统异常就是兜底,返回“系统繁忙”之类的提示,同时后端日志打印详细错误。

参数校验用Spring Validation的注解就能解决大部分问题。比如数量必须大于0,用@Min(1);订单状态必须是在合法范围内,可以自定义校验注解。不要把所有参数判断都堆在Service里写if,那会让业务代码变得非常啰嗦,可读性也差。答辩时展示这类工程化细节,会让项目看起来“有点样子”。

5.3 逻辑删除与状态流转约束

前文已经反复提到状态字段,这里再强调一次。商品下架是status置0,不是DELETE;用户取消订单是status变成已取消,不是删除订单记录。分类删不掉,因为分类下有商品时系统会提示“该分类下存在商品,无法删除”。这些规则表面上看是编程上的约束,本质上是数据完整性的保障。把这些“保护性设计”写进文档和答辩PPT里,比单纯贴一堆CRUD代码更有说服力。

我的体会是,遇到业务规则不确定的时候,多问一句“这条数据如果被删了,历史记录会不会出问题”。凡是跟订单、交易、资金相关的记录,都不应该物理删除。养成这个习惯后,很多看似复杂的设计问题其实都能自己推出来。

5.4 日志、时区、连接配置等细节

毕业设计阶段,日志系统不用做得特别复杂,但至少要保证MyBatis的SQL能打出来。在application.yml里把Mapper接口包的日志级别设为debug:

logging: level: com.example.shop.mapper: debug

开发环境下能看到每个请求实际执行的SQL,排查问题效率会高很多。另外要注意时间字段的展示,建议数据库存DATETIME,前端拿到后直接做字符串展示,不要在小程序端把时间戳转来转去。时区不一致会导致时间显示差8个小时,这种问题排查起来特别浪费时间。还有一个非常实际的点:数据库连接配置、端口号、文件上传路径,这些应该放在application.yml的显眼位置,不要硬编码到代码里,否则换环境调试时改代码重新打包,太麻烦了。

6. 源码、数据库、文档三件套:交付与答辩准备

6.1 源码目录组织与注释规范

很多同学功能做完了,代码一交就完事,结果评委打开项目发现目录混乱,注释几乎没有,观感直接打折扣。我先说一个最基础的建议:用Git管理代码,哪怕只有一个人开发也值得。现在不少学校要求学生提交项目到代码仓库,即使不强制,把版本管理做起来本身也是专业习惯的体现。

后端代码的包结构建议按职责划分:controller、service、mapper、entity、config、common。前端页面按功能命名,一个页面一个文件夹,不要把所有页面堆在一个目录里。注释不追求多,但每个Service方法上方至少写一句“这个方法做什么、入参是什么、返回值是什么”。真正高质量的代码是结构清晰、命名规范、注释关键位置,而不是写满废话注释。

6.2 数据库初始化脚本与演示数据

提交的数据库文件建议分成两个:表结构脚本和初始数据脚本。表结构脚本包含所有建表语句、索引、外键(外键视情况加);初始数据脚本给项目填充演示数据。这里我特别要强调:演示数据一定要给足。老师运行你的项目时,如果看到首页空白、商品列表空荡、分类什么都没有,心里已经打了负分。至少要准备几组合理的分类,比如蔬菜水果、休闲零食、饮料乳品、粮油调味、日用百货,每个分类下放3到6个商品,图片路径能放真实图就放真实图,哪怕暂时放占位图,也比空着好。

如果连演示数据里的商品价格、库存、销量都想得比较符合实际,比如薯片价格不是乱填的0.01元,而是贴合市场价的几元钱,评委对你的印象会立刻不一样。细节决定印象分,这句话在课程设计里是真实存在的。

6.3 设计文档的结构与篇幅控制

课程设计要求“万字文档”时,很多人的第一反应是凑字数。但更合理的思路是:把每个核心模块写透,字数自然就上去了。文档结构一般包括需求分析、系统设计、数据库设计、详细设计、系统实现、测试与分析,这几章是评分重点。

这里有一个技巧:数据库设计章节把每张表的字段列成表格,详细设计章节把每个核心流程写清楚,接口文档列出每个接口的URL、请求参数、返回参数。这三块内容占的篇幅最大,也最体现工作量。反而是开头的背景意义介绍和结论部分,简单写几句就好,不需要浪费大量篇幅。答辩老师翻文档时,往往先扫数据库设计和详细设计,这两章内容扎实,文档的基本分就保住了。

6.4 答辩演示顺序与常见提问

答辩演示的顺序很有讲究。不要一上来就打开代码读代码,也不要先介绍一堆技术概念,而是直接从业务场景走起。我的建议顺序是:

  1. 用户端登录进入系统,浏览首页和分类页,简单搜索商品。
  2. 进入商品详情,把一件商品加入购物车,演示购物车里的数量修改和勾选。
  3. 提交订单,走模拟支付流程,用户端看到订单变为已支付。
  4. 切到管理端后台,管理员看到新订单,执行发货操作。
  5. 回到用户端,刷新订单列表,看到订单状态变为已发货,然后确认收货。
  6. 再演示一个取消订单的场景,取消后回到商品页,看到库存已经回补。

这套流程走完,业务闭环和关键亮点都展示到了,全程也就三五分钟,但信息量非常大。如果现场时间充裕,可以打开数据库演示订单表和商品表的数据变化,证明“数据是真的落库了”。

答辩老师大概率会问这么几个问题:用户密码怎么保存的?库存扣减会不会超卖?订单状态是怎么流转的?接口有做权限校验吗?这些点本文前面都覆盖到了。只要你在演示结束前主动把问题答案带出来,比如演示时顺嘴提一句“这里库存扣减用的原子SQL,防止并发超卖”,老师基本不会再追问太深。

6.5 交付前的最后检查

最后再说一个实战经验:交项目之前,至少完整跑三遍流程。第一遍在开发环境,把每个按钮都点一遍;第二遍在打包后的环境,确认配置文件没问题;第三遍时把电脑断网,看本机启动是否正常,因为答辩教室的WiFi时好时坏,尽量保证项目运行不依赖外网。小程序端如果做真机演示,记得在开发者工具里勾选“不校验合法域名”,或者提前把request域名配置好。这些准备工作看着不起眼,但每年都有同学在现场因为环境问题卡壳,把好好的项目演示搞砸了。

做完上述所有事情之后,这个项目对你来说就不仅是一个“写过的系统”了——从选题分析到数据库设计,从前后端实现到并发处理,再到文档组织和答辩演示,每个环节你都有拿得出手的内容。希望这篇拆解能帮你把这个题目做成一个真正能体现自己水平、又经得起评审追问的作品。

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

鸿蒙ArkTS开发实战:待办清单应用开发指南

1. 项目背景与核心价值鸿蒙操作系统&#xff08;HarmonyOS&#xff09;作为新一代智能终端操作系统&#xff0c;其分布式能力和ArkTS语言正逐步改变移动应用开发格局。这个待办清单案例看似简单&#xff0c;实则包含了鸿蒙应用开发的多个核心技术要点。我在实际开发中发现&…

作者头像 李华
网站建设 2026/10/17 20:54:51

Tessy单元测试提高软件质量:嵌入式C函数级测试与桩机制实战

简介&#xff1a;这份PDF白皮书聚焦单元测试与分类树方法&#xff0c;面向嵌入式软件开发者、测试工程师及关注功能安全与代码质量的团队&#xff0c;帮助读者理解如何借助Tessy工具系统化提升软件可靠性。资源共1个PDF文件&#xff0c;压缩包约1.87MB&#xff0c;内容为Hitex出…

作者头像 李华
网站建设 2026/10/18 21:34:13

多线程服务器文件描述符传递:从裸int到SCM_RIGHTS的正确姿势

1. 一场典型的多线程服务器事故现场先看一段很常见的代码&#xff0c;很多刚开始写Linux并发服务器的同学&#xff0c;第一版往往长这样&#xff1a;// 主线程 while (1) {int connfd accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);thread_pool_add_task(co…

作者头像 李华
网站建设 2026/10/17 20:54:50

XXE漏洞实战:从文件读取到内网渗透的利用与防御

做授权渗透测试时&#xff0c;我有个习惯&#xff1a;只要接口里出现了XML字样&#xff0c;不管它带不带XXE三个字母&#xff0c;都会顺手测一下。原因很简单——XXE漏洞不是那种需要复杂业务逻辑才能触发的洞&#xff0c;它往往是一个解析器默认配置就坑了一个系统的洞。从一个…

作者头像 李华
网站建设 2026/10/18 11:20:35

NCS8801S芯片RGB/LVDS转EDP:选型、配置与调试实战指南

简介&#xff1a;NCS8801S 是一颗低功耗、高性能的 RGB/LVDS 转 eDP 桥接芯片&#xff0c;面向从事手机、平板、笔记本等移动设备显示方案设计的硬件工程师与嵌入式开发者。它可将单/双通道 LVDS 或 18/24bit RGB 信号转换为 1/2/4-lane eDP 输出&#xff0c;支持 1.62/2.7Gbps…

作者头像 李华