记一次今日头条前端笔试

V3hGkQ.jpg

# 第一题

  1. 点击表格单元格时输出单元格中的内容,表格的数据是异步获取的。
// 事件委托
document.querySelector('table').addEventListener('click', (event) => {
  if (event.target.tagName === 'td') {
    alert(event.target.innerHTML)
  }
})

// jQuery
$('table').on('click', 'td', function () {
  alert($(this).html())
})

# 第二题

  1. 对原码、反码、补码的理解,以及他们之间如何相互转换。
    前端的同学看到这题肯定无语了,感觉大厂还是喜欢问一些原理和底层的东西啊,即使你工作中可能根本用不到。网上搜到的头条面试也有同学被问到“http 工作原理”、“ajax 原理”、“javascript 基本类型和引用类型内存分配有什么区别”等等。

# 第三题

  1. 以下代码打印出什么
var x = 1
var func = function () {
  console.log(this.x)
}

var obj1 = { x: 1 }
var obj2 = { x: 2 }
var obj3 = { x: 3 }

var func1 = func.bind(obj1)
func1()

var func2 = func.bind(obj1).bind(obj2)
func2()

var func3 = func.bind(obj1).bind(obj2).bind(obj3)
func3()

答案是打印出三个 1。

# 第四题

  1. 实现以下布局,当页面内容超出浏览器窗口时,Footer 接在 Content 后面,未超出时 Footer 固定在页面底部。尽可能多的列出布局方案。 V3ha60.png
    感觉题意描述不是很清晰啊,没说只能用 css 还是 css 和 js 都能用,也没说兼容性要求。基础好的同学估计能想出一万种方法。我当时用 css 写了两种方法。
    方法一:
<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      .top-part {
        min-height: calc(100vh - 150px);
      }
      header {
        height: 100px;
        background: red;
      }
      content {
        display: block;
        background: blue;
        height: 500px;
      }
      footer {
        height: 150px;
        background: green;
      }
    </style>
  </head>
  <body>
    <div class="top-part">
      <header></header>
      <content></content>
    </div>
    <footer></footer>
  </body>
</html>

方法二:

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      .bottom-part {
        min-height: calc(100vh - 100px);
        display: flex;
        flex-direction: column;
        justify-content: space-between;
      }
      header {
        height: 100px;
        background: red;
      }
      content {
        display: block;
        background: blue;
        height: 500px;
      }
      footer {
        height: 150px;
        background: green;
      }
    </style>
  </head>
  <body>
    <header></header>
    <div class="bottom-part">
      <content></content>
      <footer></footer>
    </div>
  </body>
</html>

方案一可以兼容到 IE9,方案二由于使用了 flex 布局,只能兼容到 IE10。

# 第五题

  1. 日期转化函数。输入一个日期对象或时间戳或日期字符串,若它与当前时间相差少于 1 分钟,则输出“刚刚”;若小于两小时,则输出“xxx 分钟前”;若大于两小时,则输出“xxx 小时前”;若大于一天,则输出"xxx 天前";大于两天,则直接输出日期。
    转化为时间戳再比较就行了:
function dateTransform(date) {
  date = new Date(date).getTime()
  let now = new Date().getTime()
  let interval = (now - date) / 1000 / 60
  // 这里写一系列的if else判断就行了...
}

# 第六题

  1. 1234567890.12转化为123,456,789.12。要求用 js 的方法和正则的方法。
    对于外行人来说,程序员的正则就像道士的鬼画符。可惜我正则学的稀烂,当时直接把正则给 pass 掉了。于是开始用 js 的方法转化,当时想的是先取出小数部分,再对整数部分进行递归。结束后 Google 一下竟然发现数字还有toLocaleString方法,可以直接转换,有点想骂娘的心情了。附上标准答案:
// js方法
function numberTransform(num) {
  return num.toLocaleString()
}
// 正则方法
function numberTransform(num) {
  num = num.toString()
  let arr = num.split('.')
  return arr[0].replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + '.' + arr[1]
}

# 第七题

  1. 实现一个Event类,继承这个类的子类都有ononcetriggerremove方法。
    当时看到这题是懵比的,因为它题干就这么多。
class Event {
  constructor() {}
  on() {}
  once() {}
  trigger() {}
  remove() {}
}

按照题干的意思是这样就可以了。但是它这四个方法又像发布订阅模式的事件中心,于是我就把它改成了这样:

class Event {
  constructor() {
    this.evList = {}
  }
  on(evName, callback) {
    Reflect.set(this.evList, callback)
  }
  once(evName, param) {
    this.trigger(evName, param)
    this.remove(evName)
  }
  trigger(evName, param) {
    let fn = Reflect.get(this.evList, evName)
    if (!fn) return
    fn.call(null, param)
  }
  remove(evName) {
    Reflect.deleteProperty(this.evList, evName)
  }
}

# 第八题

  1. 把一堆乱七八糟的字符串转化为数组。
    没说用啥转化,转化后数组中还有字符串中不存在的字符。完全莫名其妙的题。

# 总结

对今日头条这种笔试方式略感失望啊,出题是用的牛客网这个平台,题目描述也写的不清不明,题目类型全部是问答题,有的明明是编程题。感觉自己被当成效率招聘的试验品了。