欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

面试题总结

程序员文章站 2022-04-28 14:01:39
面试题总结 1、zookeeper如何实现分布式锁,以及羊群效应 zookeeper实现分布式锁主要基于同一个目录下节点名称不能重复的原理。 (1)先创建一个永久性的节点lock,临时节点下不能创建子节点 (2)线程在lock目录下依次创建临时有序节点(避免死锁)01,02,03...... (3) ......

1  JSON key 驼峰转换

实现一个转换函数covert,将JSON对象的下划线keys({a_jh_dhs: 99})转化为驼峰形式 {aIhDhs: 99}

function getCase(obj) {
  const reg = /_(.)/g
  function keyToCase(str) {
    if(typeof str !== 'string') return ''
    return str.replace(reg, (match, $) => {
      return $.toUpperCase()
    })
  }
  // []和{} 不包含null
  const isObject =  (obj) => typeof obj === 'object' && obj;
  // []
  const isArray = (arr) => Array.isArray(arr);
  // {}
  const isPlainObj = (obj) => isObject(obj) && !isArray(obj);


  function _getCase(obj) {
    if(!isObject(obj)) return null;

    if(isArray(obj)) {
      return obj.reduce((curr, next) => {
         curr.push(_getCase(next));
         return curr;
      },[])
    }

    let result = {};
    for(let key in obj) {
      const value = obj[key];
      const caseKey = keyToCase(key);
      if(isObject(value)) {
        result[caseKey] = _getCase(value);
        return result;
      }
      result[caseKey] = value
    }

    return result;
  }

  return _getCase(obj);
}

2 数组转数

var arr3 = [
  {
    menuId: 1,
    name: '系统管理1',
    parentMenu: null
  },
  {
    menuId: 2,
    name: '系统管理2',
    parentMenu: null
  },
  {
    menuId: 3,
    name: '系统管理1_0',
    parentMenu: 1
  },
  {
    menuId: 4,
    name: '系统管理1_1',
    parentMenu: 1
  },
  {
    menuId: 5,
    name: '系统管理2_0',
    parentMenu: 2
  },
  {
    menuId: 6,
    name: '系统管理5_0',
    parentMenu: 5
  },
  {
    menuId: 7,
    name: '系统管理3',
    parentMenu: null
  }
]
function arrToThree(arr) {
  const parentList = arr.filter(item => !item.parentMenu);
  const childList = arr.filter(item => item.parentMenu);
  function foo(par, chil) {
    par.forEach(ele => {
      chil.forEach((item) => {
        if(!ele.chilren) {
          ele.chilren = [];
        }
        if(ele.menuId === item.parentMenu) {
          ele.chilren.push(item)
        }
      })
      if(ele.chilren && ele.chilren.length) {
        foo(ele.chilren, childList)
      }
    });
  }
  foo(parentList, childList)
 return parentList;
}
console.log(arrToThree(arr3))

 

3 数字千位格式化

1283543 --> 1,283,543

0.5432143144 --> 0.543,214,314,4

1343.8593218 --> 1,343.859,321,8

 

function format(num) {
  if(typeof num !== 'number') return '';
  const dotReg = /\./;
  const reg = /\B(?=(\d{3})+\b)/g;
  const numStr = num + '';

  function strToReverse(str) {
    if(typeof str !== 'string') return ''
    return str.split('').reverse().join('')
  }

  if(dotReg.test(numStr)) {
    const arr = numStr.split('.');
    arr[0] = arr[0]  ? arr[0].replace(reg, ',') : '';
    const _temStr = strToReverse(arr[1]).replace(reg, ',')
    arr[1] =  arr[1] ? strToReverse(_temStr) : ''
    return arr.join('.')
  }

  return numStr.replace(reg, ',');

}
console.log(format(1234329)) // 1,234,329
console.log(format(12343.2904365)) // 12,343.290,436,5
console.log(format(0.2904365)) // 0.290,436,5

4 实现call, apply, bind方法

  • call
Function.prototype.mycall = function(obj) {
    var obj = obj || window;
    obj.fu = this;
    var args = [];
    for(var i = 1; i < arguments.length; i++ ) {
        args.push(arguments[i]);
    }
    var result = eval('obj.fu(' + args + ')')

    delete obj.fun;
    return result;
}

function add(a) {
   console.log(this.name, a)
}
var deep = {name: 99}

add.mycall(deep, 3)
  • apply
Function.prototype.myApply = function(obj, arr) {
    var obj = obj || window;
    obj.fun = this;
    if(!arr) {
        return obj.fun()
    }
    if( !(arr instanceof Array)) {
        throw new Error('第二个参数请输入数组')
    }
    var args = [];
    for(i = 0; i< arr.length; i++) {
        args.push(arr[i])
    }
    var result = eval('obj.fun('+ args+ ')');
    delete obj.fun;
    return result;
}

var deep = {name: '麦乐'};
function add(a) {
    console.log(this.name, a)
}
add.myApply(deep, [0, 9])

  •  bind
Function.prototype.myBind = function(obj) {
    var self = this;
    var bindArgs = Array.prototype.slice.call(arguments, 1);
    return function() {
        var args = Array.prototype.slice.call(arguments);
         // 如果 是new 的方式去调用,还需要让this指向实际例子 
        return self.apply((this instanceof self) ? this : obj, bindArgs.concat(args))
    }
    
    
}

var deep = {name: 'mailes'}

function add(a) {
    console.log(this.name, a)
}

var re = add.myBind(deep);

5.实现new

function Person(name) {
    this.name = name;
    return {
        name: '麦乐',
        age: 18
    }
}

Person.prototype.sayName = function() {
    console.log(this.sayName)
};


var person = new Person('麦乐');
console.log(person.name, person.age) // 麦乐 18

function objectFactory(fun) {
    var args = Array.prototype.slice.call(arguments, 1);
    var obj = Object.create(fun.prototype);
    const result  = fun.apply(obj, args);
    return result && obj;

}
var person = objectFactory(Person, '麦乐');
console.log(person)

6.

实现instanceof

function instanceOf(L, R) {
    if(!L || !R) return false;
    var L = L.__proto__;
    var R = R.prototype;
    console.log(R)
    while(true) {
        console.log(L)
        if(L == null) return false;
        if(R === L) {
            return true;
        }
        L = L.__proto__;
    }
}
console.log(instanceOf('9', Object))

7. 深拷贝循环引用?

8. 两个页面间实时通信

WindowEventHandlers.onstorage 属性包含一个在storage事件触发时的事件句柄。 

注意:该事件不在导致数据变化的当前页面触发(如果浏览器同时打开一个域名下面的多个页面,当其中的一个页面改变 sessionStorage 或 localStorage 的数据时,其他所有页面的  storage  事件会被触发,而原始页面并不触发 storage 事件)

window.onstorage = function(e) {
  console.log( e.key + ' 键已经从 ' + e.oldValue + ' 改变为 ' + e.newValue + '.');
};

 

 

本文地址:https://blog.csdn.net/qq_41831345/article/details/109243902