前言
Hello,大家好,我是小马,受疫情影响,2022 年,我觉得是互联网最难的一年,直至 5 月也依然是互联网寒冬,大厂裁员的消息在微信群漫天飞舞,而招聘网站上的 HC 也越来越少,因此不少小厂也开始纷纷内卷,压低员工绩效,本应该晋级加薪的时间,也变成了杳无音信。难道我们就束手无策了吗?有句话说的好,“机会永远是留给有准备的人”,话虽不错,但有的人会说,“每天上班忙的要死,能完成任务就不错了,哪有时间准备面试刷题呢?”,因此我决定开发一个面试刷题小程序,让我们可以充分利用一些空闲时间提高自己,比如上班挤地铁的时候,排队做核酸的时候,都可以。
项目体验
为什么取名“面试狗”呢?取名模仿自鱼皮大佬的"面试鸭"网站,鸭是谐音,但狗却是“狗头保命”。
功能结构
-
面试刷题
-
选择题
-
简答题
-
文章
-
面试技巧
-
面试经验
-
视频
-
视频解析
-
模拟面试
因为视频都会有版权,个人也不能上架视频类小程序,所以放弃。
技术架构图
技术栈选择
关于跨端开发或者多端开发,一般会使用 Taro 或者 Uniapp
-
如果是 React 技术栈一般会选择 Taro
-
如果是 Vue 技术栈一般会选择 Uniapp
我个人本来爱好 react 技术栈,但由于 Uniapp 开发可以有免费的云开发环境(阿里云 50 个,腾讯云 1 个),果断选择 Uniapp。
初始化项目
在开始之前请先
-
注册一个微信小程序
-
下载微信小程序开发工具
-
注册一个 dcloud 账号
-
下载 hbuilderX
hbuilderX 是 dcloud 开发的代码编辑器,集成了便捷的云开发环境,可以方便我们调试。如果喜欢使用 vscode 的同学可以参考下面这篇文章。
使用 VSCode 开发 uni-app 教程[1]
新建一个空白项目,选择开启 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"
}
}
}
这里我就罗列了几个重要字段。表结构创建完成了,接下来我们需要收集下面试题。
数据收集
题目来源
-
大厂面试题每日一题[2]
-
每日一题[3]
-
前端面试[4]
-
牛客网 - 互联网求职神器和备考学习平台[5]
-
赛码网 - IT 笔试面试加分利器[6]
-
掘金面试标签[7]
建完表后我们要往表中添加一些数据,这里可以大家可以自行整理,当然也可以使用 node 爬虫,
这里就列几个可能用到的 JS 库
-
axios 用于爬取网页内容
-
cheerio[8] 是服务端的 jquery api,用于获取 dom 节点数据
-
turndown[9] 将 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 中使用?可以参考这份文档[10],这里我不过多赘述。大家若有相关需求,可以参考文档进行开发。
后台管理
按照上面步骤,相信有前端基础的同学,肯定可以开发出类似的功能,但对于云开发来说,我认为最麻烦的是后台管理,刷题小程序开发好了,总需要一个后台维护的地方,虽然 uniapp 有 uni-admin 模板,也可以快速开发出一个后台管理系统,但对于个人开发者来说,需要投入不少成本。
得益于 hbuilderX 中的 schema2code 功能,可以直接根据数据模型直接生成管理页面代码,所以我们可以直接在小程序端管理数据了。
下面我就贴一下文章模块的管理页面的步骤:
首先根据数据字段写好 schema。我这边直接使用了系统自带的 opendb,在 unicloud web 控制台中新建表,选中文章表和类别表,大家可以根据自己的需求增减字段。
在 unicloud web 控制台中表创建完成后,然后在 hbuilderX 中下载所有 DB Schema。
选中 news 表,右键 schema2code
接着会弹出字段选择页面,我们可以根据需求勾选需要管理的数据字段,点击确定就会自动生成 关于 news 表的增删查改的页面啦。一起来看下效果
权限设计
并不能让所有用户都有后台管理权限,所以我们可以根据微信小程序的提供的 openid 来建立用户系统。
下面介绍下主要步骤:
-
第一步:使用
uni.getUserProfile
来获取头像昵称等信息 -
第二步:通过微信小程序端 API
uni.login
获得code
-
第三步:在服务端通过 API auth.code2session 就可以获取到用户的 openid 了,
-
第四步:新建一张表
wx_user
,将 openId 和用户信息存入云数据库中。
最后直接把自己的信息设置成 admin, 在小程序端根据 admin 展示后台管理菜单。
红色部分并不是对所有人展示,根据 admin 字段显示管理字段。
打包发布
至此我们的面试刷题小程序开发结束了,点击菜单上的发布按钮,我们可以打包成 App、H5 和各种应用的小程序。
我这边发布的是微信小程序,要先打开微信小程序开发者工具,点击发布后,微信小程序开发者会自动运行,点击上传,最后在微信后台发布提交审核即可。
小结
一起来总结下
-
使用 uniApp 和云开发我们可以免费白嫖一个跨端的小程序。
-
可以利用爬虫抓取一些资源,来丰富我们的内容。
-
使用
schema2code
可以自动生成后台管理页面 -
通过用户权限控制,可以在小程序端管理数据,PC 端也可以(用微信客户端打开小程序即可)
以上就是本文全部内容,希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。
往期推荐
[1]使用 VSCode 开发 uni-app 教程: https://juejin.cn/post/7090532271257714695
[2]大厂面试题每日一题: https://q.shanyue.tech/
[3]每日一题: https://github.com/everest-architecture/front-end-daily-question
[4]前端面试: https://github.com/lgwebdream/FE-Interview
[5]牛客网: https://www.nowcoder.com/
[6]赛码网: https://www.acmcoder.com
[7]掘金面试标签: https://juejin.cn/frontend/%E9%9D%A2%E8%AF%95?sort=hottest
[8]cheerio: https://github.com/cheeriojs/cheerio
[9]turndown: https://github.com/mixmark-io/turndown
[10]如何 在 uniapp 中使用 towxml ?: https://github.com/sbfkcel/towxml/issues/116
文章评论