面试题(11)之 大厂外包面试题

写在前面:

一年没有面试了,约了一个外包面试,去大厂,就当我去检测我这1年的成果了。

1 变量提升

var a = 1
function a() {
  return 2
}
console.info(a) // 1
console.info(typeof a) // number

 

2 异步

for(var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.info(i)
  });
}
// 3 3 3

 

3 随机排序

实现一个方法,将有序的数组变为乱序

// 解法一
function getRandomArr(arr) {
  let len = arr.length
  let randomIndex = Math.floor(Math.random() * len)
  let temp
  while(len >= 0) {
    temp = arr[randomIndex]
    arr.splice(randomIndex, 1)
    arr.push(temp)
    len--
    randomIndex = Math.floor(Math.random() * len)
  }
  return arr
}

 

// 解法二
function getRandomArr(arr) {
  /* 每次循环时都要与第i项互换位置 */
  for (var i = 0; i < arr.length; i++) {
    var j = parseInt(Math.random() * arr.length)
    /* 将所获取的数和第i个数互换位置 */
    var temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
  }
  return arr
}

 

// 解法三
function getRandomArr(arr) {
  arr.sort(() => {
    return (0.5-Math.random())
  })
  return arr
}

 

4 绑定DOM事件

实现一个绑定DOM事件的js函数,可兼容多种浏览器

4.1 方法一
<button id="mydiv">点击触发事件</button>
<script>
    /* 因为 JavaScript 中所有对象都集成与 Object,那么只有给Object原型添加一个事件绑定函数,
     就不需要在处理绑定事件的时候,每次写一长串代码,直接调用即可。 */
    // ev 事件属性
    // fn 触发事件
    Object.prototype.addListener = function (ev, fn) {
        if (this.attachEvent) { // 兼容IE9 IE10 
            alert('a')
            this.attachEvent('on' + ev, fn)
        } else { // 兼容:firefox、chrome、IE、safari、opera
            alert('v')
            this.addEventListener(ev, fn, false)
        }
    }
    var mydiv = document.getElementById("mydiv")
    mydiv.addListener('click', click1, false)
    function click1() {
        alert("click1")
    }
</script>

 

4.2 方法二
function addEvent(ele, type, func) {
    if(ele.addEventListener()) {
        // Chrome
        ele.addEventListener(type, func)
    } else {
        // IE浏览器
        ele.attachEvent('on' + type, func)
    }
}

 

5 问题:减少页面首次请求加载的方式有哪些

前端优化清单(一):之首屏优化

  1. 首屏最小化

    首屏HTML尽量小,控制DOM节点数、请求数、外链数

  2. 元素优化

    优化落在首屏内的元素性能和结构,包括基础页、元素请求、图片、JS、是否调用第三方内容、层次机构等。

  3. 页面静态化

    首屏页包含了页面基础页时间(第一次请求),以屏内的元素总的DNS解析时间,建立连接时间,SSL握手时间,发出请求时间,重定向时间,内容下载时间等。

  4. 基础页优化 以静态页面的形式存放,用户相关数据依赖Ajax,比如登录信息。用户默认显示未登录状态,异步获取到用户数据后更新。

  5. 首屏广告优化 重点减少广告JS的下载次数,减少状态上报次数,避免iframe。同时处理脚本放在页面底部,修改广告的载入顺序,避免影响页面显示。

  6. 首屏按需加载 隐藏tab页,用了异步加载的方式,只有当用户正在要看这块内容的时候才去拉取。

  7. 单独合并素材 将代发布的源文件进行压缩合并,减少文件数量,授权请求最少原则。

  8. 统计代码优化 针对用户行为统计代码如(CNZZ,百度统计等),进行去除冗余,统一放到首屏后加载。

 

6 如何避免出现XSS漏洞

  1. 输入过滤。永远不要相信用户的输入,对用户输入的数据做一定的过滤。如输入的数据是否符合预期的格式,比如日期格式,Email格式,电话号码格式等等。这样可以初步对XSS漏洞进行防御。上面的措施只在web端做了限制,攻击者通抓包工具如Fiddler还是可以绕过前端输入的限制,修改请求注入攻击脚本。因此,后台服务器需要在接收到用户输入的数据后,对特殊危险字符进行过滤或者转义处理,然后再存储到数据库中。

  2. 输出编码。服务器端输出到浏览器的数据,可以使用系统的安全函数来进行编码或转义来防范XSS攻击。在PHP中,有htmlentities()和htmlspecialchars()两个函数可以满足安全要求。相应的JavaScript的编码方式可以使用JavascriptEncode。

  3. 安全编码。开发需尽量避免Web客户端文档重写、重定向或其他敏感操作,同时要避免使用客户端数据,这些操作需尽量在服务器端使用动态页面来实现。

  4. HttpOnly Cookie。预防XSS攻击窃取用户cookie最有效的防御手段。Web应用程序在设置cookie时,将其属性设为HttpOnly,就可以避免该网页的cookie被客户端恶意JavaScript窃取,保护用户cookie信息。

  5. WAF(Web Application Firewall),Web应用防火墙,主要的功能是防范诸如网页木马、XSS以及CSRF等常见的Web漏洞攻击。由第三方公司开发,在企业环境中深受欢迎。

 

7 CSS 如何实现div上下左右居中

未布局前的样式:

    .fa {
      width: 300px;
      height: 300px;
      background-color: #f5f5f5;
    }
    .son {
      width: 100px;
      height: 100px;
      background-color: #979191;
    }

  <div class="fa">
    <div class="son"></div>
  </div>
7.1 标准流居中
/* 前提:已知父子div的宽高 */
.fa {
    overflow: hidden; /* BFC */
}
.son {
    margin: 100px auto;
}
7.3 定位 + margin
.fa {
    position: relative;
}
.son {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -50px;
    margin-top: -50px;
}
7.4 flex
.fa {
    display: flex;
    justify-content: center;
    align-items: center;
}
7.5 grid
.fa {
    display: grid;
    grid-template-columns: 33.3% 33.3% 33.3%;
    grid-template-rows: 33.3% 33.3% 33.3%;
}
.son {
    /* 开始于第2条行网格线,结束于第3条行网格线 */
    grid-column: 2/3;
    /* 开始于第2条列网格线,结束于第3条列网格线 */
    grid-row: 2/3;
}

 

8 判断二维空间中的一个点是否在线段上

    // 实现一个函数,判断二维空间中的一个点是否在线段上
    // 思路:该点分别到这两点的距离 是否等于 这俩点距离之和
    const pointA = { x: 1, y: 4 }
    const pointB = { x: 4, y: 1 }
    let onePoint = { x: 2, y: 3 }
    let otherPoint = { x: 3, y: 1 }
    function isInLine(pointA, pointB, target) {
      let distanceA = distance(pointA, target)
      let distanceB = distance(pointB, target)
      let distanceAB = distance(pointA, pointB)
      return distanceA + distanceB === distanceAB ? 'true': 'false'
    }

    function distance(first, second) {
      let num = Math.pow((first.x - second.x), 2) + Math.pow((first.y - second.y), 2)
      return Math.round(Math.sqrt(num))
    }
    console.log(isInLine(pointA, pointB, onePoint)) // 'true'
    console.log(isInLine(pointA, pointB, otherPoint)) // 'false'

 

9 树形结构

当时面试官问我保存的str1存在那里,现在才知道,存在原型

有一个树形结构:

var data = {
  key1: 'str1',
  key2: {
    key3: 'str3',
    key4: 'str4',
    key5: {
      ket6: 'str6'
    }
  }
}

实现一个方法getKeys(data, str),获取字符串 str 在 data 中所有的上级节点名称,例如:

getKeys(data, 'str1') 返回 'key1'

getKeys(data, 'str3') 返回 'key2 key3'

getKeys(data, 'str6') 返回 'key2 key5 key6'

以下解法有问题,但是思路很好

解法一
var data = {
  key1: 'str1',
  key2: {
    key3: 'str3',
    key4: 'str4',
    key5: {
      key6: 'str6',
      key7: {
        key8: 'str8'
      }
    }
    // ...
  }
}

function getKeys(data, str) {
  for(let key in data) {
    if(typeof data[key] == 'string' && data[key] == str) {
      this.keyName ? this.keyName += key: this.keyName = key
      return this.keyName
    } else if(typeof data[key] == 'object') {
      // keyName += key
      // keyName += ' '
      this.keyName ? this.keyName += key: this.keyName = key
      this.keyName += ' '
      return getKeys(data[key], str)
    }
  }
}

getKeys.prototype.keyName = ''

console.info(getKeys(data, 'str8'))

 

解法二
function  getKeys(data,str){
  var result=[];
  function recursion(data,str){
      for(var key in data){
          if(data[key] == str){
              result.push(key);
              return result;
          }
          if(typeof data[key] == 'object'){
              result.push(key);
              return recursion(data[key],str)
          }
      }
  }
  recursion(data,str);

 

转载于:https://www.cnblogs.com/houfee/p/11148034.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值