【实战】使用 uniapp 开发一个面试刷题小程序

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 直至 5 月也依然是互联网寒冬,大厂裁员的消息在微信群漫天飞舞,而招聘网站上的 HC 也越来也少,因此不少小厂也开始纷纷内卷,压低员工绩效,本应该晋级加薪的时间,也变成了杳无音信。难道我们就束手无策了

highlight: monokai

我正在参加跨端技术专题征文活动,详情查看

前言

Hello,大家好,我是小马,受疫情影响,2022 年,我觉得是互联网最难的一年,直至 5 月也依然是互联网寒冬,大厂裁员的消息在微信群漫天飞舞,而招聘网站上的 HC 也越来也少,因此不少小厂也开始纷纷内卷,压低员工绩效,本应该晋级加薪的时间,也变成了杳无音信。难道我们就束手无策了吗?有句话说的好,“机会永远是留给有准备的人”,话虽不错,但有的人会说,“每天上班忙的要死,能完成任务就不错了,哪有时间准备面试刷题呢?”,因此我决定开发一个面试刷题小程序,让我们可以充分利用一些空闲时间提高自己,比如上班挤地铁的时候,排队做核酸的时候,都可以。

项目体验

微信小程序搜索面试狗或扫码体验。

为什么取名“面试狗”呢?取名模仿自鱼皮大佬的"面试鸭"网站,鸭是谐音,但狗却是“狗头保命”。

功能结构

  • 面试刷题

    • 选择题
    • 简答题
  • 文章

    • 面试技巧
    • 面试经验
  • 视频

    • 视频解析
    • 模拟面试

因为视频都会有版权,个人也不能上架视频类小程序,所以放弃。

技术架构图

面试刷题小程序架构图

技术栈选择

关于跨端开发或者多端开发,一般会使用 Taro 或者 Uniapp

  • 如果是 React 技术栈一般会选择 Taro
  • 如果是 Vue 技术栈一般会选择 Uniapp

我个人本来爱好 react 技术栈,但由于 Uniapp 开发可以有免费的云开发环境(阿里云 50 个,腾讯云 1 个),果断选择 Uniapp。

初始化项目

在开始之前请先

hbuilderX 是 dcloud 开发的代码编辑器,集成了便捷的云开发环境,可以方便我们调试。
如果喜欢使用 vscode 的同学可以参考下面这篇文章。

使用 VSCode 开发 uni-app 教程

新建项目

新建一个空白项目,选择开启 unicloud,选择阿里云。

关联云服务空间

然后关联云服务空间,至此项目初始化完成。

表结构设计

uniCloud 提供了一个 JSON 格式的文档型数据库。顾名思义,数据库中的每条记录都是一个 JSON 格式的文档。所以只需要保存 JSON 格式的数据就会自动往数据库里面插入一条记录。
既然是文档形数据数据库,那么我们为什么要设计数据结构呢,别着急,这个在后面有大用处,我们先按关系形数据库设计表结构。

云数据库控制台

打开云数据库控制台,新建一张表, 取名为 fe-question, 在表结构中输入以下 json,

{
  "bsonType": "object",
  "required": [],
  "permission": {
    "read": true,
    "create": true,
    "update": true,
    "delete": true
  },
  "properties": {
    "_id": {
      "description": "ID,系统自动生成"
    },
    "title": {
      "bsonType": "string",
      "title": "标题",
      "description": "标题",
      "label": "标题",
      "trim": "both"
    },
    "desc": {
      "bsonType": "string",
      "title": "描述",
      "description": "描述",
      "label": "描述",
      "trim": "both"
    },
    "explanation": {
      "bsonType": "string",
      "title": "解析",
      "description": "解析",
      "label": "解析",
      "trim": "both"
    },
    "tagId": {
      "bsonType": "number",
      "title": "tag",
      "description": "标签",
      "label": "标签",
      "trim": "both"
    }
  }
}

这里我就罗列了几个重要字段。表结构创建完成了,接下来我们需要收集下面试题。

数据收集

题目来源

建完表后我们要往表中添加一些数据,这里可以大家可以自行整理,当然也可以使用 node 爬虫,
这里就列几个可能用到的 JS 库

  • axios 用于爬取网页内容
  • cheerio 是服务端的 jquery api,用于获取 dom 节点数据
  • turndown 将 html 转化为 markdown

比如牛客网只需要直接爬接口就可以了

const axios = require("axios");
const fs = require("fs");
const _ = require("lodash");

function sleep(time) {
  return new Promise((reslove) => setTimeout(reslove, time));
}

const headers = {
  "content-type": "application/json; charset=utf-8",
  "user-agent":
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
};
const listUrl =
  "https://www.nowcoder.com/api/questiontraining/interview/jobQuestionList";

const detailUrl =
  "https://www.nowcoder.com/api/questiontraining/interview/jobQuestionDetail";

let result = [];

const fetchList = async (page = 1) => {
  console.log("请求第" + page + "页");
  const res = await axios
    .get(listUrl, {
      params: {
        questionJobId: 156,
        questionClassifyId: 0,
        size: 50,
        page,
        _: new Date().getTime(),
      },
      headers,
    })
    .then((res) => {
      return res.data;
    });
  if (res.data.subjectList.length > 0) {
    await fetchDetail(res.data.subjectList);
    await fetchList(page + 1);
  } else {
    console.log("爬完了");
    fs.writeFileSync("fe-question.json", JSON.stringify(result));
  }
};

const fetchDetail = async (data) => {
  for (let index = 0; index < data.length; index++) {
    const item = data[index];
    //await sleep(1000);
    const res = await axios
      .get(detailUrl, {
        params: {
          questionId: item.questionId,
          questionJobId: item.questionJobId,
          questionClassifyId: 0,
          _: new Date().getTime(),
        },
        headers,
      })
      .then((res) => {
        return res.data;
      });
    if (res && res.data) {
      console.log("正在保存:" + res.data.title);

      result.push({
        explanation: res.data.referenceAnswer,
        title: res.data.title,
        desc: res.data.content,
        tag: _.get(res.data.questionTags, "[0].name"),
      });
    }
  }
};
fetchList();

上面代码,可以用于很多类似网站,先爬列表再爬详情这样的接口数据, sleep函数可以自行控制,这样可以防止服务端阻止爬虫,如有些网站需要登录,可以将cookie复制出来,保存在headers
爬虫截图

云函数获取数据

有了数据,接下来我们就需要实现后端逻辑,也就是接口部分。
新建云函数
新建云函数
在 hbuilderX 中选择 cloudFunctions,右键新建云函数,输入函数名称 question-detail
新建完成后,会在 index.js 中生成最简单的云函数代码。

'use strict';
exports.main = async (event, context) => {
    //event为客户端上传的参数
    console.log('event : ', event)

    //返回数据给客户端
    return event
};

event 为客户端上传的参数 ,return 返回数据给客户端,我们修改成如下代码

'use strict';
exports.main = async (event, context) => {
    const db = uniCloud.database();
    const res = await db.collection('fe-question').doc(event.id).get()
    //返回数据给客户端
    return res.data[0]
};

这样就可以根据 id 查询面试题详情了。
那么要如何调试呢,hbuilderX 可以直接配置请求参数,输入请求参数为 JSON 格式
配置测试参数
然后点击运行本地云函数,这样就可以直接运行云函数,拿到返回的 JSON 数据。
云函数运行结果

数据请求

前端页面遵循 vue 语法,只不过数据请求我们必须用 uniCloud 帮我封装好的函数请求数据,

假设我们现在要调用下刚才的面试题详情的云函数,那么前端可以通过如下方式调用这个云函数。

// promise方式
uniCloud.callFunction({
    name: 'fe-question',
    data: { id: 1 }
  })
  .then(res => {
    this.detail=res.result
  });

// callback方式
uniCloud.callFunction({
    name: 'fe-question',
    data: { id: 1 },
    success(){},
    fail(){},
    complete(){}
});

云函数执行结果会存在 result 中,一般会在 onLoad 生命周期中请求数据。

到此,我们的面试小程序前后端可以联调啦。

Markdown 解析

Towxml 是一个可将 HTML、Markdown 转为微信小程序 WXML(WeiXin Markup Language)的渲染库。用于解决在微信小程序中 Markdown、HTML 不能直接渲染的问题。并且在有详情的文档,如何在 uniapp 中使用?可以参考这份文档,这里我不过多赘述。大家若有相关需求,可以参考文档进行开发。

后台管理

按照上面步骤,相信有前端基础的同学,肯定可以开发出类似的功能,但对于云开发来说,我认为最麻烦的是后台管理,刷题小程序开发好了,总需要一个后台维护的地方,虽然 uniapp 有 uni-admin 模板,也可以快速开发出一个后台管理系统,但对于个人开发者来说,需要投入不少成本。

得益于 hbuilderX 中的 schema2code 功能,可以直接根据数据模型直接生成管理页面代码,所以我们可以直接在小程序端管理数据了。

下面我就贴一下文章模块的管理页面的步骤:

首先根据数据字段写好 schema。我这边直接使用了系统自带的 opendb,在 unicloud web 控制台中新建表,选中文章表和类别表,大家可以根据自己的需求增减字段。

unicloud web 控制台中新建表 news 表

在 unicloud web 控制台中表创建完成后,然后在 hbuilderX 中下载所有 DB Schema。

将云端的Schema下载到本地

选中 news 表,右键 schema2code

右键 schema2code 生成代码

勾选需要管理的字段
接着会弹出字段选择页面,我们可以根据需求勾选需要管理的数据字段,点击确定就会自动生成 关于 news 表的增删查改的页面啦。
一起来看下效果
文章列表
新建文章
文章编辑

权限设计

并不能让所有用户都有后台管理权限,所以我们可以根据微信小程序的提供的 openid 来建立用户系统。

下面介绍下主要步骤:

  • 第一步:使用 uni.getUserProfile 来获取头像昵称等信息
  • 第二步:通过微信小程序端 API uni.login获得 code
  • 第三步:在服务端通过 API auth.code2session 就可以获取到用户的 openid 了,
  • 第四步:新建一张表wx_user,将 openId 和用户信息存入云数据库中。

云数据库把自己设置成admin

最后直接把自己的信息设置成 admin, 在小程序端根据 admin 展示后台管理菜单。

根据admin字段显示管理菜单

红色部分并不是对所有人展示,根据 admin 字段显示管理字段。

打包发布

至此我们的面试刷题小程序开发结束了,点击菜单上的发布按钮,我们可以打包成 App、H5 和各种应用的小程序。

hbuilderX 可以发布的小程序列表

我这边发布的是微信小程序,要先打开微信小程序开发者工具,点击发布后,微信小程序开发者会自动运行,点击上传,最后在微信后台发布提交审核即可。
微信小程序发布

小结

一起来总结下

  • 使用 uniApp 和云开发我们可以免费白嫖一个跨端的小程序。
  • 可以利用爬虫抓取一些资源,来丰富我们的内容。
  • 使用 schema2code 可以自动生成后台管理页面
  • 通过用户权限控制,可以在小程序端管理数据,PC 端也可以(用微信客户端打开小程序即可)

以上就是本文全部内容,希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。

本文首发掘金平台,来源小马博客

相关文章
预约按摩小程序开发,为什么很多上门按摩平台根本招聘不到优秀技师?
上门按摩平台面临招不到优秀技师的问题,主要原因是平台众多,技师选择多样。为解决此问题,平台可引入技师等级制度,根据订单数量和好评率划分高、低等级技师。高等级技师可享受70%-90%的高提成及首页推荐,这不仅能激励技师的积极性,还能帮助平台筛选出优质技师,提升服务质量和口碑,形成良性循环。
|
2天前
|
小程序 云计算 Android开发
发者社区 云计算 文章 正文 小程序开发与公众号用户关联推送消息(九)
发者社区 云计算 文章 正文 小程序开发与公众号用户关联推送消息(九)
12 3
|
8天前
|
小程序
|
8天前
|
小程序
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
6天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
8天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
27 4
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
66 2
|
1月前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
27 0

热门文章

最新文章