运用所学的知识对“测测你的本命专业”进行分析
1.分析对象
对https://cdn-act.knowyourself.cc/life_profession/“测测你本命专业进行分析”
2.详细分析
一、网络分析

因为页面没有跳转因此只有可能进行异步获取后端数据,选中XHR进行数据过滤,过滤后没有发现任何数据,因此这是一个纯前端项目。

二、项目结构分析
选中Sources来进行源码分析,容易发现这个前端项目是由webpack构建的。该项目的基本文件结构如下图所示:

根据包名易得components是组件包,img是存放图片的包,pages是存放页面的包,util是工具包。
大致浏览包下的源码易知pages包是该项目的核心包。
pages文件的结构大致如下:

查看了部分源码易得,p-1是开始答题页面包,p-2是答题的页面包,done是答题完成产生结果的包。
因此核心代码在done文件夹下。
3.核心代码分析
对pages/index.tsx核心代码进行分析:
const select = select_q_list.reduce((l: any, f: any, i: number) => { if (i !== 9) { // @ts-ignore l.push([f.index]) } else { l.push(f.map((v: any) => select_map.indexOf(v)).sort((a: any, b: any) => a - b)) }
将select_q_list数据转换为select数据,如下图所示


用result(select.slice(1))去除select数组的第一个元素,并将数据传输给result。
result.js核心代码分析
config中的0-9和1-10题的题号一一对应,题号中的key表示的是选项的个数,value表示的是与该选项内容相关的专业。
将page/index.tsx的select.slice(1)传输到result.js中
var result = []; for (var topic_num = 0; topic_num < select.length; topic_num++) { // 遍历本题答案 for (var j = 0; j < select[topic_num].length; j++) { var user_select = select[topic_num][j]; // 获取配置 var tmp = config[topic_num][user_select]; // 合并 result = result.concat(tmp); } }
将select.slice(1)与config对应的数组信息,全部放入result数组中
var result_map = {}; var max = -1; // 打乱一下result结果 result.shuffle(); for (var i = 0; i < result.length; i++) { if (typeof result_map[result[i]] == "undefined") { result_map[result[i]] = 0; } result_map[result[i]]++; if (max == -1) { max = result[i]; } else { if (result_map[result[i]] > result_map[max]) { max = result[i]; } }
result_map用来统计出现最多的专业编号并返回给index.tsx,并调用该页面的图片
4.测试
根据基础的组合知识可以算出前八道单选的可能性是4800种,第九题多选的可能性是286种,所以有1372800种满足题目需求的不同测试用例。本地完成1372800种测试用例的代码。用桶来记录每题出现的次数,如下图所示:

可以发觉无论怎么填写测试题,都无法出现机电工程学专业,或许是作者留的彩蛋吧!
测试用例的代码如下:
<!DOCTYPE html> <html lang="en"> <head> </head> <body> <script> // 结果页id: // 0:经济学 // 1:哲学 // 2:法学 // 3:社会学 // 4:教育学 // 5:汉语言文学 // 6:外国语言学 // 7:新闻学 // 8:历史学 // 9:数学 // 10:物理学 // 11:化学 // 12:生命科学 // 13:地理学 // 14:心理学 // 15:计算机科学与技术 // 16:土木工程学 // 17:建筑学 // 18:机电工程学 // 19:农林学 // 20:医学 // 21:管理学 // 22:艺术 // 23:戏剧影视导演 // 24:表演艺术 // 25:体育学 // 26:考古学 // 27:电子竞技 //10道题,选择传入数组,因为有多选,数组内套数组 //选择顺序从0开始算,0代表第一个选项,1代表第二个... //例如 select :[[0],[1],[3],[0],[0,1,2,3],[0,1,2,3,4],[0]] function getResult(select) { if (!Array.prototype.shuffle) { Array.prototype.shuffle = function () { for (var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x) return this; }; } var config = { 0: { 0: [1, 0, 2, 3, 4, 5, 6, 7, 8, 21, 26], 1: [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 26], 2: [22, 23, 24, 25, 27], }, 1: { 0: [0, 2, 6, 7, 20, 21, 25], 1: [3, 4, 24], 2: [5, 14, 22], 3: [1, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 23, 26, 27], }, 2: { 0: [1, 3, 4, 5, 9, 10, 14, 21, 22, 23, 24, 27], 1: [0, 2, 6, 7, 8, 11, 12, 13, 15, 16, 17, 18, 19, 20, 25, 26], }, 3: { 0: [0, 2, 3, 4, 6, 7, 20, 21, 24, 25], 1: [1, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 26, 27], }, 4: { 0: [1, 3, 4, 5, 9, 10, 14, 21, 22, 23, 24, 27], 1: [0, 2, 6, 7, 8, 11, 12, 13, 15, 16, 17, 18, 19, 20, 25, 26], }, 5: { 0: [1, 0, 2, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 25, 26, 27], 1: [3, 4, 5, 14, 22, 24], }, 6: { 0: [1, 8, 9, 10, 11, 12, 13, 20, 26], 1: [5, 22, 23, 24], 2: [15, 16, 17, 18, 19, 25, 27], 3: [3, 4, 6, 7, 14], 4: [0, 2, 21], }, 7: { 0: [1, 8, 9, 10, 11, 12, 13, 20, 26], 1: [5, 22, 23, 24], 2: [15, 16, 17, 18, 19, 25, 27], 3: [3, 4, 6, 7, 14], 4: [0, 2, 21], }, 8: { 0: [4, 5, 7, 14, 21, 23, 6], 1: [6, 15], 2: [13], 3: [10, 16, 17, 18], 4: [12, 19, 20, 25], 5: [1, 2, 7, 21], 6: [0, 9, 15, 16, 18, 10, 14], 7: [17, 22, 24, 23], 8: [3, 8, 26, 13], 9: [11, 12, 19, 20, 26], 10: [25, 27], 11: [22, 24], }, 9: { 0: [], 1: [], 2: [] } }; var result = []; for (var topic_num = 0; topic_num < select.length; topic_num++) { // 遍历本题答案 for (var j = 0; j < select[topic_num].length; j++) { var user_select = select[topic_num][j]; // 获取配置 var tmp = config[topic_num][user_select]; // 合并 result = result.concat(tmp); } } var result_map = {}; var max = -1; // 打乱一下result结果 // result.shuffle(); for (var i = 0; i < result.length; i++) { if (typeof result_map[result[i]] == "undefined") { result_map[result[i]] = 0; } result_map[result[i]]++; if (max == -1) { max = result[i]; } else { if (result_map[result[i]] > result_map[max]) { max = result[i]; } } } //console.log(result); //console.log(result_map); //console.log(max); return max; } // test // console.log(getResult([[2],[3],[0],[1],[0],[0],[1],[1],[0,7,10],[1]]));//期望结果 23 // console.log(getResult([[1],[3],[1],[1],[1],[0],[2],[2],[1,2,6],[1]])); //15 // getResult([[1],[3],[1],[1],[1],[0],[2],[2],[1,2,6],[1]]);//期望结果 15 //getResult([[2],[3],[0],[1],[0],[0],[1],[1],[0,7,10],[1]]);//期望结果 23 /** * 测试脚本 * */ //前面8道单选全部的可能性,封装到results数组中 arr = [ [0,1,2], [0,1,2,3], [0,1], [0,1], [0,1], [0,1], [0,1,2,3,4], [0,1,2,3,4] ] results = []; res = []; doExchange(arr, 0); function doExchange(arr, index){ for (var i = 0; i<arr[index].length; i++) { res[index] = arr[index][i]; if (index != arr.length - 1) { doExchange(arr, index + 1) } else { results.push(res.concat()) } } } //将results数组中的数变成数组 for (var i = 0; i < results.length; i++) { results[i].forEach(function(value,index,array){ array[index] = [].concat(value) }); } console.log(results); //第九题的所有组合算法 var data = [0,1,2,3,4,5,6,7,8,9,10,11]; var path = [] var group = [] function getGroup(k,startIndex,data = []){ if(path.length==k){ group.push(path.concat()); return; } for (let i = startIndex; i < data.length; i++) { path.push(data[i]); getGroup(k,i+1,data); path.pop() } } getGroup(2,0,data) getGroup(3,0,data) console.log(group) // 合并1-9题的所有组合 last = []; for (let i = 0; i < results.length; i++) { for (let j = 0; j < group.length; j++) { //创建一个新的数组 var arr = [].concat(results[i]) arr.push(group[j]) last.push(arr) } } console.log(last); var bucket = new Array(28).fill(0) //构建一个长度为28的桶 for (let i = 0; i < last.length; i++) { var index = getResult(last[i]) bucket[index]++ } console.log(bucket) </script> </body> </html>
PSP:
| 做什么 | 日期 | 开始时间 | 结束时间 | 休息时间 | 合计时间 |
| 写博客 | 9/15 | 21:18 | 21:53 | 0 | 47min |
| 写博客 | 9/15 | 22:06 | 22:20 | 2min | 12min |
| 总计 | 59min |
浙公网安备 33010602011771号