美文网首页
如果我是面试官系列之自己出笔试题

如果我是面试官系列之自己出笔试题

作者: Kagashino | 来源:发表于2019-02-13 16:38 被阅读0次

给定2个有序列表,求它们的交集

要点:有序的,可以设置2个“游标”,比较大小后,根据情况移动游标,直到遍历完为止,时间复杂度O(n)

function getJointSet (arrLeft,arrRight) {
    let joint = [], leftSize = arrLeft.length, rightSize = arrRight.length;
    if (leftSize === 0 || rightSize === 0) {
        return []
    }
    let l = 0, r = 0

    while ( l < leftSize && r < rightSize ) {
        if ( arrLeft[l] > arrRight[r] ) {
            r++;
        } else if ( arrLeft[l] < arrRight[r] ) {
            l++;
        } else if ( arrLeft[l] === arrRight[r] ) {
            joint.push(arrLeft[l])
            l++;
            r++;
        }
        console.log('没戏',arrLeft[l],arrRight[l])
    }

    return joint;
}

let js = getJointSet([1,2,4,5,7],[4,5,7,12,14,16,25,34])

console.log(js)

手写一个LRU(最近最少使用)算法

LRU,顾名思义,在限定长度的空间内,如果访问到一个存在的元素或者添加一个元素,则将这个元素放到队头。如果添加之前没有空间,就先弹出队尾的元素,再进行添加操作
要点:我的LRU基于双链表,熟悉双链表的基本都能实现

class Elem<E> {
  value: E
  next: Elem<E>
  prev: Elem<E>
  constructor  (value: E, prev = null, next = null) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
  valueOf():E {
    return this.value;
  }
}
interface LRUInterface<E> {
  get( param: Function|E|number, matchBox:boolean ): Elem<E>|E|null
  hit (elem: Elem<E>):void
  add( param: E ): boolean
  pop(): boolean
}

class LRU<E> implements LRUInterface<E> {
  head: Elem<E>
  tail: Elem<E>
  size: number
  limit: number
  static of (iterable: ArrayLike<any>): LRU<any> {
    const lru = new LRU(iterable.length);
    lru.head = iterable[0] || null;
    for( let i = 1; i<iterable.length; i++) {
      lru.add(iterable[i])
    }
    return lru;
  }
  constructor(limit:number) {
    this.head = null;
    this.tail = null;
    this.limit = limit;
    this.size = 0;
  }
  get( param: Function|E|number, matchBox:boolean = false ): Elem<E>|E|null  {
    if (this.size < 1) {
      return null;
    }
    let current = this.head;
    let index = 0;
    while (current && index < this.size ) {
      const currentValue = current.valueOf();
      if (typeof param === "number" && param === index) {
        this.hit(current);
        return currentValue;
      } else if ( typeof param === 'function' && !matchBox && param.call(this,current.valueOf(),index) ) {
        this.hit(current);
        return currentValue;
      } else if ( currentValue === param ) {
        this.hit(current);
        return matchBox?current:currentValue;
      } else {
        index += 1;
        current = current.next;
      }
    }
    return null;
  }
  hit (elem: Elem<E>):void {
    if (elem !== this.head && this.size > 1) {
      elem.prev.next = elem.next;
      elem.prev = null;
      const t = this.head;
      t.prev = elem;
      this.head = elem;
      elem.next = t;
    }
  }
  add( param: E ): boolean {
    const elem = new Elem(param)
    if( this.size === this.limit ){
      this.pop()
    }
    if (this.size === 0) {
      this.head = elem
      this.tail = elem
    } else {
      let t = this.head;
      this.head = elem;
      t.prev = elem;
      elem.next = t;
    }
    this.size += 1;
    return true;
  }
  pop(): boolean {
    if (this.size <= 0) {
      return false;
    } else if (this.size === 1) {
      this.head = null;
      this.tail = null;
      this.size = 0
    } else {
      const poped = this.tail;
      this.tail = this.tail.prev;
      this.tail.next = null;
      this.size -= 1;
    }
  }
}

实现一个单例模式,且不能直接调用(必须new构造)

要点:实现static

function SingleClass () {
  if ( !this instanceof SingleClass ) {
    thow Error('must construct with "new" operator!')
  }
  if (!SingleClass.instance){
   SingleClass.instance = this;
  }
  return SingleClass.instance;
}

实现一个事件订阅/发布类

自己实现一个bind函数

要点:原生bind传参规则、call/apply运用

Function.prototype.myBind = function (context) {
  var func = this
  var slice = Array.prototype.slice
  var restArguments = slice.call(arguments,1) //接受bind传入的载荷
  var bindFunc = function () {
    var afterArguments = slice.call(arguments) // 接收实例传入的载荷
    return func.apply(context,restArguments.concat(afterArguments))
  }
  // 绑过的函数不能再绑
  Object.defineProperty(bindFunc,'myBind',{
    value: function (){return bindFunc},
    configurable: false
  })
  return bindFunc
}

自己实现一个Promise

https://www.jianshu.com/p/d36f6f5f3372

用Promise函数封装XHR请求:

function httpRequest(url,userOption) {
        return new Promise ((res,rej)=>{
            const option = Object.assign({
                method: 'GET',
                headers: {},
            },userOption)

            const xhr = new XMLHttpRequest()

            if (option.method.toUpperCase() === 'GET' && option.params) {
                let queryString = /\?/.test(url)?'&':'?'
                let params = option.params
                for( let key of Object.keys(params) ) {
                    queryString += key + '=' + params[key] + '&'
                }
                url += queryString.substr(0,queryString.length-1)
            }
            // 打开
            xhr.open(option.method.toUpperCase(),url,true)
            // 请求头必须在打开后设置
            if (option.headers) {
                let headers = option.headers
                for (let key of Object.keys(headers) ) {
                    xhr.setRequestHeader(key,headers[key])
                }
            }

            xhr.onreadystatechange = ()=>{
                if (xhr.readyState === 4 ) {
                    let response = {
                        success: false,
                        status: xhr.status
                    }
                    if (xhr.status ===200) {
                        response.success = true
                        response.data = xhr.responseText
                        res(response)
                        option.callback && option.callback(response)
                    } else {
                        response.errorMsg = xhr.responseText
                        rej(response)
                        option.callback && option.callback(response)
                    }
                }
            }

            if(option.method.toUpperCase() ==='POST' || option.method.toUpperCase() ==='PUT' ){
                xhr.send(JSON.stringify(option.params))
            } else {
                xhr.send()
            }
        })
    }

Promise有什么缺点,async/await 如何解决这个问题

设想这样的场景,我想先从后端获取某个ID,再通过这个ID发起请求拿数据,即便使用Promise(以及promise化的API)一样也是回调地狱:

function getID () {
  return fetch('/get_id').then(res=>res.id)
}

function getDataByID (id) {
  return fetch(`/data/${id}`)
}

function gogogo () {
  getID().then(id=>{
    getDataByID(id).then(onData)
  })
}

function onData(res) {
  //  do sth with res
}

gogogo()
使用async/await解决上述问题:https://www.jianshu.com/p/220b7f3469d5

手写一个webpack4.0配置,要求:

  • 使用src/js下的index.js作为入口,打包后输出到src平级目录dist下,入口文件为dist/bundle.js
  • src/index.html同样输出为dist/index.html
  • 抽取JavaScript中导入的的css文件,输出为dist/style.css
  • 复制src/images下的文件到dist/images
  • 构建前删除上次构建过的文件
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    mode : 'production',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist')
    },
    module: {
        rules: [{
            test: /\.css$/,
            use: ExtractTextPlugin.extract({
                fallback: "style-loader",
                use: "css-loader"
            })
        }]
    },
    plugins: [
        // 加入 html 模板任务
        new HtmlWebpackPlugin({
            // 模板文件
            template: 'src/index.html',
            // 打包后文件名称,会自动放到 output 指定的 dist 目录
            filename: 'index.html'
        }),
        // 复制图片
        new CopyWebpackPlugin([{
            from : path.resolve(__dirname,'./src/images'),
            to : './images'
        }]),
        // 构建后清除原有dist插件
        new CleanWebpackPlugin('./dist',{
            verbose:  true,
            dry:      false
        }),
        new ExtractTextPlugin('style.css')
    ]
}

给定2个超出位数的正整数字符串,求它们和(大数相加)

原理:如同列竖式计算,把字符串分割为数组(JS中String对象不能直接通过下标修改,也没有StringBuffer这种东西),从最后往前加和。位数不同时低位需要补0(这个可以优化)

function add(strA, strB) {
    const b = strB.split(''), a = strA.split('')
    const bitDiff = a.length - b.length; //补零个数
    const needAdd = bitDiff > 0 ? b : a; // 需要补零的数组
    for (var i = 0; i < Math.abs(bitDiff); i++) {
        needAdd.unshift('0')
    }
    let bit = a.length - 1; //从个位算起
    let cache = 0; // 是否需要进位
    while (bit > 0 ) {
        var sum = parseInt( a[bit] ) + parseInt( b[bit] ) + cache;
        b[bit] = (sum%10) + ''; //先加个位
        cache = sum < 10? 0 : 1
        bit --;
    }
    b[bit] = parseInt( a[bit] ) + parseInt( b[bit] ) + cache; //处理最高位

    return b.join('');
}

var a = '11111111111111111111111111111', b = '555555555'

console.log('result--:' + r)

根据下面代码预期效果,实现Iterable函数

for (const [key, value] of Iterable({a:1, b:2, c:3}) ) {
  console.log(key, value) // 输出 a 1; b 2; c 3
}

解法: 这个题目按实现的方式可以判断一个人对JavaScript迭代的理解程度,这里提供一个基于Symbol.iterator的解法:

const Iterable = (object, callback) => {
  const assignable = !object[Symbol.iterator]
  console.assert(assignable, 'iterator already existed')
  if (!assignable) {
    return object;
  }
  object[Symbol.iterator] = typeof callback === 'function' ? callback : function* () {
    for (const key of Object.keys(this)) {
      yield [key, this[key]];
    }
  };
  return object;
};

相关文章

  • 如果我是面试官系列之自己出笔试题

    给定2个有序列表,求它们的交集 要点:有序的,可以设置2个“游标”,比较大小后,根据情况移动游标,直到遍历完为止,...

  • 京东二面,Redis为什么这么快?

    本期是【 大厂面试 】系列文章的第 6 期,模拟 Redis基础知识 高频面试题目。 面试开始 面试官: 今天聊聊...

  • 为什么 100 == 100, 200 != 200

    这是道蛮有意思的面试题。不废话,看题: 输出是多少? 运行下试试: 这是道极好的考察基础的面试题。如果我是面试官,...

  • 非技术面试题

    《2018 iOS面试题系列》 1、请你自我介绍一下你自己? 回答提示:这是面试官100%会问的问题,一般人回答这...

  • ios面试

    《2018 iOS面试题系列》 1、请你自我介绍一下你自己? 回答提示:这是面试官100%会问的问题,一般人回答这...

  • String类面试题

    String类的面试题,往往是面试的开端,如果String类的面试题都没有答好,那么给面试官的第一印象并不太好了 ...

  • 如何设计一个高并发系统?

    一、面试题 如何设计一个高并发系统? 二、面试官心理分析 说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶...

  • 41、如何设计一个高并发系统?

    1、面试题 如何设计一个高并发系统? 2、面试官心里分析 说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶...

  • 解剖前端面试之var

    说起这个var勾起了我太多回忆,尽管拒绝了笔试题还是被面试官要求看一下题目说出答案,现在是2020年4月12日,星...

  • string 的应用

    背、用、查 “Javascript+面试题+字符串” 搜一下这个 最著名的是回文 如果面试官不让用API,那...

网友评论

      本文标题:如果我是面试官系列之自己出笔试题

      本文链接:https://www.haomeiwen.com/subject/mqpdeqtx.html