富途笔试
// 代码填空
function showmoney(){
return this.money; //此处为填空内容
}
var personA = new Object();
var personB = new Object();
personA.money = 100;
personB.money = 150;
personA.showmoney = showmoney;
personB.showmoney = showmoney;
console.log(personA.showmoney());
console.log(personB.showmoney());
// 代码填空
function obj(name){
if(name){
return {name: name}
}
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;
console.log(a.name);
console.log(b.name);
var obj = {
age: 18,
foo: function(func){
func();
arguments[0]();
}
};
var age = 10;
function temp(){
console.log(this.age);
}
obj.foo(temp);
// 这段CSS代码实现的效果是什么?(三角形)
width: 0;
height: 0;
border-top: 40px solid transparent;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
border-bottom: 40px solid #ff0000;
new Promise((resolve, reject) => {
reject();
}).then(function(){
console.log('success');
}, function(){
console.log('fail');
}).catch(() => {
console.log('catch');
});
// fail
BIGO笔试题
// 求字符串的序列号。 'A' -> 1, 'B' -> 2, ……,'AA' -> 27.
let fn = (str) => {
let res = 0;
for(let i = 0; i < str.length; i++){
res += (str.charCodeAt(i) - 'A'.charCodeAt(0)+ 1) * Math.pow(26, str.length - i - 1);
}
return res;
}
// 反过来,给出序列,求字符串
function fn(number){
let start = 'A'.charCodeAt(0);
let res = '';
let shang = 0;
let mod = 0;
while(Math.floor(number / 26) > 0 || (number % 26 !== 0)){
shang = Math.floor(number / 26);
mod = number % 26;
// console.log(mod);
if(mod === 0){
res = 'Z' + res;
shang--;
}else {
res = String.fromCharCode(mod+start-1) + res;
}
number = shang;
}
return res;
}
判断是否是数组的方法有哪些?
// 目前能想到的是下面五种
let arr = [1,2,3];
console.log(Object.prototype.toString.call(arr).indexOf('Array') !== -1);
console.log(arr instanceof Array);
console.log(Array.isArray(arr));
console.log(Array.prototype.isPrototypeOf(arr));
console.log(arr.constructor.toString().indexOf('Array') !== -1);
腾讯笔试题
//压缩算法
//小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压
缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为
[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的
同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么。
//我是利用栈来解这道题。
let fn = (s) => {
let stack = '';
let index = 0;
while(index < s.length){
if(s[index] !== ']'){
stack += s[index];
index++;
}else{
let temp = '';
while(stack[stack.length-1] !== '['){
temp = stack[stack.length-1]+temp;
stack = stack.substring(0,stack.length-1);
}
stack = stack.substring(0,stack.length-1);
let num = parseInt(temp);
let str = '';
let index1 = temp.indexOf('|');
temp = temp.substring(index1+1);
for(let i = 0; i < num; i++){
str += temp;
}
stack += str;
index++;
}
}
return stack;
}
腾讯笔试题
//小Q在周末的时候和他的小伙伴来到大城市逛街,一条步行街上有很多高楼,共有n座高楼排成一行。
小Q从第一栋一直走到了最后一栋,小Q从来都没有见到这么多的楼,所以他想知道他在每栋楼的位
置处能看到多少栋楼呢?(当前面的楼的高度大于等于后面的楼时,后面的楼将被挡住)
let fn = (arr,n) => {
let s = [];
let ans = [];
for(let i = 0; i < n; i++){
ans[i] = 1;
ans[i] += s.length;
while(s.length && s[s.length-1]<=arr[i]){
s.pop();
}
s.push(arr[i]);
}
s = [];
for(let i = n-1; i >= 0; i--){
ans[i] += s.length;
while(s.length && s[s.length-1]<=arr[i]){
s.pop();
}
s.push(arr[i]);
}
ans = ans.join(' ');
return ans;
}
CVTE二面
访问对象属性时,方括号和点的区别:主要是方括号可以用变量来遍历属性,如果属性名用的是关键字或者保留字,或者带空格,也可以用方括号来遍历。
HTTP请求的方法中,OPTIONS、TRACE、CONNECT是HTTP1.1才支持的。
//乱序输出一个数组
function random(arr){
let len = arr.length;
//let arr1 = [];
for(let i = 0; i < arr.length; i++){
let randomNum = Math.floor(Math.random()*len);
//arr1.push(arr[randomNum]);
[arr[randomNum],arr[i]] = [arr[i],arr[randomNum]];
}
return arr;
}
//将一个数组顺时针旋转九十度打印出来
//思路一
var rotate = function(matrix) {
for(let i = 0; i < matrix.length; i++){
for(let j = i + 1; j < matrix.length; j++){
[matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]
}
matrix[i].reverse();
}
return matrix;
};
//思路二
var rotate = function(matrix) {
let XLen = matrix.length;
for(let i = 0; i < XLen; i++){
for(let j = XLen-1; j >= 0; j--){
matrix[i].push(matrix[j][i])
}
}
for(let i = 0; i < XLen; i++){
matrix[i].splice(0,XLen)
}
};
拼多多一面面试题
console.log('start')
setTimeout(function(){
console.log('time')
})
Promise.resolve().then(
console.log(1)
)
console.log('end')
//考察Symbol.for()和Symbol的区别。
let a = Symbol.for(1) === Symbol.for(1)
let b = Symbol(1) === Symbol(1)
console.log(a);
console.log(b);
提取URL中的参数
let str = 'www.taobaao?a=1&b=2';
function f(str){
let str1 = str.slice(str.indexOf('?')+1);
let arr = str1.split('&');
let obj = {};
for(let i = 0; i < arr.length; i++){
let args = arr[i].split('=');
obj[args[0]] = args[1]
}
return obj
}
shopee一面面试题
var A = function() {};
A.prototype.n = 1;
var b = new A();
A.prototype = {
n: 2,
m: 3
}
var c = new A();
console.log(b.n);
console.log(b.m);
console.log(c.n);
console.log(c.m);
XSS攻击防御中CSP是谁来设置的。
是浏览器设置的,浏览器发出命令,服务器执行
CSP开启方式有两种。 juejin.cn/post/684490…
- 设置 HTTP Header 中的 Content-Security-Policy
- 设置 meta 标签的方式
shopee二面
1. 实现一个观察者模式 Observer 类。$on 注册监听事件,$emit 广播事件,$off 取消事件监听,注意 $off 可以取消监听指定的 handler 或所有指定事件。(隔了好几个月,终于写出一版啦)
const bus = new Observer();
const handler = function(name) { console.log(`hello ${name}`); };
bus.$on('customEvent', handler);
bus.$on('customEvent', handler.bind(this));
bus.$emit('customEvent', 'shopee');
bus.$off('customEvent', handler);
bus.$emit('customEvent', 'team');
// output:
// hello shopee
// hello shopee
// hello team
class Observer{
constructor(){
this.topics = {}
}
$on(topic, func){
if(!this.topics.hasOwnProperty(topic)){
this.topics[topic] = [];
}
this.topics[topic].push(func);
}
$emit(topic, info){
if(!this.topics.hasOwnProperty(topic)){return;}
this.topics[topic].forEach(func => {
func(info);
})
}
$off(topic, func){
let funcIndex = -1;
this.topics[topic].forEach((item, index) => {
if(item === func){
funcIndex = index;
}
})
if(funcIndex > -1){
this.topics[topic].splice(funcIndex,1);
}
}
};
const handler = function(name){
console.log(`hello, ${name}`);
}
const bus = new Observer();
bus.$on('cunstomEvent', handler);
bus.$on('cunstomEvent', handler.bind(this));
bus.$emit('cunstomEvent', 'shopee');
bus.$off('cunstomEvent', handler);
bus.$emit('cunstomEvent', 'team');
2. 实现 JS 函数式编程中的 compose 函数(可接收多个 function 用于组合,执行顺序从右到左,前函数的执行结果作为后函数的入参)
function compose(){
}
const add2 = num => num+2;
const fn1 = compose(add2);
console.log(fn1(3)); //执行后,打印 5
const sum = (a,b) => a+b;
const fn2 = compose(add2, sum);
console.log(fn2(3,2)); //执行后,打印 7
function compose(){
let funcs = Array.from(arguments);
return funcs.reduce(function(a,b){
return function(...args){
return a(b(...args))
}
})
}
网易互联网一面
const shape = {
radius: 10,
diameter() {
return this;
},
perimeter: () => {return this}
};
const temp = shape.diameter;
console.log(shape.perimeter());
console.log(shape.diameter());
console.log(temp());
百度一二三面
JSONP返回的数据格式是什么?
JSONP的本质是执行一段脚本。在前端定义好函数方法,后端服务器会调用这个方法,并传入参数,然后通过script或者img的src引入后端创建的脚本来加载这个方法。所以返回的其实是一个函数。
jpg和png有什么区别?
图片格式分三类。
- 无压缩。例:BPM
- 无损压缩。例:png
- 有损压缩。例:jpg
具体来说:
- gif: 无损压缩,支持透明和动画。缺点: 只能存8位颜色索引,不适用于色彩复杂,细节丰富的图片。
- jpg: 有损的基于直接色的图片格式。适合色彩丰富,有渐变色的图片。但是jpg不适合做icon, logo。因为相比png-8和gif,在文件大小上没有优势。
- png-8采用无损压缩,相比gif,对透明度的支持更好,同等质量下,尺寸更小。缺点:不支持动画。如果没有动画需,建议png-8替代gif。
- png-24:无损压缩。质量堪比bpm,但尺寸比bpm小,比jpg,gif和png-8大。支持透明。支持丰富色彩但大小比jpg大得多,约是jpg的5倍。
页面之间通信
面试官提到postMessage。实现窗口间通信。
React 和Vue的区别。
- vue支持数据双向绑定,react支持单项数据流。
- 监听数据实现变化的原理不用。Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能,React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的VDOM的重新渲染。
- React是在组件JS代码中,通过原生JS实现模板中的常见语法,比如插值,条件,循环等,都是通过JS语法实现的,Vue是在和组件JS代码分离的单独的模板中,通过指令来实现的,比如条件语句就需要 v-if 来实现。
美团一面
for...in, for...of, forEach的区别.
forEach不可以使用过return或者break来终止循环。
for...in循环的是可枚举对象(包括原型上的)的,for...of遍历的是不包括原型上的。
遍历数组时,for...in遍历属性名,for...of遍历属性值。for...of不能用来直接遍历对象,可以用Object.keys()或者Object.values()来遍历对象。
单冒号和双冒号的区别
单冒号表示伪类,双冒号表示伪元素
京东一面
position: sticky说一下
粘性定位是relative和fixed的混合。具体说来,在目标区域以内,sticky会让元素在页面滚动时如同在正常流中,当滚动到特定位置时,就会固定在屏幕上,如同fixed。指定top,left,right,bottom四个阈值其中之一,粘性定位才会生效。元素并不脱离文档流。
sticky的作用域:相对于离它最近的具有滚动框的父级元素的位置。
forEach和map的区别?
- forEach没有return, map有返回值。
- forEach改变原数组, map不改变原数组,会为返回值分配内存空间。
- 共同点:既可遍历数组,也可遍历对象。
选择器类型及优先级
- !important > 内联样式1000 >id选择器100>类选择器|伪类选择器10>标签选择器|伪元素选择器1>通用选择器0
如何取消事件冒泡
event.stopPropagation()或者ie下event.cancelBubble = true。
btn.onclick = function(event){
event.stopPropagation();
}
e.target 和 e.currentTarget区别?
e.target是事件触发的真正元素,e.currentTarget是注册事件处理程序的元素。
如何阻止特定事件的默认行为?
obj.onclick = function(event){
event.preventDefault()
}
只有cancel属性设为true的事件,才可以使用preventDefault()来取消事件的默认行为。
不同页面的localStorage可以共享吗?
同一浏览器的相同域名和端口的不同页面之间可以共享相同的localStorage(同域名下共享),但是不同页面之间无法共享sessionStorage的信息。
localStorage的值类型为string,也遵循同源策略。
字节跳动一面
//考察解构赋值
var a = x => x;
var b = x => {return x;};
var c = x => ({x});
console.log(a(1));
console.log(b(1));
console.log(c(1));
//注意空对象是两个不同的对象,set结构认为 NaN === NaN
let set = new Set([1,1,2,2,{},{},NaN,NaN]);
console.log(set.size);
//是同时打出还是每隔一秒打一次?输出是什么?如何修改为每秒打印一次?
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 5000);
}
var a = function () { this.b =3; }
var c = new a();
a.prototype.b = 9;
var b = 7;
a();
console.log(b)
console.log(c.b)
window.name = 'ByteDance';
function Foo () {
this.name = 'bar';
}
Foo.prototype.getName = function(){
console.log(this);
return this.name + 1;
}
let foo = new Foo();
let getName = foo.getName;
console.log(getName());
console.log(foo.getName());
console.log(getName.call(Foo));
算法题
删除字符串中出现次数 >= 2 次的相邻字符
输入:"abbbaca"
输出:"ca"
解释:"abbbaca" => "aaca" => "ca"
var removeDuplicates = function(S) {
let stack= [];
let index = 0;
while(index < S.length){
if(stack.length === 0 || stack[stack.length-1] !== S.charAt(index)){
stack.push(S.charAt(index));
index++;
}else{
while(stack[stack.length-1] === S.charAt(index)){
index++;
}
if(stack[stack.length-1] !== S.charAt(index)){
stack.pop();
}
}
}
let str = stack.join('');
return str
};
console.log(removeDuplicates('abbbacaccca')) //c
//
实现一个函数: 数字格式化问题:1234567890 --> 1,234,567,890
function formatCash(num) {
let str = num.toString();
let newStr = '';
for(let i = str.length-1; i >= 0; i--){
if(i%3===0 && i !== str.length -1){
newStr = str.charAt(i) + "," + newStr;
}else{
newStr = str.charAt(i) + newStr;
}
}
return newStr;
}
给定一个升序整形数组[0,1,2,4,5,7,13,15,16],
找出其中连续出现的数字区间为如下:["0->2", "4->5", "7", "13", "15->16"]
function summaryRanges(arr) {
let newArr = [];
let start = arr[0];
let index = 1;
let flag = false;
while(index < arr.length){
if(arr[index-1]+1 !== arr[index]){
flag = true;
}else{
index++;
}
if(flag){
if(start === arr[index-1]){
newArr.push(start.toString());
start = arr[index];
index++;
}else{
newArr.push(start + '->' + arr[index-1]);
start = arr[index];
index++;
}
}
}
return newArr;
}
斜45度打印二维矩阵
描述信息:对于一般的m * n矩阵a,第一条45度斜边:a0,第二条45度斜边:a0, a1
………
最后一条45度斜边:am - 1
例如:
input = [[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]]
output = 1, 2, 6, 3, 7, 11, 4, 8, 12, 5, 9, 13, 10, 14, 15
function printdialog(arr){
let rows = arr.length,
cols = arr[0].length,
res = [];
for(let i = 0; i < cols; i++){
let row = 0,
col = i;
while(row >= 0 && row < rows && col >= 0 && col < cols){
res.push(arr[row][col]);
row++;
col--;
}
}
for(let j = 1; j < rows; j++){
let row = j,
col = cols - 1;
while(row >= 1 && row < rows && col >= 0 && col < cols){
res.push(arr[row][col]);
row++;
col--;
}
}
return res;
}
请实现 DOM2JSON 一个函数,可以把一个DOM节点输出JSON的格式,例如下面的例子
function DOM2JSON(root) {
// 请实现这个函数
}
输入:
<div>
<span>
<a></a>
</span>
<span>
<a></a>
<a></a>
</span>
</div>
输出:
{
tag: 'DIV',
children: [
{
tag: 'SPAN',
children: [
{ tag: 'A', children: [] }
]
},
{
tag: 'SPAN',
children: [
{ tag: 'A', children: [] },
{ tag: 'A', children: [] }
]
}
]
}
两人在一个圆桌上『交替』放置圆形的棋子,棋子是有无穷多个。
要求棋子不能有重叠,也不能超出圆桌。
如果有一方不能再放置棋子,认为是输了。
问题:如果是先手,要用什么策略可以保证一定能赢?
Symbol数据类型的作用
独一无二,保证不与其他变量名产生冲突。
如何判断页面加载完毕?
1.用document.onreadystatechange = dosomething来监听状态的改变 document.readyState == 'complete'
2.window.onload = function(){}
3.vue中,mounted:{ this.$nextTick(()=>{"确保Dom异步加载完毕"}) }
页面加载readtState的五个状态:
0:Uninitialized未初始化
1:Loading载入
2:Loaded载入完成
3:Interactive交互,正在解析响应内容
4:Complete完成,响应内容解析完成,可以在客户端调用了
严格模式和非严格模式有什么区别?
严格模式下编写代码,更严谨规范,更安全,提高编译效率,提高运行速度,为未来新版本的JavaScript做准备。
开启严格模式,是在脚本或者函数的顶部加上字符串"use strict".
严格模式下,不能使用保留字作为变量名。
全局上下文this不再指向window,而是指向undefined.
字节二面
HTTPS和HTTP2的区别?
HTTP2采用新的二进制格式,多路复用,头部压缩,服务端推送。
省略号的实现(单行和多行)
//单行
{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
//多行
{
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
事件捕获和冒泡有兼容性问题吗?
IE8及以下不支持事件流。
GET和POST区别。
1.从缓存角度:GET请求会被浏览器缓存,而POST请求默认不会。
2.从编码角度:GET只能进行URL编码,只能接收 ASCII 字符,而 POST 没有限制。
3.从参数角度,GET请求参数放在URL中,不安全,POST放在请求体中,更适合传输敏感信息。
4.从TCP的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,
首先发header 部分,如果服务器响应 100(continue), 然后发 body 部分。
(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
如果要自己实现一个JSONP跨域,需要设置哪些API?
// 实现不算难
// 需要的API: document.createElement(), document.body.appendChild(),
document.body.removeChild(), promise
const jsonp = ({url, params, callbackName}) => {
const generateUrl = () => {
let dataStr = '';
for(let key in params){
dataStr += `${key}=${params[key]}&`;
}
dataStr += `${callback}=${callbackName}`;
return `${url}?${dataStr}`;
}
return new Promise((resolve, reject) => {
let scriptElement = document.createElement('script');
scriptElement.src = generateUrl();
document.body.appendChild(scriptElement);
window[callbackName] = (data) => {
resolve(data);
document.body.removeChild(scriptElement);
}
})
}
jsonp({
url: 'http://localhost:3000',
params: {
a: 1,
b: 2
},
callbackName: 'xxx'
}).then((data) => {
console.log(data);
})
// JSONP跨域的缺点
// 1.不安全,如果请求的资源中有恶意代码,没办法追究。
// 2.需要提供JSONP接口
// 3.只支持GET请求
// JSONP跨域的优点
// 兼容性好,CORS跨域不支持IE低版本浏览器
哪些事件不能冒泡?
- UI事件load, unload, resize, error
- 焦点事件:blur, focus
- 鼠标事件:mouseleave, mouseenter
发微信是属于TCP还是UDP?
TCP。
对元素设置margin-left,margin-top为负值,与设置margin-right,margin-bottom为负值时有何不同?
前两个是相对于自身而言。后两个是相对于其他元素而言。
京东二面
路由的导航守卫有哪些?
- 全局前置守卫
- 全局解析守卫
- 全局后置钩子
- 路由独享的守卫
- 组件内的守卫
出现白屏的原因有哪些,怎么定位问题?
面试官讲到,先打开控制台,查看HTML,CSS部分有没有问题,再看资源有没有获取到,然后还可以检查babel转义是否正确。(大概记了下,没有记全)