news 2026/9/16 14:21:07

SpringBoot3+Vue3校园跳蚤市场毕业设计实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot3+Vue3校园跳蚤市场毕业设计实战

简介:本资源是一套面向计算机专业本科生的2025届毕业设计实战项目——大学校园跳蚤市场平台,聚焦高校二手交易场景,完整覆盖需求分析、前后端开发、数据库设计与部署实践,适用于Java全栈入门到进阶学习者及课程设计/毕设选题参考。压缩包共4个文件(47.03MB),含1个功能演示录屏MP4(直观展示商品浏览、发布、下单全流程)、1个结构清晰的源码ZIP(SpringBoot3后端+Vue.js3双端前台)、1个MySQL8建库建表SQL脚本(含用户、商品、订单等核心表结构与示例数据)、1份详实的需求文档DOCX(含功能模块划分、角色权限说明与业务流程图)。目前已有138人学习下载,配套B站启动教程与系统录屏双视频,降低环境配置门槛;代码分层规范、注释完整,数据库设计兼顾扩展性与校园场景特性,是理解电商类系统从0到1落地的优质教学级案例。

1. 为什么一个「大学校园跳蚤市场平台」值得用 SpringBoot3 + Vue.js3 做毕业设计?

不是所有毕业设计都扛得住答辩现场的三连问:数据怎么存?并发怎么压?前端怎么和后端对齐接口?而「大学校园跳蚤市场平台」恰恰是检验工程能力的黄金切口——它不追求百万级 QPS,但必须真实覆盖用户注册、商品发布、图片上传、即时沟通、订单状态流转、多角色权限(学生/管理员/审核员)等完整闭环;它不依赖复杂算法,却天然暴露事务一致性(如库存扣减+订单生成+消息通知)、文件安全(学生上传的二手教材封面/电子产品实拍图需防 XSS 和越权访问)、前后端协作规范(比如商品列表分页参数命名是否统一为page而非pageNum)等硬核细节。用 SpringBoot3 而非 2.x,不是为了“新”,而是必须直面 Jakarta EE 9+ 命名空间迁移(javax.*jakarta.*)、GraalVM 原生镜像兼容性、更严格的默认 CSRF 策略;选 Vue.js3 则绕不开 Composition API 对响应式逻辑的封装能力——比如「发布商品时实时校验标题长度并同步更新剩余字数」这种交互,在 Options API 里要散落在datamethodswatch三处,而在setup()里能聚合成一个可复用的useTitleCounter组合式函数。这正是 2025 届计算机/软件工程专业学生最该拿得出手的「小而全、严而实」的技术落地方案。

2. 搭建 SpringBoot3 后端:从 IDEA 创建项目到 RESTful 接口落地

2.1 在 IDEA 中创建 SpringBoot3 项目的最小可行配置

SpringBoot3 要求 JDK17+,且必须使用 Spring Initializr 的 3.x 版本(非 legacy)。在 IDEA 2024.1+ 中新建项目时,关键操作如下:

  • Project SDK:选择已安装的 JDK17 或 JDK21(推荐 JDK21,因 SpringBoot3.2+ 对其支持更成熟)
  • Spring Boot Version:明确选3.2.12(截至 2025 年初的稳定版,避免选-SNAPSHOTRC
  • Dependencies:勾选以下四项(精简原则:不加 MyBatis-Plus、不加 Lombok、不加 Security Starter,先跑通再加固):
    • Spring Web
    • Spring Data JPA
    • H2 Database(开发阶段内存数据库,免装 MySQL)
    • Validation(用于@NotBlank等注解校验)

提示:若创建后pom.xml中出现spring-boot-starter-parent版本为3.1.x,请手动改为3.2.12,并确认<java.version>1721。否则启动时会报java.lang.NoClassDefFoundError: jakarta/servlet/Filter——这是 Jakarta EE 迁移不彻底的典型症状。

2.1.1 验证项目能否启动:写一个最简 Controller
// src/main/java/com/example/flea/HelloController.java @RestController @RequestMapping("/api") public class HelloController { @GetMapping("/health") public Map<String, Object> healthCheck() { return Map.of( "status", "UP", "timestamp", System.currentTimeMillis(), "spring-boot-version", "3.2.12" ); } }

启动应用后访问http://localhost:8080/api/health,返回 JSON 即表示基础环境就绪。注意:SpringBoot3 默认关闭了/actuator/health的暴露,此接口是手动编写的轻量替代方案,专为毕业设计答辩演示准备——评委能一眼看到版本号和时间戳,比单纯返回"Hello World"更显工程意识。

2.2 设计核心实体与 JPA 映射:紧扣跳蚤市场业务语义

跳蚤市场本质是 C2C 交易,实体关系必须反映校园场景约束。例如:学生账号必须绑定学号(唯一且不可改)商品图片存储路径需按用户 ID 分目录隔离订单状态流转需严格限定(如“已下单”不能直接跳转“已评价”)。JPA 实体设计如下:

// src/main/java/com/example/flea/entity/User.java @Entity @Table(name = "t_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true, nullable = false, length = 20) // 学号最长20位 private String studentId; // 关键字段:学号,非 username! @Column(nullable = false, length = 50) private String realName; @Column(unique = true, nullable = false, length = 100) private String email; @Column(length = 255) private String avatarUrl; // 头像地址,如 /upload/avatar/202411001.jpg // getter/setter 省略 }
// src/main/java/com/example/flea/entity/Commodity.java @Entity @Table(name = "t_commodity") public class Commodity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, length = 100) private String title; // 商品标题 @Column(columnDefinition = "TEXT") // 长文本,存商品描述 private String description; @Column(nullable = false, precision = 10, scale = 2) private BigDecimal price; // 价格,精确到分 @Column(name = "user_id", nullable = false) private Long userId; // 外键指向 t_user.id,不建 @ManyToOne,避免懒加载陷阱 @Column(name = "status", nullable = false, length = 20) @Enumerated(EnumType.STRING) private CommodityStatus status; // 枚举:ON_SALE, SOLD_OUT, DELETED @Column(name = "created_time", nullable = false, updatable = false) @CreationTimestamp private LocalDateTime createdTime; // getter/setter 省略 } // 枚举类定义 public enum CommodityStatus { ON_SALE, // 在售 SOLD_OUT, // 已售出 DELETED // 已下架(软删除) }

注意:Commodity中未使用@ManyToOne关联User,而是用userId字段存外键值。这是毕业设计阶段的务实选择——避免 JPA 懒加载导致 N+1 查询(如查 10 个商品,触发 10 次用户查询),也规避了@JsonIgnore循环引用问题。后续如需查用户信息,用JpaRepository.findById()单独查即可,逻辑清晰,答辩时易解释。

2.3 实现商品 CRUD 接口:用 Spring Data JPA + 自定义 SQL 控制精度

RESTful 接口需严格遵循资源命名规范:/api/commodities(集合)和/api/commodities/{id}(单个)。关键点在于分页查询和状态过滤:

// src/main/java/com/example/flea/repository/CommodityRepository.java @Repository public interface CommodityRepository extends JpaRepository<Commodity, Long> { // 自定义 JPQL 查询:只查在售商品,按创建时间倒序,支持分页 @Query("SELECT c FROM Commodity c WHERE c.status = :status ORDER BY c.createdTime DESC") Page<Commodity> findOnSale(@Param("status") CommodityStatus status, Pageable pageable); // 原生 SQL 查询:按标题模糊搜索(防 SQL 注入,用 ?1 占位符) @Query(value = "SELECT * FROM t_commodity WHERE status = ?1 AND title LIKE %?2%", nativeQuery = true) List<Commodity> searchByTitle(CommodityStatus status, String keyword); }
// src/main/java/com/example/flea/controller/CommodityController.java @RestController @RequestMapping("/api/commodities") public class CommodityController { private final CommodityRepository commodityRepository; public CommodityController(CommodityRepository commodityRepository) { this.commodityRepository = commodityRepository; } // GET /api/commodities?page=0&size=10&status=ON_SALE @GetMapping public ResponseEntity<Page<Commodity>> listCommodities( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size, @RequestParam(defaultValue = "ON_SALE") CommodityStatus status) { Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdTime")); Page<Commodity> result = commodityRepository.findOnSale(status, pageable); return ResponseEntity.ok(result); } // POST /api/commodities @PostMapping public ResponseEntity<Commodity> createCommodity(@RequestBody Commodity commodity) { // 强制设置状态为 ON_SALE,防止前端传入非法值 commodity.setStatus(CommodityStatus.ON_SALE); commodity.setCreatedTime(LocalDateTime.now()); Commodity saved = commodityRepository.save(commodity); return ResponseEntity.status(HttpStatus.CREATED).body(saved); } }
参数名类型必填说明示例
pageint页码(从 0 开始)0表示第一页
sizeint每页数量10为默认值
statusstring商品状态枚举值ON_SALESOLD_OUT

3. 构建 Vue.js3 前端:从 Vite 初始化到商品列表组件化开发

3.1 使用 Vite 创建 Vue3 项目并集成 Axios 与路由

Vue.js3 官方推荐 Vite 构建工具,启动速度远超 Vue CLI。终端执行:

npm create vite@latest flea-frontend -- --template vue cd flea-frontend npm install npm install axios vue-router@4 pinia@2

关键配置文件修改:

  • src/router/index.js:定义路由守卫,确保未登录用户无法访问/publish页面
import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' import PublishView from '../views/PublishView.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'home', component: HomeView }, { path: '/publish', name: 'publish', component: PublishView, beforeEnter: (to, from, next) => { // 简单模拟登录态:检查 localStorage 是否有 token const token = localStorage.getItem('auth_token') if (token) { next() } else { next({ name: 'login' }) // 跳转登录页 } } } ] }) export default router
  • src/utils/request.js:封装 Axios,统一处理 baseURL 和错误
import axios from 'axios' const request = axios.create({ baseURL: 'http://localhost:8080/api', // 后端 SpringBoot 地址 timeout: 10000 }) // 请求拦截器:自动携带 token request.interceptors.request.use(config => { const token = localStorage.getItem('auth_token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // 响应拦截器:统一错误处理 request.interceptors.response.use( response => response, error => { if (error.response?.status === 401) { localStorage.removeItem('auth_token') window.location.href = '/login' } return Promise.reject(error) } ) export default request

3.2 开发商品列表页面:Composition API + Pinia 状态管理

HomeView.vue是首页,核心是「分页加载商品」和「状态筛选」。使用defineComponentref/onMounted实现:

<!-- src/views/HomeView.vue --> <script setup> import { ref, onMounted } from 'vue' import request from '@/utils/request.js' import { useCommodityStore } from '@/stores/commodity.js' const store = useCommodityStore() const page = ref(0) const size = ref(10) const status = ref('ON_SALE') const loading = ref(false) // 加载商品列表 const loadCommodities = async () => { loading.value = true try { const res = await request.get('/commodities', { params: { page: page.value, size: size.value, status: status.value } }) store.setCommodities(res.data.content) // 存入 Pinia store store.setTotalPages(res.data.totalPages) } catch (err) { console.error('加载商品失败:', err) } finally { loading.value = false } } onMounted(() => { loadCommodities() }) </script> <template> <div class="container"> <h2>在售商品</h2> <div class="filter-bar"> <select v-model="status" @change="loadCommodities"> <option value="ON_SALE">在售</option> <option value="SOLD_OUT">已售出</option> </select> </div> <div v-if="loading" class="loading">加载中...</div> <div v-else class="commodity-grid"> <div v-for="item in store.commodities" :key="item.id" class="commodity-card"> <img :src="item.imageUrl || '/placeholder.jpg'" alt="商品图" /> <h3>{{ item.title }}</h3> <p class="price">¥{{ item.price }}</p> <p class="desc">{{ item.description.substring(0, 50) }}...</p> </div> </div> </div> </template>
3.2.1 Pinia Store 封装商品状态:解耦组件逻辑

src/stores/commodity.js定义全局商品状态,避免父子组件 props 层层传递:

import { defineStore } from 'pinia' export const useCommodityStore = defineStore('commodity', { state: () => ({ commodities: [], totalPages: 0 }), actions: { setCommodities(list) { this.commodities = list }, setTotalPages(total) { this.totalPages = total } } })

提示:Vue.js3 的ref响应式变量在模板中无需.value,但 JS 逻辑中必须加。Pinia 的state是 reactive 对象,直接赋值即可触发更新。这种组合让代码既符合 Vue3 最佳实践,又便于答辩时讲解「为什么不用 Vuex」——Pinia 更轻量、TypeScript 支持更好、API 更简洁。

4. 前后端联调与关键功能实现:图片上传、JWT 登录、权限控制

4.1 实现学生头像与商品图片上传:SpringBoot3 文件接收与 Vue3 FormData 构建

跳蚤市场强依赖图片,但 SpringBoot3 默认限制单文件大小为 1MB。需在application.yml中放宽:

# src/main/resources/application.yml spring: servlet: context-path: /api web: resources: static-locations: classpath:/static/ # 文件上传配置 servlet: multipart: max-file-size: 5MB max-request-size: 10MB

后端 Controller 接收 MultipartFile:

// src/main/java/com/example/flea/controller/FileController.java @RestController @RequestMapping("/api/files") public class FileController { private static final String UPLOAD_DIR = "uploads/"; @PostMapping("/avatar") public ResponseEntity<Map<String, String>> uploadAvatar( @RequestParam("file") MultipartFile file, @RequestParam("userId") Long userId) { try { String originalFilename = file.getOriginalFilename(); String extension = FilenameUtils.getExtension(originalFilename); String filename = userId + "_avatar." + extension; Path uploadPath = Paths.get(UPLOAD_DIR, "avatar"); Files.createDirectories(uploadPath); Path targetLocation = uploadPath.resolve(filename); file.transferTo(targetLocation); String url = "/upload/avatar/" + filename; Map<String, String> result = Map.of("url", url); return ResponseEntity.ok(result); } catch (Exception e) { return ResponseEntity.badRequest().build(); } } }

Vue3 前端调用(注意FormData的 key 名必须与后端@RequestParam一致):

// src/composables/useUpload.js import { ref } from 'vue' import request from '@/utils/request.js' export function useUpload() { const uploading = ref(false) const uploadAvatar = async (file, userId) => { uploading.value = true const formData = new FormData() formData.append('file', file) // key 必须是 'file' formData.append('userId', userId) // key 必须是 'userId' try { const res = await request.post('/files/avatar', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) return res.data.url } finally { uploading.value = false } } return { uploading, uploadAvatar } }

注意:Vue3 中FormDataappend方法第二个参数是File对象(来自<input type="file">event.target.files[0]),不是 base64 字符串。若传错类型,后端MultipartFile会为空,返回 400 错误。

4.2 基于 JWT 的登录鉴权:SpringBoot3 Security 配置要点

毕业设计不必实现 OAuth2 复杂流程,JWT 足够。添加依赖:

<!-- pom.xml --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.12.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.12.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.12.5</version> <scope>runtime</scope> </dependency>

Security 配置类(精简版,仅放行/api/login和静态资源):

@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) // 毕业设计可关,但需向评委说明原因 .authorizeHttpRequests(authz -> authz .requestMatchers("/api/login", "/api/files/**", "/h2-console/**").permitAll() .requestMatchers("/api/**").authenticated() .anyRequest().permitAll() ) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }

登录接口返回 JWT Token:

@PostMapping("/login") public ResponseEntity<Map<String, String>> login(@RequestBody LoginRequest request) { // 1. 校验用户名密码(此处简化为查学号) User user = userRepository.findByStudentId(request.getStudentId()) .orElseThrow(() -> new BadCredentialsException("学号不存在")); // 2. 生成 JWT(有效期 24 小时) String jwt = Jwts.builder() .subject(user.getStudentId()) .claim("realName", user.getRealName()) .issuedAt(new Date()) .expiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000)) .signWith(SignatureAlgorithm.HS256, "your-secret-key-here") .compact(); Map<String, String> result = Map.of("token", jwt); return ResponseEntity.ok(result); }

Vue3 登录成功后存 token:

// src/views/LoginView.vue const login = async () => { try { const res = await request.post('/login', { studentId, password }) localStorage.setItem('auth_token', res.data.token) router.push('/') } catch (err) { alert('登录失败:' + err.response?.data?.message) } }

4.3 角色权限控制:用枚举 + 拦截器区分学生与管理员

校园跳蚤市场需区分普通学生(只能删自己发布的商品)和管理员(可删任意商品)。SpringBoot3 中不建议用@PreAuthorize注解(需开启 AOP,增加复杂度),改用方法级校验:

// src/main/java/com/example/flea/service/CommodityService.java @Service public class CommodityService { private final CommodityRepository commodityRepository; private final UserRepository userRepository; public CommodityService(CommodityRepository commodityRepository, UserRepository userRepository) { this.commodityRepository = commodityRepository; this.userRepository = userRepository; } // 删除商品:校验 userId 是否匹配 public void deleteCommodity(Long id, Long currentUserId) { Commodity commodity = commodityRepository.findById(id) .orElseThrow(() -> new RuntimeException("商品不存在")); // 普通学生只能删自己的商品 if (!commodity.getUserId().equals(currentUserId)) { // 检查是否为管理员(学号以 'ADMIN_' 开头) User user = userRepository.findById(currentUserId).orElse(null); if (user == null || !user.getStudentId().startsWith("ADMIN_")) { throw new AccessDeniedException("无权限删除此商品"); } } commodity.setStatus(CommodityStatus.DELETED); commodityRepository.save(commodity); } }

前端按钮根据角色显示:

<!-- 商品卡片内 --> <button v-if="item.userId === currentUser.id" @click="deleteSelf(item.id)"> 删除我的商品 </button> <button v-else-if="isAdmin" @click="deleteAny(item.id)"> 管理员删除 </button>

5. 毕业设计交付与答辩技巧:ER 图绘制、部署验证、高频面试题预判

5.1 数据库 ER 图绘制:用 draw.io 导出 PNG 并嵌入论文,标注关键约束

毕业设计论文必须包含 ER 图。不要用 PowerDesigner 等重型工具,推荐在线 draw.io(diagrams.net),理由:免费、导出 PNG 清晰、支持中文、可直接拖拽生成标准 Crow's Foot 符号。核心实体关系如下:

  • t_user(用户表)与t_commodity(商品表):一对多(一个用户发多个商品),连线标注1..*,外键user_idt_commodity中。
  • t_commodityt_order(订单表):一对多(一个商品可被多次购买),但实际是多对多(一个订单含多个商品),需引入关联表t_order_item
  • t_usert_order:一对多(一个用户下多个订单),外键buyer_idseller_id分别指向t_user.id

提示:draw.io 中右键实体 → “Edit Style” → 添加html=1可支持换行;导出时选 “PNG” 格式,分辨率设为2(两倍清晰),插入 Word 论文后尺寸调整为宽度 15 厘米,自动适配 A4 页面。答辩时评委若问“为什么没做商品收藏功能”,可答:“当前 ER 图已覆盖核心交易链路,收藏属于增值功能,可在二期迭代中通过新增t_favorite表实现,符合软件工程渐进式开发原则。”

5.2 本地打包部署验证:SpringBoot3 打 jar 包 + Vue3 build 静态文件

毕业设计需证明“能跑起来”。步骤如下:

  1. 后端打包mvn clean package -DskipTests,生成target/flea-market-0.0.1-SNAPSHOT.jar
  2. 前端构建npm run build,生成dist/目录
  3. 合并部署:将dist/内所有文件复制到 SpringBootsrc/main/resources/static/下(覆盖原 static)
  4. 运行 jar 包java -jar target/flea-market-0.0.1-SNAPSHOT.jar

此时访问http://localhost:8080即打开 Vue 前端,所有 API 自动代理到/api路径。验证点:

  • 打开浏览器开发者工具 → Network 标签 → 切换到Fetch/XHR→ 点击“在售商品”,确认请求 URL 为http://localhost:8080/api/commodities,状态码200
  • 查看 Response Headers →Content-Type: application/json,确认是 JSON 响应而非 HTML

5.3 预判 Java 面试题:从毕业设计代码中提炼 3 个必答技术点

答辩老师常从你的代码出发提问。以下是基于本项目可立即作答的高频题:

面试问题回答要点(结合本项目代码)关键代码位置
SpringBoot3 和 SpringBoot2 的主要区别?重点说 Jakarta EE 迁移:javax.servletjakarta.servlet,所以pom.xmlspring-boot-starter-web依赖隐式引入的是jakarta.servlet-api;另外@ConfigurationProperties默认开启 relaxed binding,server.port可写成server.port=8080server.port: 8080pom.xmlapplication.yml
JPA 中@ManyToOne和外键字段哪种方式更好?在毕业设计规模下,用外键字段(如userId)更可控:避免懒加载 N+1 问题,减少@JsonIgnore配置,序列化 JSON 时字段名清晰("userId": 123而非"user": {"id":123})。若未来扩展需关联查询,再用@ManyToOne(fetch = FetchType.EAGER)Commodity.java第 22 行
Vue3 的refreactive有什么区别?ref用于基本类型(string/number)和单个对象,模板中自动解包({{ count }});reactive用于复杂对象,必须用const { x, y } = toRefs(obj)才能在模板中解包。本项目pageref,Pinia store 用reactive状态HomeView.vue第 5 行、commodity.js第 3 行

最后一步:把flea-market-0.0.1-SNAPSHOT.jarsrc/main/resources/application.yml(脱敏后)打包为毕业设计_跳蚤市场_源码.zip,放在 GitHub 公开仓库(设为私有亦可),README.md 中写清「技术栈、运行步骤、截图」——这比任何 PPT 都更能证明你真的做过。

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

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

机械手PID控制与Simulink仿真:从PD控制到跟踪微分器

简介&#xff1a;面向机械手控制课程设计与毕业设计场景&#xff0c;一套基于Matlab的机械手PID控制源码包&#xff0c;提供了从动力学建模、控制器设计到Simulink仿真验证的完整参考路径。资源主要面向具备一定Matlab基础、需要完成机械手或机器人控制相关作业的高校学生&…

作者头像 李华
网站建设 2026/9/16 14:19:10

C语言课设实操:校园新闻发布管理系统链表设计与文件持久化

简介&#xff1a;基于C语言的校园新闻发布管理系统&#xff0c;是一套面向计算机专业课程设计与毕业设计的完整源码和说明文档。系统围绕新闻采集、编辑、审核、发布与用户评论等功能展开&#xff0c;采用模块化编程&#xff0c;源码由多个C源文件与头文件按功能拆分&#xff0…

作者头像 李华
网站建设 2026/9/16 14:17:19

10. 软件设计架构-分布式-分布式事务

文章目录前言一、分布式事务基础1. 什么是事务2. 本地事务3. 分布式事务4. 分布式事务的场景二、分布式事务解决方案三、二阶段提交1. 概述2. 处理流程3. 问题四、三阶段提交1. 概述2. 处理流程3. 问题五、补偿事务TCC1. 概述2. 工作流程3. 问题六、 通过消息队列实现1. 本地消…

作者头像 李华
网站建设 2026/9/16 14:16:29

GitHub热榜观察指南:从趋势洞察到技术选型实战

作为一个常年泡在 GitHub 上的人&#xff0c;我每天早上打开浏览器的第一件事&#xff0c;基本就是扫一眼 GitHub 热榜——也就是大家常说的 Trending。很多刚接触 GitHub 的朋友会把它当成“今天哪些项目最火”的娱乐榜单&#xff0c;但说实话&#xff0c;刷了这么多年&#x…

作者头像 李华
网站建设 2026/9/16 14:15:20

用Java实现WiFi信号室内定位:RSSI建模、指纹匹配与Android工程实践

简介&#xff1a;这是一套面向计算机相关专业毕业设计或课程设计场景的WiFi信号强度定位工具项目&#xff0c;基于Java开发Android端APK&#xff0c;完整呈现了通过WiFi信号强度实现位置估算的工程实现路径。压缩包共254个文件&#xff0c;以66个Java源码、78个XML配置与布局、…

作者头像 李华