)
1. 項目背景與整體設計思路這個選題我第一眼看到就想拍大腿典型的技術棧好看業(yè)務能落地型畢設題目。Spring Boot做后端接口Android做前端移動端中間再配上MySQL存數(shù)據(jù)一套完整的家教服務平臺就出來了。你說它是管理系統(tǒng)其實本質(zhì)上是一個雙向匹配的在線平臺——家長端找家教、家教端接單子中間夾雜訂單、評價、排課、結算這一條完整的業(yè)務鏈。先聊聊為什么這個題適合做畢業(yè)設計因為它的復雜度剛好卡在能把你和其他人區(qū)分開的位置。你要是只做一個普通的CRUD管理系統(tǒng)老師一眼就能看穿但加上訂單狀態(tài)機、教師等級認證、家長評價體系之后整個系統(tǒng)的業(yè)務完整性立刻不一樣了。而且Spring Boot Android這個組合本身就自帶話題性答辯的時候老師問什么你都能接得上話。再說說場景怎么拆。一個合格的家教平臺至少要覆蓋三類角色管理員、家長、家教老師。家長端要能瀏覽老師列表、按科目篩選、看評分、下單預約家教老師要能上傳資質(zhì)、管理自己的課程時間、接受或拒絕訂單管理員則要負責審核老師資質(zhì)、處理投訴、統(tǒng)計平臺數(shù)據(jù)。這三條線合在一起才是完整的家教管理系統(tǒng)缺了任何一條線都只是半成品。從技術演進的角度看其實現(xiàn)在很多人會糾結要不要用小程序替代Android端我的看法是畢設直接用Android原生就行原因后面工具選型部分詳細說。這里先明確一個共識——做這個項目的核心目標不是真的上線運營而是通過一個完整的全棧項目展示你對前端交互后端接口數(shù)據(jù)庫設計的整合能力。2. 技術選型與核心原理2.1 Spring Boot 3.x MyBatis Plus 的組合邏輯后端我推薦直接用Spring Boot 3.x配合MyBatis Plus這是目前Java系畢設里的主流搭配。Spring Boot負責把整個Web服務的骨架搭起來內(nèi)嵌Tomcat一行代碼都不用配就能跑起來這對時間緊張的畢業(yè)生來說太友好了。MyBatis Plus相比純MyBatis的優(yōu)勢在于單表CRUD根本不用寫SQLBaseMapper里那些insert、selectById、updateById直接拿來用省下來的時間都夠你把訂單狀態(tài)機多寫兩個狀態(tài)了。不過我要提醒一句MyBatis Plus不是萬能藥多表關聯(lián)查詢老老實實自己寫XML里的SQL別硬套它那個Wrapper很多時候查出來的字段對不上會讓你排查到懷疑人生。接口設計上走RESTful風格統(tǒng)一返回Result對象code message dataAndroid端拿到這個結構體再解析協(xié)作效率會高很多。權限認證用JWT登錄成功后頒發(fā)一個有效期為24小時的tokenAndroid端保存到SharedPreferences里每次請求帶上Authorization頭就行。為什么不用SessionAndroid端不像瀏覽器會自動管理Cookie用JWT免去了很多會話同步的麻煩而且天然支持無狀態(tài)擴展這點在答辯的時候可以拿出來說。2.2 Android原生開發(fā)到底選Java還是Kotlin現(xiàn)在去搜Android開發(fā)相關內(nèi)容鋪天蓋地都是Kotlin但我不建議畢設一上來就啃Kotlin除非你之前已經(jīng)用Kotlin寫過項目。原因是大部分學校的Android課程還是用Java教的你需要在短時間內(nèi)同時搞明白Activity生命周期、RecyclerView適配器、網(wǎng)絡請求回調(diào)這幾個硬骨頭沒必要再疊加一門新語言的認知負擔。當然你完全可以最后沖刺階段把代碼重構成Kotlin這屬于錦上添花。但核心邏輯用Java寫完并且能跑通比什么都強。Android端架構上我建議MVP就夠了Activity當View層Presenter負責業(yè)務邏輯Model管數(shù)據(jù)。MVVM也行但LiveData ViewModel這套組合對于畢設來說有點over-engineering你還要處理生命周期綁定的細節(jié)時間不劃算。網(wǎng)絡框架用OkHttp Retrofit。Retrofit的注解式接口定義方式非常適合這種前后端分離的協(xié)作模式后端接口一定義好Android端照著接口文檔寫interface就行自動把JSON解析成Java對象。JSON解析就用Gson簡單直接都是Java系的東西配合格外順暢。2.3 數(shù)據(jù)庫選型和表結構設計的第一性原理MySQL 8.0是標配這沒什么好糾結的。關鍵在于表結構怎么設計——這決定了你的業(yè)務邏輯是清晰還是混亂。我見過太多人做畢設時隨手下兩張表就開始寫代碼結果到后面訂單狀態(tài)一復雜整個系統(tǒng)直接崩盤。一個家教平臺的核心表我建議至少包含這些用戶表user、老師詳情表teacher_info、科目表subject、老師科目關聯(lián)表teacher_subject、訂單表order、排課表course_schedule、評價表review、收藏表favorite、公告表notice。這些表之間的外鍵關系要不要物理外鍵我建議不要邏輯外鍵就夠了。畢業(yè)設計階段物理外鍵的維護成本大于收益而且你答辯時完全可以說生產(chǎn)環(huán)境通常禁用物理外鍵以保證擴展性這反而是加分項。訂單狀態(tài)這塊單獨強調(diào)一下用int類型存狀態(tài)碼0待支付、1待上課、2已上課、3已完成、4已取消、5退款中。不要直接存字符串狀態(tài)碼配合常量類或者枚舉類使用可讀性照樣高而且后續(xù)要統(tǒng)計所有退款訂單這種數(shù)據(jù)的時候?qū)慡QL會舒服很多。3. 后端核心模塊設計與實現(xiàn)3.1 基于JWT的登錄認證與角色權限控制登錄這塊是整個系統(tǒng)的入口做得不好后面全崩。我的方案是登錄接口接收手機號和密碼校驗通過后用JJWT庫生成tokentoken的payload里塞userId和role字段1管理員、2家長、3老師然后返回給客戶端。后續(xù)請求通過攔截器解析token把用戶信息放到ThreadLocal里業(yè)務層隨時能拿到當前操作人。角色權限控制用一個自定義注解RequireRole配合Spring攔截器在handler執(zhí)行前做校驗。比如發(fā)布公告這個接口標注RequireRole(1)家教接單接口標注RequireRole(3)家長下單接口標注RequireRole(2)。代碼看起來是這樣PostMapping(/order/create) RequireRole(2) public ResultString createOrder(RequestBody OrderCreateRequest request) { // 業(yè)務邏輯... }攔截器里先解析token再檢查當前用戶角色是否匹配注解要求不匹配直接返回403。另外密碼存儲必須用BCrypt加密spring-security-crypto這個依賴單獨拎出來用就行不需要引入整套Spring Security。BCrypt有個特點每次加密同一個密碼得到的密文都不一樣因為內(nèi)部帶了隨機鹽這比MD5那種固定哈希值安全一個數(shù)量級。3.2 家教檢索的核心算法與實現(xiàn)家長端最核心的功能就是搜索家教這決定了平臺的使用體驗。我的實現(xiàn)邏輯是按科目id 區(qū)域 價格區(qū)間 綜合評分做組合篩選分頁返回教師列表。綜合評分的計算是(科目匹配分數(shù)×0.4 教齡分數(shù)×0.2 評價分數(shù)×0.4)每個維度都歸一化到0-5分用這個算出來的分數(shù)做排序。這個算法的關鍵在于打分的規(guī)則要講得清楚答辯的時候這是重點展示環(huán)節(jié)。你在代碼里封裝一個ScoreCalculator類從teacher_subject表里取科目匹配度從teacher_info里取教齡從review表里AVG出評價分然后按權重加總。排序整合在SQL里做也行但如果在Java層計算你就必須注意N1查詢的問題——每個老師都要查一次評價表的話10個老師就是11次查詢。我當時是先把教師列表一次性查出再按id批量查相關數(shù)據(jù)內(nèi)存里做匹配性能至少快3倍。3.3 訂單狀態(tài)機與排課沖突校驗訂單是整個平臺的主線我用一個簡單的狀態(tài)機來管理待支付0→ 待上課1→ 已完成2待支付超過30分鐘自動取消家長可以主動取消待支付和待上課狀態(tài)的訂單上課完成后雙方確認訂單進入已完成狀態(tài)此時家長才能評價。每次創(chuàng)建訂單前必須要做排課沖突校驗這是很多粗制濫造系統(tǒng)會漏掉的地方。校驗邏輯是查詢老師在該時間段開始時間到結束時間是否存在時間重疊的已接訂單或已排課記錄存在一律拒絕創(chuàng)建訂單。SQL這樣寫SELECT COUNT(*) FROM order WHERE teacher_id #{teacherId} AND status IN (1, 2) AND #{endTime} start_time AND #{startTime} end_time這個重疊判斷條件很經(jīng)典兩個區(qū)間[a,b]和[c,d]存在交集只要滿足c b且a d即可。我在第一次實現(xiàn)時寫成了start_time BETWEEN #{startTime} AND #{endTime}結果漏掉了訂單完全包含已有排課的情況后來才發(fā)現(xiàn)這種寫法只覆蓋了一部分重疊場景。改成交集條件后各種邊界情況全部覆蓋了。3.4 評價系統(tǒng)與教師評分動態(tài)更新評價表的設計要精細一點id、order_id一個訂單只能評價一次所以這個字段加唯一索引、rating1-5分、content、create_time。家長提交評價后transaction里要同時做兩件事插入評價記錄、更新老師的綜合評分。評分字段放在teacher_info表里冗余存儲這樣列表頁展示老師評分就只需要查教師表不需要每次都聚合review表。但這里有個體驗細節(jié)容易忽略評價必須要在訂單完成后7天內(nèi)提交超過時間就鎖定不能再評。這個限制一方面防止惡意刷評價另一方面也督促家長及時反饋。在代碼上就用一個update語句配合時間條件來控制寫起來很輕量。4. Android端核心模塊與實現(xiàn)4.1 項目架構與Navigation底部導航設計Android端我遵循單Activity多Fragment的設計主界面一個MainActivity底部三個Tab首頁找家教、訂單我的訂單、我的個人中心。Fragment之間的切換用FragmentManager FragmentTransaction不需要引入Navigation組件——那個對畢設來說配置太繁瑣而且你現(xiàn)在不熟的話踩坑成本太高。底部導航欄用BottomNavigationView菜單資源里定義三個item每個item對應一個Fragment的tag切換時show/hide而不是replace。為什么這么做因為replace每次都會重新走一遍Fragment的生命周期導致網(wǎng)絡請求重新執(zhí)行用戶翻個Tab回來數(shù)據(jù)全部刷新一遍體驗非常差。show/hide的方式能保留Fragment的狀態(tài)實測滑動列表位置不會被重置。4.2 Retrofit網(wǎng)絡層封裝與響應統(tǒng)一解析Android端網(wǎng)絡層是整個項目最容易寫亂的地方。我的做法是定義ApiService接口用注解聲明后端所有接口然后用Retrofit.Builder創(chuàng)建實例配合GsonConverterFactory做JSON轉(zhuǎn)換。統(tǒng)一的響應體Result 在Android端也用對應結構體映射解析完判斷code是否為200不是就直接toast提示后端返回的消息。網(wǎng)絡請求的異步處理用Retrofit的Callback機制就好不要因為圖新鮮去引入RxJava。那會讓數(shù)據(jù)流變得復雜而且你如果之前沒接觸過響應式編程光理解Observable和Observer的關系都要花不少時間。Callback雖然寫起來顯得啰嗦但邏輯清晰——onResponse處理成功、onFailure處理失敗很適合這個項目。兩三年前我?guī)腿伺挪檫^一個bug用戶上傳頭像后圖片一直沒顯示查了半天發(fā)現(xiàn)是Android 10對文件訪問權限收緊直接用file://協(xié)議打開相冊選中的URI會崩潰。解決方案是用ContentResolver把URI拷貝到應用私有目錄再交給Glide加載。這個坑新手必踩畢設里做頭像上傳功能時一定要提前處理。4.3 教師列表展示與篩選交互設計教師列表頁用RecyclerView CardView的組合每個item展示老師的頭像、昵稱、主教科目、教齡、綜合評分和價格。篩選條件用BottomSheetDialog彈出面板里面放科目、區(qū)域、價格范圍等選項點擊確定后重新請求列表接口。滑動加載更多用RecyclerView的OnScrollListener實現(xiàn)監(jiān)聽最后一個可見item的位置是否接近總數(shù)是就加載下一頁。這里有個細節(jié)需要加一個isLoading標志位防止重復請求否則用戶快速滑動時可能同時觸發(fā)多次分頁請求數(shù)據(jù)順序就亂套了。每頁我設20條一屏剛好放5個卡片滑動兩三屏才觸發(fā)一次加載交互節(jié)奏剛剛好。5. 數(shù)據(jù)庫設計實戰(zhàn)與核心建表語句5.1 核心表結構全解析把完整的建表SQL都貼出來不現(xiàn)實挑幾張核心表說。用戶表是最基礎的字段包括id、phone、password、role、nickname、avatar、status、create_time。這里phone要加唯一索引platform登錄直接綁定手機號不搞郵箱注冊那套復雜流程。訂單表的字段設計直接決定業(yè)務邏輯好不好寫CREATE TABLE order ( id bigint(20) NOT NULL AUTO_INCREMENT, order_no varchar(32) NOT NULL COMMENT 訂單編號, parent_id bigint(20) NOT NULL COMMENT 家長用戶ID, teacher_id bigint(20) NOT NULL COMMENT 老師用戶ID, subject_id bigint(20) NOT NULL COMMENT 科目ID, start_time datetime NOT NULL COMMENT 上課開始時間, end_time datetime NOT NULL COMMENT 上課結束時間, price decimal(10,2) NOT NULL COMMENT 訂單金額, status int(11) NOT NULL DEFAULT 0 COMMENT 訂單狀態(tài), create_time datetime NOT NULL, update_time datetime NOT NULL, PRIMARY KEY (id), KEY idx_teacher_time (teacher_id,start_time,end_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;order_no用yyyyMMddHHmmss 3位隨機數(shù)生成這是最簡單不會重復的方式。索引設計上聯(lián)合索引teacher_id, start_time, end_time能極大加快排課沖突校驗的查詢速度這個索引在真實場景中就是量級上的性能差異。5.2 一對多與多對多關系的處理策略教師和科目之間是多對多關系需要一張關聯(lián)表teacher_subject來維系字段就三個id、teacher_id、subject_id??颇勘肀旧碓谙到y(tǒng)里基本就是一個靜態(tài)字典數(shù)學、英語、物理、化學、語文、生物、歷史、地理、政治、鋼琴、繪畫、編程。畢設階段直接在SQL初始化腳本里INSERT進去就行不用專門做科目管理功能。老師詳情表teacher_info和用戶表是一對一關系存放老師專屬的信息教齡、學歷、學校/機構、教學風格、每小時價格、可教區(qū)域等。為什么不分一張表全塞進user里因為家長端的用戶根本不需要這些屬性分表后邏輯更清晰而且這也能向老師展示你掌握了垂直分表的設計思路。6. 核心業(yè)務流程與代碼實現(xiàn)6.1 下單流程的完整時序下單是整個系統(tǒng)里橫跨前后端最多的業(yè)務建議先從時序?qū)用胬砬宄议L在教師詳情頁點擊預約試聽→ 選擇上課時間和時長 → 后端校驗老師是否空閑 → 創(chuàng)建訂單狀態(tài)為待支付→ 家長確認支付 → 模擬支付成功回調(diào) → 訂單狀態(tài)變?yōu)榇险n??紤]到畢設沒辦法接真實支付渠道我用的方案是做一個模擬支付頁面點擊確認支付后直接跳轉(zhuǎn)一個模擬支付成功的回調(diào)接口接口把訂單狀態(tài)更新為待上課。這個方案雖然是模擬的但業(yè)務閉環(huán)是完整的答辯時說明實際生產(chǎn)可替換為微信/支付寶官方SDK就夠了。6.2 接口定義與Android端調(diào)用對齊前后端接口對齊的關鍵在字段命名。后端返回的JSON字段統(tǒng)一用駝峰命名法和Java屬性保持一致這樣Gson解析時不需要額外寫SerializedName注解。日期格式統(tǒng)一為yyyy-MM-dd HH:mm:ss直接作為字符串傳輸Android端用SimpleDateFormat解析出Date對象再格式化展示。我列幾個核心接口路徑POST /api/auth/login登錄、GET /api/teacher/list教師列表、GET /api/teacher/detail/{id}教師詳情、POST /api/order/create創(chuàng)建訂單、GET /api/order/my我的訂單、POST /api/review/submit提交評價。這些接口路徑在設計階段就要定好寫進接口文檔里前后端各自照著文檔開發(fā)能少吵很多架。6.3 教師端接單與日程管理老師端的核心場景是接單和排課。在我的日程頁面老師可以看到自己所有時間段的排課情況支持手動添加和刪除排課。排課數(shù)據(jù)存在course_schedule表里字段包含teacher_id、start_time、end_time、type1空閑、2已預約、3不可約。對老師來說這條時間軸就是他的可售賣資源。比較有意思的是推薦算法在這里的應用當家長瀏覽教師列表時我調(diào)了一個活躍推薦排序因子近期有排課活動的老師權重升高。這個功能看著不起眼但能體現(xiàn)你對業(yè)務的理解深度——平臺需要鼓勵老師保持活躍而不是注冊完就消失。7. 前端關鍵頁面與交互實現(xiàn)7.1 教師詳情頁的信息層級設計教師詳情頁直接決定家長會不會下單。我按這樣的信息層級排布最頂部是大圖頭像和名字下面一排展示教齡、學歷、評分三個標簽再往下是ta的可教科目和價格區(qū)間繼續(xù)往下是個人介紹和教學風格最后是評價列表。整個頁面用NestedScrollView包裹評價列表嵌套RecyclerView時要注意設置setNestedScrollingEnabled(false)否則會出現(xiàn)滑動沖突。頁面底部固定一個預約試聽按鈕顏色用平臺主色點擊后彈BottomSheetDialog選擇上課時間。這個按鈕要一直懸浮在頁面底部用戶瀏覽完所有信息后最自然的動作就是點擊它。7.2 下拉刷新和加載狀態(tài)的細節(jié)處理頁面加載狀態(tài)我用三種視圖管理加載中顯示居中ProgressBar加載失敗顯示帶重試按鈕的提示視圖加載成功顯示內(nèi)容。用ViewStub按需inflate這三種狀態(tài)視圖比動態(tài)addView效率更高也避免了視圖層級過深的問題。下拉刷新用SwipeRefreshLayout在onRefresh回調(diào)里重新請求第一頁數(shù)據(jù)請求完成后調(diào)用setRefreshing(false)結束動畫。這里有個很多人會忽略的坑如果刷新請求失敗一定要結束刷新動畫否則用戶會看到轉(zhuǎn)圈圈停不下來的詭異狀態(tài)。正確做法是在finally代碼塊里調(diào)用setRefreshing(false)。8. 系統(tǒng)優(yōu)化點與進階提升方向8.1 服務端性能優(yōu)化三板斧畢設如果能展示出性能優(yōu)化意識答辯老師通常會高看一眼。我做了三件事第一教師列表接口開啟了Spring Cache緩存key為teacherList:page:{page}:size:{size}緩存過期時間60秒有效降低數(shù)據(jù)庫壓力第二熱門科目和評價數(shù)據(jù)用Redis緩存你就算只寫幾行RedisTemplate的get/set代碼也足夠展示你對緩存技術的理解第三SQL層面盡量覆蓋索引避免在查詢條件中使用函數(shù)導致索引失效。這里說個實際的緩存一致性經(jīng)驗我在寫評價和更新教師評分的事務里手動刪除對應教師的緩存key這樣下次請求時就能拿到最新的評分數(shù)據(jù)。這種寫操作刪緩存的玩法雖然是Cache Aside Pattern的基礎操作但在畢設里能自己悟出來并寫出來說明你確實理解了緩存的核心邏輯。8.2 Android端體驗優(yōu)化細節(jié)Android端可以做很多小而美的優(yōu)化圖片加載用Glide配置占位圖和錯誤圖列表頁的item布局用ConstraintLayout減少布局嵌套層級提升渲染速度大列表加setHasFixedSize(true)告訴RecyclerView尺寸不變跳過重新測量布局的過程。另外建議在項目里加一個BaseActivity和BaseFragment把網(wǎng)絡請求的Loading對話框和錯誤Toast統(tǒng)一封裝。這樣每個頁面的代碼會清爽很多而且這種框架思維是導師喜歡的風格。8.3 功能擴展的想象空間做完全部功能后可以想想還有哪些地方能擴展增加消息推送功能的話可以用WebSocket實現(xiàn)站內(nèi)聊天增加后臺數(shù)據(jù)分析的話可以在管理員端加訂單統(tǒng)計報表按天/周/月維度展示GMV增長曲線增加推薦系統(tǒng)的話可以基于用戶行為記錄做猜你喜歡的教師推薦。這些擴展方向在論文的未來展望章節(jié)里寫出來既能體現(xiàn)你思考的深度又不會給自己增加實際工作量。我當年就是這么干的老師看完后特意在答辯時問了一圈擴展方案的技術實現(xiàn)思路。9. 常見問題與排查技巧實錄9.1 跨域問題與Android請求失敗的區(qū)分前后端聯(lián)調(diào)時最容易碰到的就是請求失敗。如果你用瀏覽器調(diào)試接口發(fā)現(xiàn)一切正常但Android端請求總是走onFailure大概率是網(wǎng)絡請求被拒絕。排查方法先在AndroidManifest.xml確認加了INTERNET權限——這個問題出現(xiàn)頻率高到令人發(fā)指再看是不是用了http明文請求Android 9.0之后默認禁止明文流量需要在manifest里配置usesCleartextTraffictrue或者在networkSecurityConfig里配置域名白名單。如果你是后端接口在瀏覽器里直接訪問出現(xiàn)跨域報錯記得加一個CorsFilter或者用CrossOrigin注解解決。這在前后端分離項目里是必踩的坑提前處理能省一晚上時間。9.2 時間參數(shù)時區(qū)和格式不一致問題Java后端默認的日期解析格式是ISO標準的yyyy-MM-ddTHH:mm:ss.SSSZ但前端傳來的可能是yyyy-MM-dd HH:mm:ss直接用RequestBody接收會導致解析失敗。解決方案是用JsonFormat注解標注時間字段的格式同時指定timezone為GMT8避免時區(qū)偏移導致時間差8小時的問題。這個坑我第一次做項目時踩過排查了整整一個晚上最后發(fā)現(xiàn)是Jackson反序列化默認不帶解析自定義格式導致的。后來我在所有LocalDateTime字段上都加了JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)從此再沒為時間格式頭疼過。9.3 Android內(nèi)存泄漏的幾個典型場景Android端的內(nèi)存泄漏問題可以從源頭避免Activity里持有靜態(tài)Context引用、Handler匿名內(nèi)部類持有Activity引用、網(wǎng)絡請求回調(diào)在Activity銷毀后仍然執(zhí)行、Bitmap沒有及時回收。我的建議是網(wǎng)絡請求用ApplicationContext起步回調(diào)回來后判斷Activity是否已經(jīng)isFinishing是就直接return不再更新UI。實際項目里我用IntentService處理頭像上傳的任務這樣Activity銷毀了任務也能繼續(xù)執(zhí)行上傳完成后再通過EventBus通知刷新。雖然EventBus現(xiàn)在有點被嫌棄但畢設里用起來非常順手而且這套模式在真實項目中也很常見。10. 部署發(fā)布與環(huán)境配置經(jīng)驗10.1 后端打包部署的完整流程后端部署我用的是阿里云的一臺2核4G的輕量應用服務器操作系統(tǒng)Ubuntu 22.04安裝JDK 17和MySQL 8.0。打包時用mvn clean package -DskipTests生成jar包通過scp命令傳到服務器 /home/app 目錄下用nohup java -jar xxx.jar app.log 21 啟動。生產(chǎn)環(huán)境和本地環(huán)境用不同的application-xxx.yml配置文件通過啟動參數(shù)--spring.profiles.activeprod指定。數(shù)據(jù)庫連接、Redis地址這些敏感配置不要寫死在代碼里通過環(huán)境變量注入。這樣代碼倉庫里的配置都是脫敏的安全習慣從畢設就開始養(yǎng)成。10.2 Android簽名打包與真機調(diào)試Android端調(diào)試時強烈建議直接連真機調(diào)試不要用模擬器。模擬器雖然看起來方便但冷啟動慢、GPS模擬麻煩、相機權限需要額外配置這些限制都會影響家教App這種真實業(yè)務App的調(diào)試體驗。我用的是小米手機開USB調(diào)試Android Studio直接識別設備一鍵run到手機上看到效果的速度比模擬器快三倍。正式簽名打包時在build.gradle里配置好簽名證書生成release APK放到服務器上提供下載。這里有個加分項可以做一張二維碼用Android的Scan QR Code功能掃碼下載安裝包演示的時候非常炫酷而且讓老師感覺到這個系統(tǒng)真的是可交付的。11. 項目答辯指南與亮點包裝11.1 演示流程圖與核心賣點提煉答辯演示的時候按這條主線講故事從家長搜索家教開始 → 查看老師詳情和評價 → 選擇時段預約試聽 → 支付創(chuàng)建訂單 → 老師端確認接單 → 排課日程更新 → 上課完成后評價 → 評分動態(tài)更新到列表頁。這條鏈路一氣呵成能向老師展示整個系統(tǒng)的完整度和業(yè)務閉環(huán)。核心賣點提煉三個詞全棧前端Android后端Spring Boot數(shù)據(jù)庫MySQL、閉環(huán)訂單狀態(tài)從創(chuàng)建到完成全流程管理、體驗教師篩選、評分算法、排課沖突校驗這些功能細節(jié)。這三個詞在匯報開場就拋出來定好基調(diào)后面演示的時候不斷呼應。11.2 常見答辯問題應對策略老師最愛問的問題基本集中在幾個方向為什么選這個技術棧訂單狀態(tài)是怎么管理的并發(fā)場景下有沒有考慮超賣問題你作為畢設項目怎么防止一個老師的同一時間段被多個家長同時預約超賣問題這個值得提前做準備。我在下單接口里用數(shù)據(jù)庫層面的條件更新來保證原子性UPDATE teacher_schedule SET status 2 WHERE id #{id} AND status 1如果返回影響行數(shù)為0說明已經(jīng)被搶了這一點在并發(fā)場景下能保證不會出現(xiàn)同一位老師同一時段被兩個人約走的情況。把這條SQL的邏輯在答辯時講出來老師就能看出來你確實思考過并發(fā)問題。還有老師會問JWT和傳統(tǒng)Session有什么區(qū)別為什么不用OAuth2.0你的回答思路是JWT無狀態(tài)適合移動端和分布式場景OAuth2.0更適合開放平臺給第三方授權登錄的場景我們這個系統(tǒng)自己管理用戶體系JWT方案更簡潔高效。最后再說說做這個項目我個人的心態(tài)變化。剛開始寫訂單模塊的時候我以為最難的是Android界面怎么畫得好看但真正做下來才發(fā)現(xiàn)數(shù)據(jù)庫表怎么設計、接口怎么定義、狀態(tài)怎么流轉(zhuǎn)才是核心難點。前端界面反而是在后端邏輯理清楚之后水到渠成的事情。所以如果你也在準備做一個類似的系統(tǒng)我真心建議你先花三天時間把表結構和接口設計文檔寫透再動手寫代碼。你會發(fā)現(xiàn)后面的開發(fā)速度快到超乎想象而且這種先設計再編碼的做事習慣到實際工作中比掌握某個具體框架值錢得多。