前端面试手撕编程

目录

ES6

改变this

call

[typeof this !== 'function'](#typeof this !== 'function')

[context = context || window](#context = context || window)

[context._this = this](#context._this = this)

[delete context._this](#delete context._this)

[bind: return _this.apply(context, [...arguments].slice(1));](#bind: return _this.apply(context, [...arguments].slice(1));)

深拷贝

[!arr|| arr == null || typeof arr != 'object'](#!arr|| arr == null || typeof arr != 'object')

[arr instanceof Array ? [] : {}](#arr instanceof Array ? [] : {})

for (const key in arr)

[result[key] = cloneDeep(arr[key])](#result[key] = cloneDeep(arr[key]))

算法

合法的URL

[千位分割:num.slice(render, len).match(/\d{3}/g).join(',')](#千位分割:num.slice(render, len).match(/\d{3}/g).join(','))

公司*

用友sp

一面【二选一】

数组相邻和最大的对应两个元素

千位分割【无负数,含小数】

二面

华容道:BFS

[k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标](#k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标)

swap(t[k],t[a*3+b]);

版本号排序:【滴滴提前批】


ES6

改变this

call

typeof this !== 'function'

context = context || window

context._this = this

delete context._this

javascript 复制代码
    // 给function的原型上面添加一个 _call 方法
    Function.prototype._call = function (context) {
        //  判断调用者是否是一个函数  this 就是调用者
        if (typeof this !== 'function') {
           throw new TypeError('what is to be a function')
        }
        // 如果有 context 传参就是传参者 没有就是window
        context = context || window
        // 保存当前调用的函数
        context._this = this   
        // 截取传过来的参数
        /*
          arguments
                 a: 1
                 fn: ƒ fns()
        */
        // 通过 slice 来截取传过来的参数
        const local = [...arguments].slice(1)
        // 传入参数调用函数
        let result = context._this(...local)
        // 删属性
        delete context._this
        return result
    }

    let obj = { a: 1 }
    function fns(a, b) {
        console.log(a, b);
        console.log(this)
    }
    fns._call(obj, 23, 555)

bind: return _this.apply(context, [...arguments].slice(1));

深拷贝

!arr|| arr == null || typeof arr != 'object'

arr instanceof Array ? [] : {}

for (const key in arr)

result[key] = cloneDeep(arr[key])

javascript 复制代码
 function cloneDeep(arr = {}) {
        // 终止递归 
        if (!arr|| arr == null || typeof arr != 'object' ) return arr
        // 用 instanceof 判断原型链上是否有该类型的原型 是 Array => [] ! Arrays =>{}
        let result=arr instanceof Array ?  [] :  {}
        // forin 循环对象的key值
        for (const key in arr) {
            //  对象 key 赋值 result
            result[key] = cloneDeep(arr[key])
        }
        return result
   }

算法

合法的URL

URL结构一般包括协议、主机名、主机端口、路径、请求信息、哈希

  1. 域名不区分大小写:"www"子域名(可选)、二级域名、"com"顶级域名
  2. 只能包含字母(a-z、A-Z)、数字(0-9)和连字符(-)(但-不能再首尾)
javascript 复制代码
https://www.bilibili.com/video/BV1F54y1N74E/?spm_id_from=333.337.search-card.all.click&vd_source=6fd32175adc98c97cd87300d3aed81ea
//开始:                     ^
//协议:                     http(s)?:\/\/
//域名:                     [a-zA-Z0-9]+-[a-zA-Z0-9]+|[a-zA-Z0-9]+
//顶级域名 如com cn,2-6位:   [a-zA-Z]{2,6}
//端口 数字:                (:\d+)?
//路径 任意字符 如 /login:   (\/.+)?
//哈希 ? 和 # ,如?age=1:    (\?.+)?(#.+)?
//结束:                      $
//     https://           www.bilibili                com    /video/BV1F54y1N74E  ?spm..            
/^(http(s)?:\/\/)?(([a-zA-Z0-9]+-[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)+([a-zA-Z]{2,6})(:\d+)?(\/.+)?(\?.+)?(#.+)?$/.test(url)

千位分割:num.slice(render, len).match(/\d{3}/g).join(',')

javascript 复制代码
  const format = (n) => {
        let num = n.toString() // 拿到传进来的 number 数字 进行 toString
        let len = num.length // 在拿到字符串的长度
        // 当传进来的结果小于 3 也就是 千位还把结果返回出去 小于3 不足以分割
        if (len < 3) {
            return num
        } else {
            let render = len % 3 //传入 number 的长度 是否能被 3 整除
            if (render > 0) { // 说明不是3的整数倍
                return num.slice(0, render) + ',' + num.slice(render, len).match(/\d{3}/g).join(',')
            } else {
                return num.slice(0, len).match(/\d{3}/g).join(',')
            }
        }
    }

    let str = format(298000)
    console.log(str)

公司*

用友sp

一面【二选一】

数组相邻和最大的对应两个元素

千位分割【无负数,含小数】

javascript 复制代码
function formatNumberWithCommas(number) {
    // 将数字转换为字符串
    const numStr = number.toString();
    
    // 判断是否为小数
    const isDecimal = numStr.includes('.');
    
    // 如果是小数,分割整数部分和小数部分
    let integerPart = numStr;
    let decimalPart = '';
    if (isDecimal) {
        [integerPart, decimalPart] = numStr.split('.');
    }
    
    // 使用贪心算法从右往左插入逗号
    let formattedInteger = '';
    let count = 0;
    for (let i = integerPart.length - 1; i >= 0; i--) {
        formattedInteger = integerPart[i] + formattedInteger;
        count++;
        if (count === 3 && i !== 0) {
            formattedInteger = ',' + formattedInteger;
            count = 0;
        }
    }
    
    // 如果有小数部分,添加回小数点和小数部分
    const formattedNumber = isDecimal
        ? formattedInteger + '.' + decimalPart
        : formattedInteger;
    
    return formattedNumber;
}

// 测试
const number1 = -1234567.89;
const number2 = 12345.67;
const number3 = 123456;
console.log(formatNumberWithCommas(number1)); // 输出 "-1,234,567.89"
console.log(formatNumberWithCommas(number2)); // 输出 "12,345.67"
console.log(formatNumberWithCommas(number3)); // 输出 "123,456"

二面

华容道:BFS

k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标

swap(t[k],t[a*3+b]);

distance 数组用于记录每个状态距离初始状态的步数。

在华容道问题中,每次移动一次,就相当于从一个状态转移到了另一个状态。

BFS的核心思想是从初始状态开始,逐步地将可能的状态加入队列,并记录每个状态距离初始状态经过的步数。

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
 
using namespace std;
 
int bfs(string start)
{
    string end = "12345678x";
    
    queue<string> q;
    unordered_map<string,int> d;
    
    q.push(start);
    d[start] = 0;
    
    int dx[] = {-1,0,1,0}, dy[] = {0,1,0,-1};
    
    //宽搜过程
    while(q.size())
    {
        auto t = q.front();
        q.pop();
        
        int distance = d[t];
        
        if(t == end) return distance;
        
        //状态转移
        //找到x的位置
        int k = t.find('x'); //返回x的下标
        int x = k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标
        
        //枚举上下左右四个方向
        for(int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if(a >= 0 && a < 3 && b >= 0 && b < 3)
            {
                swap(t[k],t[a*3+b]);
                
                if(!d.count(t)) //当前更新的状态没有搜到过
                {
                    d[t] = distance + 1; //更新当前距离
                    q.push(t); //把新的状态加到队列中
                }
                
                swap(t[k],t[a*3+b]); //状态恢复
            }
        }
    }
    
    return -1;
}
int main()
{
    string start;
    for(int i = 0 ; i < 9; i ++ )
    {
        char c;
        cin >> c;
        start += c;
    }
    
    cout << bfs(start) << endl;
    
    return 0;
}

版本号排序:【滴滴提前批】

javascript 复制代码
// 假设有一个版本号数组
const versionNumbers = ["1.0.2", "1.1.0", "2.0.0", "1.0.1"];

// 定义一个比较函数来进行版本号排序
function compareVersions(versionA, versionB) {
    const partsA = versionA.split('.').map(Number);
    const partsB = versionB.split('.').map(Number);

    for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
        const partA = partsA[i] || 0;
        const partB = partsB[i] || 0;

        if (partA < partB) return -1;
        if (partA > partB) return 1;
    }

    return 0;
}

// 使用比较函数对版本号数组进行排序
const sortedVersions = versionNumbers.sort(compareVersions);

// 打印排序后的版本号数组
console.log(sortedVersions);
相关推荐
西猫雷婶2 分钟前
python画图|在3D图上画2D直方图(作图平面移动)
开发语言·python·平面
用你的胜利博我一笑吧5 分钟前
supermap iclient3d for cesium中entity使用
前端·javascript·vue.js·3d·cesium·supermap
测试界兮兮8 分钟前
Python的调试工具之交互式调试器
开发语言·自动化测试·软件测试·python·功能测试·单元测试·压力测试
初心魏25 分钟前
Uniapp 跨域
前端·数据库·uni-app
Daking-38 分钟前
「队列」实现优先队列(priority_queue)的功能 / 手撕数据结构(C++)
开发语言·数据结构·c++
学会沉淀。38 分钟前
Vue3快速入门+axios的异步请求(基础使用)
前端·javascript·vue.js
林小果139 分钟前
设计模式总览
java·开发语言·设计模式
gopher951144 分钟前
go语言 结构体
开发语言·后端·golang
机器人迈克猫1 小时前
Django_Vue3_ElementUI_Release_003_前端Vue3项目初始化
前端·elementui·django
小于负无穷1 小时前
Webpack:现代前端项目的强大打包工具
前端·javascript·webpack·typescript·node.js