写点什么

【精华 +1】HarmonyOS 官方模板优秀案例 (第 3 期:教育行业· 教育备考)

  • 2025-08-20
    北京
  • 本文字数:10555 字

    阅读完需:约 35 分钟

🚀🚀🚀🚀

鸿蒙生态为开发者提供海量的 HarmonyOS 模板/组件,助力开发效率原地起飞

★一键直达生态市场组件&模板市场 , 快速应用DevEco Studio插件市场集成组件&模板 ★

前两期案例介绍了便捷生活新闻行业,大家是不是意犹未尽?

第三期-教育行业的案例加急发布啦!

👉覆盖 20+行业,本帖下方以汇总形式持续更新中,点击收藏!一键三连!常看常新!

 

【第 3 期】教育行业· 教育备考

一、 概述

1. 行业洞察

1) 行业诉求:

  • 精准分发:面对不同的受众教育类应用有不同的业务场景,产出适配内容、精准题库等,并以高效且契合场景的方式进行分发,最终实现优质教育资源的有效传递。

  • 高效流畅、操作敏捷是教育类应用不同场景重要诉求,在线学习、考试等场景出现卡顿会严重影响学习、考试的。

  • 需具备智能刷题与精准辅导能力:基于大数据和算法,依据答题情况判断用户知识掌握状况,动态调整出题难度,推送契合的学习内容。

  • 多端协同能力:实现手机、平板、PC 端数据实时互通,提供离线功能,便于用户利用碎片化时间用于刷题或知识点复习,并可在线后同步学习进度。


2) 行业常用三方 SDK

说明:“以上三方库及链接仅为示例,三方库由三方开发者独立提供,以其官方内容为准”

SDK 链接:

腾讯浏览服务SDK 高德定位SDK 百度地图SDK 极光Push SDK 火山引擎SDK 同盾SDK 友盟SDK 微信支付 SDK 支付宝 SDK 听云SDK 福昕 PDF SDK 网易云信 IM SDK 保利威视频直播webSDK 支付宝分享SDK

 

2. 行业案例概览(下载模板

基于以上行业分析,本期将介绍鸿蒙生态市场教育行业模板——教育备考应用模板,为行业提供常用功能的开发案例,模板主要分练习、课程和我的三大模块。

  • Stage 开发模型 + 声明式 UI 开发范式。

  • 分层架构设计+ 组件化拆分,支持开发者在开发时既可以选择完整使用模板,也可以根据需求单独选用其中的业务组件。

  • 本模板已集成华为账号服务,只需做少量配置和定制即可快速实现华为账号的登录等功能。


 

本模板主要页面及核心功能如下所示:

​题库模板 |-- 开屏页 |-- 练习 |    |-- banner |    |-- 搜索 |    └-- 答题练习 |-- 课程 |    |-- 分类列表 |    |-- 精选课程 |    |    |-- 课程详情 |    |    └-- 支付购买 |    └-- 已购我的课程 |         |-- 练习模式 |         |-- 考试模式 |         |-- 错题记录 |         └-- 收藏记录 |         └-- 笔记记录 └-- 我的      |-- 用户信息      |    |-- 登录      |    |-- 用户信息      |-- 我的订单      |-- 我的错题      |-- 我的收藏      |-- 练习记录      |-- 浏览记录      └-- 设置           |-- 个人信息           |-- 意见反馈           |-- 反馈记录           |-- 隐私协议           |-- 清除缓存           └-- 退出登录
复制代码

 

二、 应用架构设计

1. 分层模块化设计

  • 产品定制层:专注于满足不同设备或使用场景的个性化需求,作为应用的入口,是用户直接互动的界面。

① 本实践暂时只支持直板机,为单 HAP 包形式,包含路由根节点、底部导航栏等。

  • 基础特性层:用于存放相对独立的功能 UI 和业务逻辑实现。

① 本实践的基础特性层将应用功能拆分成 6 个相对独立的业务功能模块。

② 每个功能模块都具备高内聚、低耦合、可定制的特点,支持产品的灵活部署。

  • 公共能力层:存放公共能力,包括公共 UI 组件、数据管理、外部交互和工具库等共享功能。

① 本实践的公共能力层分为公共基础能力和行业组件,均打包为 HAR 包被基础特性层的业务模块引用。

② 公共基础能力包含账号管理、动态布局等工具,公共类型定义,网络库,以及弹窗、加载等公共组件。

③ 行业组件将包含行业特点、可完全自闭环的能力抽出独立的组件模块,支持开发者在开发中单独集成使用,详见业务组件设计章节。

 2. 业务组件设计

为支持开发者单独获取特定场景的页面和功能,本模板将功能完全自闭环的部分能力抽离出独立的行业组件模块,不依赖公共基础能力包,开发者可以单独集成,开箱即用,降低使用难度。


三、 行业场景技术方案

1. 一键搜题

1) 场景说明

用户可在首页-搜题进入一键搜题页面,可输入、语音输入,拍照识别,粘贴和清除功能。

2) 技术方案

  • 语音输入

① 根据语音识别可实现功能。

  • 拍照识别

① 根据拍照可实现拍照功能,

② 图片获取后参考recognizeText获取具体结果。


3) 代码参考

  • 部分核心代码参见搜题组件实现章节。


2. 多级分栏

1) 场景说明

  • 用户可通过首页右上角的按钮拉起多级选择界面,可进行多级别职称的选择。



2) 技术方案

采用左右两个List做为基础组件来实现业务,三级、多级目录采用数据源刷新特性实现具体业务。


3. 答题

1) 场景说明

用户可通过首页点击每日一练可进入答题练习页面,可添加笔记、收藏、答题等相关业务,答题这块只做了单选业务。


 

2) 技术方案

 

四、 模板代码

1. 工程结构(下载模板

详细代码结构如下所示:

Exam  ├─commons/commonLib/src/main  │  ├─ets  │  │  ├─components  │  │  │      CommonHeader.ets                 // 一级页面标题组件  │  │  │      TopBar.ets                       // 标题菜单内容组件  │  │  ├─utils  │  │  │      Logger.ets                       // 日志  │  │  │      PreferenceUtil.ets               // 首选项  │  │  ├─viewModel  │  │  │      BrowsingHistoryModel.ets         // 记录模块数据模型  │  │  │      OrderInfo.ets                    // 订单数据模型  │  │  │      PracticeRecordModel.ets          // 练习数据模型  │  └─resources  ├─commons/router_module/src/main  │  ├─ets  │  │  ├─routerModule  │  │  │  │    RouterModule.ets                // 路由  │  │  │  │  ├─constants  │  │  │  │  │  │ RouterMap.ets                // 路由Key  │  └─resources    │─components/aggregated_payment/src/main     │  ├─ets  │  │  ├─common  │  │  │      Constant.ets                     // 常量类  │  │  ├─components  │  │  │      AggregatedPaymentPicker.ets      // 支付组件  │  │  ├─model  │  │  │      Index.ets                        // 数据类型  │  │  │      WXApiWrap.ets                    // 微信支付数据类型  │  │  └─viewmodel  │  │         AggregatedPaymentVM.ets          // 支付组件数据模型  │  └─resources  │─components/answer_questions/src/main     │  ├─ets  │  │  ├─components  │  │  │      AnswerQuestionsPage.ets           // 答题组件  │  │  │      AddNotePage.ets                   // 添加笔记组件  │  │  │      AnswerSheetPage.ets               // 答题卡组件  │  │  ├─dialog  │  │  │      AddNoteDialog.ets                 // 添加笔记弹框  │  │  │      AnswerSheetDialog.ets             // 答题卡弹框  │  │  └─viewModel  │  │         TopicItemModel.ets                // 答题选项模型  │  │         TopicPageModel.ets                // 答题模型  │  └─resources  │─components/feed_back/src/main     │  ├─ets  │  │  ├─components  │  │  │      Feedback.ets                      // 意见反馈功能组件  │  │  ├─model  │  │  │      FeedbackRecordModel.ets           // 数据类型  │  │  ├─utils  │  │  │      FileSelect.ets                    // 意见反馈功工具类  │  └─resources  │─components/select_category/src/main     │  ├─ets  │  │  ├─components  │  │  │      MainPage.ets                      // 二级分类组件  │  │  │      ThirdcatePage.ets                 // 三级分类组件  │  │  ├─model  │  │  │      SelectCateModel.ets               // 数据类型       │  └─resources  │─components/login_info/src/main     │  ├─ets  │  │  ├─components  │  │  │      AgreementDialog.ets               // 同意协议弹窗组件  │  │  │      QuickLogin.ets                    // 一键登录组件  │  │  ├─model  │  │  │      ErrorCode.ets                     // 错误码类型  │  │  │      UserInfo.ets                      // 用户类型  │  │  └─utils  │  │         AccountUtil.ets                   // 账户工具类  │  └─resources  │─components/search/src/main     │  ├─ets  │  │  ├─components  │  │  │      SearchPage.ets                    // 搜索组件  │  └─resources  │─components/search_question/src/main     │  ├─ets  │  │  ├─components  │  │  │      SearchQuestionPage.ets            // 一键搜题组件  │  └─resources  │─components/base_select/src/main     │  ├─ets  │  │  ├─components  │  │  │      MainPage.ets                      // 基础通用组件  │  │  ├─model  │  │  │      SelectModel.ets                   // 选项数据模型  │  └─resources    │─features/homePage/src/main     │  ├─ets  │  │  ├─components                             // 封装组件  │  │  │      CourseBookComponent.ets           // 资料卡片组件          │  │  │      CourseComponent.ets               // 课程卡片        │  │  ├─model  │  │  │     ChapterPractice.ets                // 分类页面数据模型  │  │  │     CommonTopic.ets                    // 分类数据模型  │  │  │     Course.ets                         // 课程数据模型    │  │  │     CourseArray.ets                    // 课程数组模型  │  │  │     CourseBook.ets                     // 资料模型  │  │  │     CourseQuestions.ets                // 科目数据模型  │  │  │     PracticeMode.ets                   // 业务类型数据模型    │  │  │     TopicItemModel.ets                 // 答题类型数据模型    │  │  │     TopicModel.ets                     // 分类数据源    │  │  ├─pages  │  │  │      ChapterPractice.ets               // 科目页面  │  │  │      FeaturedCourses.ets               // 精选课程页面  │  │  │      MainPage.ets                      // 练习首页面  │  │  │      MaterialDownload.ets              // 资料页面  │  │  │      SearchIndexPage.ets               // 搜索页面  │  │  │      SearchInputPage.ets               // 搜索输入框页面    │  │  │      SecondListPage.ets                // 2级分类  │  │  │      ThirdListPage.ets                 // 3级分类  │  │  │      TopicHomePage.ets                 // 1级分类    │  │  │  └─resources  │─features/topicPage/src/main     │  ├─ets  │  │  ├─views  │  │  │      AnswerQuestionsPage.ets           // 答题模式一页面  │  │  │      AnswerQuestionsTwoPage.ets        // 答题模式二页面  │  │  │      CourseHomePage.ets                // 课程页面  │  │  │      CourseIntroductionPage.ets        // 课程详情页面  │  │  │      ExamResultPage.ets                // 答题结果页面  │  │  │      GoodCourseDetailPage.ets          // 精选课程页面  │  │  │      MockTestPage.ets                  // 科目练习页面  │  │  │      MyCollectionPage.ets              // 收藏页面  │  │  │      MyNotesPage.ets                   // 笔记页面  │  │  │      MyWrongPage.ets                   // 错题页面  │  │  │      TestReportPage.ets                // 测试报告页面  │  │  │      ViewNotePage.ets                  // 笔记组件  │  │  └─viewModel  │  │  │      CourseHomeModel.ets               // 课程页面数据模型  │  │  │      PracticeMode.ets                  // 科目数据模型  │  │  │      SecondListModel.ets               // 选项类型数据模型  │─features/minePage/src/main     │  ├─ets  │  │  ├─components  │  │  │      Header.ets                        // Header组件  │  │  ├─viewModel                              // 数据类型  │  │  │      MessageModel.ets               │  │  │      setUpModel.ets                    // 设置相关模型数据模型  │  │  │      MineModel.ets                     // 用户资料信息数据模型  │  │  ├─views  │  │  │      AboutPage.ets                     // 关于页面  │  │  │      AuthenticationPage.ets            // 用户认证协议页面  │  │  │      BrowsingHistoryPage.ets           // 浏览页面  │  │  │      CollectionPage.ets                // 课程收藏页面  │  │  │      CoursePage.ets                    // 课程精选页面  │  │  │      EditPersonalCenterPage.ets        // 个人信息详情页面  │  │  │      FeedbackPage.ets                  // 意见反馈页面  │  │  │      FeedbackRecordPage.ets            // 反馈记录页面  │  │  │      MessageCenterPage.ets             // 消息页面  │  │  │      MinePage.ets                      // 我的页面  │  │  │      MyOrderPage.ets                   // 订单首页页面  │  │  │      OneDayPracticeRecordsPage.ets     // 单个练习记录页面  │  │  │      OrderDetailPage.ets               // 订单详情页面  │  │  │      OrderListPage.ets                 // 订单页面  │  │  │      PracticeDetailsPage.ets           // 反馈页面  │  │  │      PracticeRecordsPage.ets           // 练习记录页面  │  │  │      PrivacyAgreementPage.ets          // 同意  │  │  │      PrivacyPage.ets                   // 协议  │  │  │      PrivacyStatementPage.ets          // 隐私页面  │  │  │      SetupPage.ets                     // 设置页面  │  │  │      TermsOfServicePage.ets            // 用户服务页面  └─products/entry/src/main        ├─ets     │  ├─entryability     │  │      EntryAbility.ets                  // 应用程序入口     │  ├─entrybackupability     │  │      EntryBackupAbility.ets            // Backup配置入口          │  ├─pages     │  │      Index.ets                         // 入口页面     │  │      LoginPage.ets                     // login页面     │  ├─model     │  │      TabListItem.ets                   // 数据声明     │  ├─viewmodels     │  │      MainVM.ets                        // 页面数据模型     │  ├─common                                 // 常量及Tab数据源     │         TabConstants.ets     └─resources
复制代码

 

2. 关键代码解读

本篇代码非应用的全量代码,只包括应用的部分能力的关键代码。

若需获取全量代码,请查看模板集成章节。

1) 一键搜题

​// 语音识别// 请求权限后创建服务并监听this.atManager.requestPermissionsFromUser(this.context, ['ohos.permission.MICROPHONE'])            .then(async (data) => {              if (data.authResults[0] === 0) {                await this.createSREngine()                this.startListener()              }            })            .catch(() => {              //在此处进行异常处理            });
async createSREngine() { const extraParams: Record<string, Object> = { 'locate': 'CN', 'recognizerMode': 'short' } const initParamsInfo: speechRecognizer.CreateEngineParams = { language: 'zh-CN', online: 1, extraParams } try { this.asrEngine = await speechRecognizer.createEngine(initParamsInfo) this.setListener() } catch (e) { //在此处进行异常处理 } }
startListener() { const audioParam: speechRecognizer.AudioInfo = { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 }; const extraParam: Record<string, Object> = { 'maxAudioDuration': 40000, 'recognitionMode': 0 }; this.sessionId = new Date().getTime().toString() const recognizerParams: speechRecognizer.StartParams = { sessionId: this.sessionId, audioInfo: audioParam, extraParams: extraParam }; this.asrEngine?.startListening(recognizerParams) }
setListener() { let that = this // 创建回调对象 let setListener: speechRecognizer.RecognitionListener = { // 开始识别成功回调 onStart() { }, // 事件回调 onEvent() { }, // 识别结果回调,包括中间结果和最终结果 onResult(_sessionId: string, result: speechRecognizer.SpeechRecognitionResult) { that.textInput = that.textInputPre + result.result }, // 识别完成回调 onComplete() { that.textInputPre = that.textInput }, // 错误回调,错误码通过本方法返回 // 返回错误码1002200002,开始识别失败,重复启动startListening方法时触发 // 更多错误码请参考错误码参考 onError() { }, } // 设置回调 this.asrEngine?.setListener(setListener); };
// 拍照识别async startCameraPicker() { let pickerProfile: picker.PickerProfile = { cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, }; let result: picker.PickerResult = await picker.pick(getContext(), [picker.PickerMediaType.PHOTO, picker.PickerMediaType.VIDEO], pickerProfile); let uri = result.resultUri; let imageSource: image.ImageSource; let chooseImage: PixelMap; setTimeout(async () => { let fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); imageSource = image.createImageSource(fileSource.fd); chooseImage = await imageSource.createPixelMap(); if (!chooseImage) { return; } // 获取图片后调用文本识别接口 let visionInfo: textRecognition.VisionInfo = { pixelMap: chooseImage }; let textConfiguration: textRecognition.TextRecognitionConfiguration = { isDirectionDetectionSupported: true }; await textRecognition.recognizeText(visionInfo, textConfiguration).then((textRecognitionResult) => { if (textRecognitionResult.value !== '') { this.search(textRecognitionResult.value) } }) }, 100) }
复制代码


2) 系统路由封装及使用

// 1、定义路由工具类import { RouterMap } from './constants/RouterMap';
export default interface NavRouterInfo { url: string; // 跳转路由名 mode?: NavDestinationMode; // NavDestination类型 param?: Object; // 传递参数 onPop?: Callback<PopInfo>; // 回调事件}
class RouterModule { public static stack: NavPathStack = new NavPathStack(); static builderMap: Map<string, WrappedBuilder<[object]>> = new Map<string, WrappedBuilder<[object]>>();
// 页面跳转(指定页面) public static push(info: NavRouterInfo, animated?: boolean) { try { RouterModule.stack.pushPathByName(info.url, info.param, info.onPop, animated); } catch (err) { } }
// 页面替换(指定页面) public static replace(info: NavRouterInfo) { try { RouterModule.stack.replacePathByName(info.url, info.param); } catch (err) { } }
// 页面回退(上个页面) public static pop<T = boolean>(result?: T, animated?: boolean) { try { RouterModule.stack.pop(result, animated); } catch (err) { } }
// 页面回退(携带参数) public static popWithRes(res: ESObject, animated?: boolean) { try { RouterModule.stack.pop(res, animated); } catch (err) { } }
// 页面回退(至对应页面名) public static popToName(name: string, animated?: boolean) { try { RouterModule.stack.popToName(name, animated); } catch (err) { } }
// 页面栈清空(回Navigation) public static clear(animated?: boolean) { try { RouterModule.stack.clear(animated); } catch (err) { } }
// 获取页面栈大小 public static size(): number { return RouterModule.stack.size(); }
// 获取参数(指定页面) public static getNavParam<T = Object>(info: NavRouterInfo): T | undefined { try { const paramsArr = RouterModule.stack.getParamByName(info.url) as T[] | undefined[]; return paramsArr.pop(); } catch (err) { } return undefined; }
// 获取页面名(页面栈前一个) public static getSourcePage(): string | undefined { const pathNames = RouterModule.stack.getAllPathName(); pathNames.pop(); return pathNames.pop(); }}
export { RouterModule, RouterMap };
// 2、定义RouterMap 注册路由表时用 export enum RouterMap { // 主页 MAIN_PAGE = 'MainPage',}// 3、注册路由表export class RouterTable { static builderMap: Map<string, WrappedBuilder<[object]>> = new Map<string, WrappedBuilder<[object]>>();
// 初始化路由表 public static routerInit() { RouterTable.builderMap.set(RouterMap.MAIN_PAGE, wrapBuilder(MainPageBuilder)); }
// 通过名称获取builder public static getBuilder(builderName: string): WrappedBuilder<[]> { let builder = RouterTable.builderMap.get(builderName); return builder as WrappedBuilder<[]>; }}
4、使用前需先init注册 // 初始化路由表 RouterTable.routerInit()
// 创建导航Navigation@Builder pageMap(name: string) { NavDestination() { RouterTable.getBuilder(name).builder() } .mode(NavDestinationMode.STANDARD) .hideTitleBar(true) .onBackPressed(() => { return this.backPress(name) }) }
build() { Column() { Navigation(RouterModule.stack) { } .hideNavBar(true) .hideToolBar(true) .hideTitleBar(true) .hideBackButton(true) .mode(NavigationMode.Stack) .navDestination(this.pageMap) } }
复制代码

 

3. 模板集成

本模板提供了两种代码集成方式,供开发者自由选用。

1) 整体集成(下载模板

开发者可以选择直接基于模板工程开发自己的应用工程。

  • 模板代码获取:

① 通过 IDE 插件创建模板工程,开发指导

② 通过生态市场下载源码, 下载模板

③ 通过开源仓访问源码,仓库地址

  • 打开模板工程,根据 README 说明中的快速入门章节,将自己的应用信息配置在模板工程内,即可运行并查看模板效果。


 

根据自己的业务内容修改模板,进行定制化开发。


2) 按需集成

若开发者已搭建好自己的应用工程,但暂未实现其中的部分场景能力,可以选择取用其中的业务组件,集成在自己的工程中。

  • 组件代码获取:

① 通过 IDE 插件下载组件源码。开发指导

② 通过生态市场下载组件源码。 下载地址

  • 下载组件源码,根据 README 中的说明,将组件包配置在自己的工程中。



  • 根据 API 参考和示例代码,将组件集成在自己的对应场景中。

 

以上是第三期“教育行业-教育备考”行业优秀案例的内容,更多行业敬请期待~

欢迎下载使用行业模板“点击下载”,若您有体验和开发问题,或者迫不及待想了解 XX 行业的优秀案例,欢迎在评论区留言,小编会快马加鞭为您解答~

同时诚邀您添加下方二维码加入“组件模板活动社群”,精彩上新 &活动不错过!



👉本系列持续更新,欢迎收藏本帖!

第一期:HarmonyOS官方模板优秀案例 | 便捷生活行业· 购物中心

第二期:HarmonyOS官方模板优秀案例 | 新闻行业· 综合新闻

第三期:HarmonyOS官方模板优秀案例 | 教育行业· 教育备考

第四期:HarmonyOS 官方模板优秀案例 | 餐饮行业· 美食菜谱(马上发布)

第五期:HarmonyOS 官方模板优秀案例 | 工具行业· 日历应用(马上发布)


👉HarmonyOS 组件模板相关推荐

  • 【活动 ing】HarmonyOS 组件/模板集成创新活动,报名时间截止 2025 年 8 月 30 日,点击查看

  • ·鸿蒙应用开发者激励计划 2025,点击查看

2025-08-20 11:131906

评论

发布
暂无评论

开源数据库这么香,为什么我们还要下功夫自研?

华为云开发者联盟

数据库 开源 数据

MySQL-技术专题-问题分析

码界西柚

深入分析CRM系统对现代企业的作用

Learun

来不及解释了,快上车!力软快速开发平台,助力企业搭乘万物互联的顺风车

Learun

31道Java核心面试题,一次性打包送给你

小Q

Java 学习 程序员 架构 面试

2020年秋招阿里136道Java高级岗面试题(含答案及复习资源)

Java架构之路

Java 程序员 面试 算法 编程语言

区块链是一个不知道要解决什么问题的解决方案吗?

CECBC

比特币 区块链 银行

架构师训练营第四章 系统架构总结

郎哲158

Spring Cloud 微服务实践(7) - 日志

xiaoboey

kafka 微服务 Spring Cloud 日志 spring cloud stream

字节跳动 Flink 单点恢复功能实践

Apache Flink

flink

Python时间序列分析简介(2)

计算机与AI

Python 时间序列

Web前后端:如何分离,如何解耦?

华为云开发者联盟

大前端 后端 开发

互联网应用系统技术方案主要解决什么问题?

博古通今小虾米

lldb常用命令与调试技巧

iOSer

ios lldb常用命令 lldb调试技巧

从构建小系统到架构分布式大系统,Spring Boot2的精髓全在这里了

Java架构之路

Java 程序员 面试 Spring Boot 编程语言

PyFlink + 区块链?揭秘行业领头企业 BTC.com 如何实现实时计算

Apache Flink

flink

建筑行业区块链应用场景是怎样的

CECBC

区块链 行业资讯

国庆期间,我造了台计算机

yes

计算机 底层

SpringBoot-技术专题-启动原理

码界西柚

Nacos-技术专题-配置中心实现

码界西柚

区块链教育 丨 首批区块链专业新生正式入学

CECBC

区块链技术 区块链教育

架构师训练营1期第三周作业

木头发芽

技术实操丨SoundNet迁移学习之由声音分类到语音情感识别

华为云开发者联盟

AI 数据 语音识别

开源=免费?

Learun

光大银行刘淼:基于华为云GaussDB(DWS) 数据仓库创新实践

华为云开发者联盟

数据仓库 数据 huawei

架构师训练营第四周作业

郎哲158

EffectiveJava读书笔记-01-对象创建与销毁

wander

读书笔记 编程开发

程序员去外包真的不可取吗?

Java架构师迁哥

MySQL-技术专题-查询速度性能

码界西柚

Java程序员月薪多少K才能在北上广买得起房?

Java架构之路

Java 程序员 编程语言

spring-boot-route(十)多数据源切换

Java旅途

Java Spring Boot

【精华+1】HarmonyOS官方模板优秀案例  
(第3期:教育行业· 教育备考)_HarmonyOS_HarmonyOS_InfoQ精选文章