1、写出以下程序输出什么,为什么?
const people = {
name:"",
hello() {
console.log(this.name)
},
hey:() => {
console.log(this.name)
}
}
people.hello() // 输出 " "。// 解释:people.hello() 通过people调用,因此hello内部this指向people,所以打印" "
people.hey() // 输出 ' ' // 解释:hey()是箭头函,箭头函数声明时候所在的作用域是全局,因此指向window。而window自身就带有name这个属性,属性值为' '
2、请写出以下报错的 原因 和 详细的解决方案
解答: 原因:本域名、端口号和请求接口的域名、端口号不一致,导致了跨域。浏览器为了安全限制跨站资源访问,阻止恶意跨站站点攻击的一个保护行为
解决方案:
方案一:通过服务器代理。也就是可以让后台处理第三方接口代理成自己的接口,在调用即可
方案二:如果是在vue项目中可以在config.js文件中的proxyTable属性中配置跨域代理
方案三:用jsonp。引用script标签不受同源策略的影响动态创建一个script标签,声明一个callback回调函数,在设置scr为请求url,在url后面回调函数作为参数传参。
缺点:只能支持get请求
3、按题目要求编写代码
使用es新语法,定义一个列表类List,该类必需包含至少以下两个成员:
- 属性length(表示列表中的元素个数)
- 方法add(向列表添加元素)
其中要求构造函数和add方法可以接收任意个数的参数。
解答:
class List(){
constructor(...items){
// ...items 为es6的语法剩余参数(rest)相当于普通函数的arguments
// constructor内定义的方法和属性是实例对象自己(即this)
// 而constructor外定义的方法和属性则是所有实例对象可以共享
this.items = items
this.length = items.length
}
add(...items){
this.items.push(...items)
this.length = items.length
}
}
var arr = List('123','1234','12')
console.log(arr.items) // ['123','1234','12']
console.log(arr.length) // 3
4、按题目要求编写代码
背景:
通过qq号码,调用getUid接口获取用户uid,再依赖uid去分别获取用户基本信息和支付信息。
以下是实习生小明根据需求写的代码。
要求:
请你使用es新语法重写代码,使代码逻辑更加健壮,更加规范,更加清晰,减少嵌套。
function request(methodName, paramObj, cb){
var params = '?'
for (var key in paramObj) {
params += key+'='+paramObj[key] + '&'
}
var url = 'http://test.com/'+methodName+params
var xhr = new XMLHttpRequest();
xhr.onload = function(e){ cb(e.target.response) };
xhr.open('GET',url);
xhr.send();
}
// 1、getInfo方法
function getInfo(qq, cb) {
// 获取用户ID
request('getUid',{qq:qq}, function(data){
if(data.ret === 0){
var uid= data.uid;
// 获取用户基本信息
request('getBaseInfo',{uid:uid}, function(data){
if(data.ret === 0){
var baseInfo = data.info;
}else {
var baseInfo = {};
}
// 获取用户支付信息
request('getPayInfo',{uid:uid}, function(data){
if(data.ret === 0){
var payInfo = data.info;
}else {
var payInfo = {};
}
// 返回
cb( Obejct.assign({},baseInfo, payInfo) );
})
})
}else{
throw new Error("获取用户ID失败");
}
})
}
// 2、开始调用getInfo
getInfo(123456,function(data){ console.log(data) })
解答:
function request(methodName, paramObj, cb){
let params = '?'
let url = 'http://test.com/'+methodName+params
let xhr = new XMLHttpRequest();
for (var key in paramObj) {
params += key + '=' + paramObj[key] + '&'
}
xhr.onload = function(e){ cb(e.target.response) };
xhr.open('GET',url);
xhr.send();
}
// 1、getInfo方法
function getInfo(qq, cb) {
new Promise((resolve, reject) => {
// 获取用户ID
request('getUid',{qq:qq}, function(data){
resolve(data);
})
}).then(res=> {
let uid = res.uid
let baseInfo = {}
let payInfo = {}
// 获取用户基本信息
request('getBaseInfo',{uid:uid}, function(data){
baseInfo = data.ret === 0? data.info :{}
}
// 获取用户支付信息
request('getPayInfo',{uid:uid}, function(data){
payInfo = data.ret === 0? data.info :{}
})
// 返回
cb( Obejct.assign({},baseInfo, payInfo) );
}).catch(error)=>{
reject(error)
}
}
// 2、开始调用getInfo
let fn = function(data){console.log(data) })
getInfo(123456,fn}
5、按题目要求编写代码
写一个JS函数,判断数字是否为对称数(比如121从左到右读,和从右到左读都是一样的)
function isSymmetryNumber(num){
}
isSymmetryNumber(121)
isSymmetryNumber(123321)
isSymmetryNumber(1234)
解答:
思路:先把num转换为字符串后在转换为数组,在用reverse反转数组,然后转换回字符串,最后在两者进行比较,相同则返回ture
function isSymmetryNumber(num){
let numSt = num.toSting()
let numArr = []
for(let arr of numSt){
numArr.push(arr)
}
let reNumSt = numArr.reverse().join('')
console.log(numSt ==reNumSt) // 相等为true
isSymmetryNumber(121)
isSymmetryNumber(123321)
isSymmetryNumber(1234)
6、请完成以下环境搭建
● 要求:
1、 选择一个HTTPS的网站(没具体要求,任意非敏感的、公开的网站即可);
2、 浏览器访问该网站,并抓取其随意1条XHR的HTTPS请求包,并保存为SAZ格式文件;
3、 请抓取与个人信息无关的且是公开的请求,并将请求包的 Cookie 和 敏感信息(如个人隐私、登录态)删除;
4、 请在请求头里添加一个自定义头部,x-cuz-flag,值为请求时的时间戳,如1641052799
解答: 抓取m.hao.123.com
在控制台输入下列代码:
var xhr = new XMLHttpRequest();
let url = 'https://m.hao123.com/hao123_api/page/getRootData?vit=h123&from=3w123&sample=1'
xhr.open('GET',url)
xhr.setRequestHeader('x-cuz-flag', '202405071524') // 设置请求头
xhr.send()
7、 按题目要求编写Vue3项目
创建一个 Vue3 项目,并按要求使用 TypeScript 完成项目:
创建1个List.vue组件:
HTML/CSS:
1、 组件由N个div组成,每个div要求:
● width: 100%; height: 500px;
● 背景颜色随机
● 内容为div序号(从0开始)
2、 若处于数据加载请求中时,则底部显示Loading样式(样式不限)
Typescript:
1、 使用 <script setup lang="ts"> 语法标签
2、 初始化基础变量名为 list,初始值为 [ { background: "rgb(233,32,38)" } ],
该变量表示页面上div的渲染个数
3、写一个返回模拟数据的方法 getList(10)
● 该方法接受1个参数:num,表示每次返回的数组长度。 例如传入10,则返回10个随机颜色长度的数组, 例如 [ { background: "rgb(233,32,38)" }, ....其余9个随机颜色.... ]
● 该方法每次执行时,随机模拟 [0,5) 秒的延迟再返回数据
4、组件初始化后,调用 getList(10) 获取新的数据后渲染到页面上;
并且监听滚动条事件,但滚动超过一半时,继续调用 getList(10) 获取新的数据渲染,直到渲染超过50个则停止;
说明:
在完成基础要求的基础上,可以尝试做一些性能优化;
解答:
<template>
<div class="list" ref="scrollRef">
<div
class="listItem"
:style="item.bgClass"
v-for="(item, index) in datas"
:key="index"
>
{{ index }}
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, nextTick, onMounted, watch } from 'vue';
// 随机生成的颜色
function randomColor(): void {
let bgColor = '#';
var str = '0123456789abcdef';
let bgArr = [];
for (var i = 0; i < 6; i++) {
let idx = parseInt(Math.random() * str.length);
bgColor += str[idx];
}
return bgColor;
}
// 获取数据
function getList(num): void {
let data = [];
for (var i = 0; i < num; i++) {
data.push({ id: i });
}
return data;
}
let datas = ref();
// 延迟2秒展示数据
setTimeout((): void => {
datas.value = getList(10);
// 根据数据的条数随机展示不同颜色n个div
datas.value.forEach((item, index) => {
item.bgClass = `background-color:${randomColor()}`;
datas.value[0].bgClass = 'background-color:rgb(233, 32, 38)'; // 默认颜色
});
}, 2000);
let scrollRef = ref(null);
onMounted(() => {
scrollRef.value.addEventListener('scroll', (event): void => {
console.log('@@@scrollRef', scrollRef.value.scrollTop, scrollRef.value);
});
});
// 滚动事件
</script>
<style scoped>
.list {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: hidden;
overflow-y: scroll;
}
.listItem {
width: 100%;
height: 500px;
}
</style>
注意:最后两题后台的不会老铁们!!!
8、按题目要求编写NestJS项目
请使用如:
等在线运行环境,完成项目的创建和编写,并分享编写后的项目地址做为答案
创建一个 Nest JS 项目,并按要求使用 TypeScript 完成项目:
1、 创建1个service\utils服务,提供一个double方法:接收一个数字num,返回num*2;
2、 app提供1个路径为 '/api/test' 的 POST请求方法,接收的请求体参数为 {num: 任意数字},其内部调用1的 utilsService.double(num) 方法进行运算后返回
3、 使用NestJS的ValidationPipe,在调用 '/api/test' 时对请求体参数进行自动校验,不符合的请求则返回错误
9、 按题目要求编写SQL代码
请使用如:sqlfiddle.com/postgresql/…等在线运行环境,完成项目的创建和编写,并分享编写后的项目地址做为答案。
请你在 MYSQL 的 test 数据库里,创建一张 广告表(table_name=ad):
| id (自增ID) | game_code (游戏) | expose (曝光度) | channel (渠道) | spend (渠道花费) |
|---|---|---|---|---|
| 1 | lol | 500 | A | 5 |
| 2 | cf | 300 | A | 10 |
| 3 | wzry | 1000 | B | 6 |
| 4 | pubgm | 800 | B | 11 |
| 5 | pubgm | 900 | A | 1 |
| 6 | lolm | 700 | A | 2 |
● 可自己本地搭建MYSQL服务,或者使用在线SQL引擎(如 sqlfiddle.com/)
● 要求使用 MYSQL 语法:
1、 写出 创建表 和 插入上述模拟数据 的SQL Build Schema语句
注意:业务中存在大量按指定game_code进行查询的需求,请考虑该场景进行设计
2、 写出 每个【channel】里最高【spend】的【game_code】SQL查询语句,最终呈现的结果如下:
| game_code | channel | spend |
|---|---|---|
| lol | A | 11 |
| wzry | B | 6 |
3、写出 按【game_code】、【channel】聚合,将【spend】和【expose】分别累加起来,并先按【spend】降序,再按【expose】升序排序,且分页查询(查询首页,一页2行记录)的SQL查询语句,最终呈现的结果如下:
| game_code | channel | spend | expose |
|---|---|---|---|
| pubgm | A | 12 | 1700 |
| cf | A | 10 | 300 |
4、在3的基础上,写出不分游戏,不分渠道,将【spend】的【game_code】分别做全量合计的SQL查询语句,最终呈现的结果如下:
| game_code | channel | spend | expose |
|---|---|---|---|
| - | - | 35 | 4200 |
5、在3的基础上,写出查询总页数的SQL语句,最终呈现的结果如下:
| total_page_num |
|---|
| 3 |