每天嚼烂5道精选面试题,中高级工程师的进阶之路(day01)

Posted 贪吃ღ大魔王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天嚼烂5道精选面试题,中高级工程师的进阶之路(day01)相关的知识,希望对你有一定的参考价值。


程序员才懂的哪些事儿:

在这里插入图片描述




1、封装一个方法,要求把给定的任意的 IP 字符串,转化成 32 位的二进制字符串。

思路:

  1. 用 split()将 ip 炸开,进行遍历
  2. 将每个截断转为数字,再转为二进制字符串
  3. 如果截断的长度不够八位,需要补够八位
  4. 存入数组,转为字符串

实现步骤:

  1. 用 split()将 ip 炸开,用 list 接收
        function toget(ip) {
            let list;
            list = ip.split('.')
            console.log(list);
  		}
        toget('172.1.1.1');

得到的 list 是一个数组:

在这里插入图片描述

  1. 遍历 list,将每个字符串转为数字,再转为二进制,使用 toString(2)
for (let i = 0; i < list.length; i++) {
                str = (list[i] - 0).toString(2)  
                console.log(str);
            }

得到四段二进制的字符串:
在这里插入图片描述
这里发现如果进行拼接的话,组成的字符串不是32位,并不符合题目要求。所以需要进行判断

  1. 如果转化后的二进制字符串不是八位,则需要补够八位,这里可以使用 padStart()
for (let i = 0; i < list.length; i++) {
                str = (list[i] - 0).toString(2)
                if (str.length < 8) {
                    str = str.padStart(8, '0')
                }
                console.log(str);
            }

也可以使用 str = '0' + str

同样可以得到所需要的八位字符串:
在这里插入图片描述

  1. 将每段字符串存入到数组中,再转为字符串
arr.push(str)
console.log(arr.join(''));

实现效果:

在这里插入图片描述

完整实现代码:

function toget(ip) {
            let list = [];
            let str = ''
            list.push(ip.split('.')[0], ip.split('.')[1], ip.split('.')[2], ip.split('.')[3])
            for (let i = 0; i < list.length; i++) {
                str += list[i].charCodeAt().toString(2)
            }
            console.log(str);
        }
        toget('172.0.0.1');



2、求出现次数最多的字符、出现了多少次。

思路:

  1. 由于需要判断出现的次数,这里选择使用对象存入字符
  2. 遍历字符串,判断 obj 对象中是否存在该字符串
  3. 如果不存在,则设置位对象的属性 key,且属性值设为 1
  4. 如果存在,则这个属性的属性值加 1
  5. 假设最大字符和最大次数 max ; 遍历对象,如果最大次数 max 小于某属性的属性值,那么 max 等于这个属性值,最大字符等于这个属性

实现步骤:

  1. 遍历字符串,判断 obj 对象中是否存在该字符串
  2. 如果不存在,则设置位对象的属性 key,且属性值设为 1
  3. 如果存在,则这个属性的属性值加 1
 function getMax(str) {
            let obj = {}
            for (var i = 0; i < str.length; i++) {
                var char = str.charAt(i)
                if (obj[char]) obj[char]++
                else obj[char] = 1
            }
            console.log(obj);
        }
        getMax('wszxdswsasfdwsvgope')

打印这个对象,查看 obj
在这里插入图片描述

  1. 假设最大字符和最大次数 max ; 遍历对象,如果最大次数 max 小于某属性的属性值,那么 max 等于这个属性值,最大字符等于这个属性
			let t = ''
            let max = 0;
            for (var key in obj) {
                if (obj[key] > max) {
                    max = obj[key]
                    t = key
                }
            }
            console.log('出现最多的字符是:' + t, '\\n次数是:' + max);

实现效果:

在这里插入图片描述

完整实现代码:

 function getMax(str) {
            let obj = {}
            for (var i = 0; i < str.length; i++) {
                var char = str.charAt(i)
                if (obj[char]) obj[char]++
                else obj[char] = 1
            }
            let t = ''
            let max = 0;
            for (var key in obj) {
                if (obj[key] > max) {
                    max = obj[key]
                    t = key
                }
            }
           console.log('出现最多的字符是:' + t, '\\n次数是:' + max);
        }
        getMax('wszxdswsasfdwsvgope')



3、封装冒泡排序算法 sortMe() 。

一句话概括冒泡排序:

  • 依次对数组中相邻数字进行比较(两两比较),大的放后面

理解:

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.
  • 在这一点,最后的元素应该会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

思路:

  1. 两层循环,第一次循环是比较的趟数 i 从0开始 寻找规律 i < arr.length - 1
  2. 第二层循环,负责比较次数 j 从0开始 寻找规律 i < arr.length - i - 1
  3. 前一个数比 比较的数大,进行交换

<例图供参考>

在这里插入图片描述

实现步骤:

  1. 两层循环,第一次循环是比较的趟数 i 从0开始 寻找规律 i < arr.length - 1
  2. 第二层循环,负责比较次数 j 从0开始 寻找规律 i < arr.length - i - 1
 for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - i - 1; j++) {
                    if (arr[j] > arr[j + 1]) {
                    }
                }
            }
  1. 前一个数比 比较的数大,进行交换
				num = arr[j]
                arr[j] = arr[j + 1]
               	arr[j + 1] = num

实现效果:
在这里插入图片描述
完整实现代码:

function sortMe(arr) {
            let num = 0
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - i - 1; j++) {
                    if (arr[j] > arr[j + 1]) {
                        num = arr[j]
                        arr[j] = arr[j + 1]
                        arr[j + 1] = num
                    }
                }
            }
            console.log(arr);

        }
        sortMe([5, 9, 1, 7, 4, 2, 5])



4、使用 Promise 封装 $.ajax,得到 request() 。

思路:

  1. 理解回调函数,同步异步,Promise对象
  2. 使用 jQuery 封装 ajax 请求,包括请求方法method、请求地址path、请求成功回调successCallback请求失败回调failCallback、请求头headers、响应体body
  3. 正常的ajax请求步骤,需要先遍历请求头,再设置请求头
  4. 请求成功执行成功回调,请求失败执行失败回调
  5. 使用promise 封装改造

理解:

  • 什么是回调函数 Callback ?

callback 是一种特殊的函数,这个函数被作为参 数传给另一个函数去调用。

常见实例:

$button.on('click', function(){})
click后面的 function 就是一个回调,用户点击 button 时调用的(当用户点击之后,这个函数才执行,现在我只是传了一个参数,这个参数是一个点击后要执行的函数)。
div.addEventListener('click', function(){})
click 后面的 function 也是一个回调,是浏览器在用户点击 button 时调用的。
一般来说,只要参数是一个函数,那么这个函数就是回调。

一般,在 执行异步任务的时候,就会使用 callback。

  • 什么是异步?

JS 引擎不能同时做两件事。

同步:一定要等任务执行完了,得到结果,才执行下一个任务

异步:不等任务执行完,直接执行下一个任务。

常见异步:定时器,延时器,ajax请求…

  • 什么是Promise?

简单来理解:Promise 是一个对象,通过返回这个promise对象,再调用他的then()和 catch()可以来解决异步

  • $.ajax()函数会返回一个promise,然后在后面.then(success,fail)时候,如果成功了就会调用第一个参数里的函数即success函数,如果失败了就会调用第二个参数的函数即fail函数.

第一次封装:

window.jQuery.ajax = ({method,path,body,successFn,failFn,headers})=>{
    
    let request = new XMLHttpRequest();
    request.open(method,path);//配置

    for (const key in headers) {//遍历header,设置响应头
        let value = headers[key];
        request.setRequestHeader(key,value);
    }
    request.send(body);//发送,并配置响应体

    request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            if ( request.status>=200&&request.status<=400){
                successFn.call(undefined,request.responseText);//执行成功函数
            }else if(request.status>=400){
                failFn.call(undefined,request);//执行失败函数
            }
        }
    }
}

再次封装:使用promise 简单改造

完整实现代码:

window.jQuery.ajax = ({ method, path, body, headers }) => {
            // 返回一个promise对象 resolve, reject 获取异步数据
            return new Promise((resolve, reject) => {
                let request = new XMLHttpRequest()
                request.open(method, path) //配置

                 //遍历headers 设置响应头
                for (const key in headers) {
                    let value = headers[key]
                    request.setRequestHeader(key, value)
                }

                //配置响应体  发送请求
                request.send(body)
                request.onreadystatechange = function () {
                    if (request.readyState === 4) {
                        if (request.status === 200) {
                            //执行成功函数
                            resolve.call(undefined, request.responseText)
                        } else {
                            reject.call(undefined, request)
                        }
                    }
                }
            })
        }

使用方法:

这里我们使用 cnode开源的api 请求数据:https://cnodejs.org/api

 let myButton = document.getElementById('myButton');

        myButton.addEventListener("click", (e) => {
            //使用ajax
            $.ajax({
                method: "get",
                path: "https://cnodejs.org/api/v1/topics",
                body: "username=mtt&password=1",
                headers: {
                    "content-type": 'application/x-www-form-urlencoded',
                    'ws': 18,

                }
            }).then(
                (responseText) => { console.log(responseText); },//成功就调用这个函数
                (request) => { console.log(request); }//失败就调用这个函数
            )
        })

实现效果:

在这里插入图片描述
在这里插入图片描述



5、有哪些数组去重的方法?(至少3种)

方法:

  1. splice() 去重
  2. indexOf() 去重
  3. Set() 去重
  4. sort() 去重
  5. 递归去重
  6. 对象的属性的特点 去重

1.splice() 去重 ES5常用

思路:

  1. 遍历数组,第一次循环负责趟数
  2. 第二次循环判断是否相等进行去重,如果循环的数组元素与下一个相等则去重

完整实现代码:

 function delArr(arr) {
            for (var i = 0; i < arr.length; i++) {
                for (var j = i + 1; j < arr.length; j++) {
                    if (arr[i] == arr[j]) {         //第一个等同于第二个,splice方法删除第二个
                        arr.splice(j, 1);
                    }
                }
            }
            console.log(arr);
        }
        delArr([2, 5, 9, 4, 2, 5, 3, 9, 2, 4])

实现效果:
在这里插入图片描述

2.indexOf() 去重

思路:

  1. 创建新数组 list用来存放,遍历数组 arr
  2. 使用 indexOf()来判断 新数组list中是否存在arr[i]
  3. 如果不存在,indexOf()==-1 则将 arr[i]存入新数组 list

完整实现代码:

function delArr(arr) {
            var list = [];
            for (var i = 0; i < arr.length; i++) {
                if (list.indexOf(arr[i]) === -1) {
                    list.push(arr[i])
                }
            }
            console.log(list);

        }
        delArr([1, 3, 5, 7, 5, 3, 7, 1, 5])

实现效果:

在这里插入图片描述


3.Set() 去重 ES6常用

思路:

  1. 遍历数组,直接使用new set()方法

完整实现代码:

function delArr(arr) {
            let list = new Set(arr)
            console.log(list);

        }
        delArr([1, 3, 5, 7, 5, 3, 7, 1, 5])

实现效果:
在这里插入图片描述
这里也可以直接使用 es6 的 … 语法

console.log([...new Set(arr)]);

4.sort() 去重

思路:

  1. 使用sort()方法先将 arr 数组进行排序
  2. 创建新数组list,遍历数组arr 如果当前元素arr[i] 不等于上一个元素arr[i-1] 则将当前元素arr[i]放入新数组中
  3. 如果当前元素为 arr[1]时,则它的上一个元素时 arr[0],我们需要在创新新数组list时,把 arr[0] 存入

完整实现代码:

function delArr(arr) {
            arr = arr.sort()
            var list = [arr[0]];
            for (var i = 1; i < arr.length; i++) {
                if (arr[i] !== arr[i - 1]) {
                 console.log(arr[i - 1]);
                    list.push(arr[i]);
                }
            }
            console.log(list);

        }
        delArr([1, 3, 5, 7, 5, 3, 7, 1, 5])

实现效果:
在这里插入图片描述


5.递归去重

思路:

  1. 先使用sort()先将数组arr进行排序,为了去重更加方便
  2. 使用递归,设置递归终止条件,index>=1
  3. 如果当前元素等于上一个元素,则用`splice(index,1)进行截取

完整实现代码:

function delArr(arr) {
       

以上是关于每天嚼烂5道精选面试题,中高级工程师的进阶之路(day01)的主要内容,如果未能解决你的问题,请参考以下文章

每天嚼烂5道精选面试题,中高级工程师的进阶之路(day01)

每天嚼烂5道精选面试题,中高级工程师的进阶之路(day01)

精选面试题教你应对高级iOS开发面试官(提供底层进阶规划蓝图)

Python面试大全PDF(245道Python面试题)

Android高级工程师每日面试题精选,offer拿到手软

2021精选1万道大厂Java中高级面试题,面试官能问到的都有