每日一题:个性化推荐
发表于:2024-12-10
字数统计:1303 字
预计阅读5分钟
介绍
当下,移动互联网技术和智能手机的发展,使得采集用户数据的能力变得空前强大,无时无刻,无所不在。拥有这些数据后,全行业的个性化推荐能力变得更加容易实现,不论是淘宝京东,还是今日头条,无疑是这个时代的最大受益者。个性化推荐的本质是根据不同的人群,将最有可能感兴趣的内容优先推荐给相应的用户,最大限度的提高转化率。
本题需要在已提供的基础项目中,使用 Nodejs 实现个性化推荐的效果。
准备
本题已经内置了初始代码,打开实验环境,目录结构如下:
txt
├── index.html
├── customized.html
├── data.json
└── js
└── index.js其中:
index.html是标签选择页面。customized.html是根据选择标签渲染的个性化推荐页面。data.json是后台标签的数据文件。js/index.js是需要补充代码的文件。
注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:
bash
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/14311/10.zip && unzip 10.zip && rm 10.zip目标
请在 js/index.js 文件中补全代码,最终实现个性化推荐的功能。
首先,在终端运行以下命令启动服务器:
bash
node ./js/index.js当看到终端输出:server is running in port 8080,表明服务器启动成功。
并在浏览器中通过 8080 端口预览 index.html 页面,显示如下所示:

在完成勾选后,点击确认,页面会发送 post 请求并跳转到新的页面,你需要根据用户的勾选项,从 data.json 中查询对应的数据,并读取 customized.html 文件的内容,两者结合生成结果页面数据,并返回给前端浏览器:
- 如果用户没有勾选任何标签,直接点击确认,新页面给与提示:

提示信息的 DOM 结构如下:
html
<div class="unselect">你还未选择任何感兴趣的标签!</div>- 如果用户勾选了标签,则返回对应的标签的查询信息以及相关推荐,比如用户选择了标签
Javascript,除了查询tag为Javascript的内容,也需要查询Javascript的相关推荐标签HTML5,CSS3的内容(即relevance字段对应的数据),一并返回。- 注意:不再需要进一步查询相关推荐的相关推荐,即不需要查询
HTML5的相关推荐标签的内容。
- 注意:不再需要进一步查询相关推荐的相关推荐,即不需要查询
- 多个标签之间的相关标签可能重复,需要对查询内容进行去重,比如选择了标签
Javascript和CSS3,最终的去重结果应该是标签Javascript、CSS3、HTML5的内容。


每一条信息的 DOM 结构如下:
html
<div class="interest">
<div class="tag">标签名</div>
<div>标签内容</div>
</div>
customized.html文件中已提供基础的样式,请保证你生成的节点带有指定的 class 信息,并填充到 body 中。 在代码更新后,请记得重启服务器!
规定
- 请勿修改
js/index.js文件外的任何内容。 - 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。
- 满足题目需求后,重启服务器并保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分。
判分标准
- 完成目标 1,得 5 分。
- 完成目标 2,得 20 分。
总通过次数: 50 | 总提交次数: 115 | 通过率: 43.5%
题解:
js
req.on("end", () => {
let { interested = [] } = qs.parse(body);
// TODO: 补充个性化页面处理代码
let html = ''
if (!interested.length) {
html = `<div class="unselect">你还未选择任何感兴趣的标签!</div>`
} else {
// 处理interested只有一个,不是数组的情况
const hashMap = {}
const result = []
if (!Array.isArray(interested)) interested = [interested]
for(let i = 0; i < interested.length; i++) {
// 外层遍历
for(let j = 0; j < data.length; j++) {
// 内层遍历匹配
if (interested[i] === data[j]['tag'] && !hashMap[interested[i]]) {
// 使用tag匹配,如果匹配,和不重复出现(hashMap)就填入数据
result.push(data[j])
hashMap[interested[i]] = 1
// 深度优先,在此遍历re
for(let tag of data[j]['relevance']) {
// 这里也可以用hashmap,都行
if (interested.indexOf(tag) === -1) {
interested.push(tag)
}
}
}
}
}
// 处理html
for(let item of result)
html += `<div class="interest">
<div class="tag">${item.tag}</div>
<div>${item.content}</div>
</div>`
// console.log(html);
}
let customized = fs.readFileSync(path.join(__dirname, "../customized.html"), {
encoding: "utf8",
});
customized = customized.replace('<body></body>', `<body>${html}</body>`)
// 将读取的 index.html 内容写入响应中,并返回给前端展示
res.writeHead(200, { "Content-Type": "text/html" });
res.write(customized);
res.end();
});