Сводка знаний о фронтенд-интервью

опрос

привет всем, меня зовут Дерек

Сегодня я поговорю с вами об основных знаниях фронтенд-интервью. Осень и весна — сезоны смены работы. Надеюсь, эта статья поможет вам и поможет получить любимое предложение.

Основы интерфейса

браузер

  • Механизмы кэширования браузера: сильный кэш против согласованного кэша и в чем разница?
  • Связанные с хранилищем: для чего используются localstorage, sessionStorage, файлы cookie и т. д. и в чем различия?
  • Что означают элементы на сетевой панели браузера, в основном период времени под таймингом? Что такое ТТФБ?
  • Использовали ли вы производительность браузера и для чего он нужен?
  • Принцип кроссдоменности, каковы методы реализации кроссдоменности?
  • Что такое цикл событий в среде браузера? По сути, это еще и макрозадача, и микрозадача, как видитеэта статья

JavaScript

Примитивные типы данных и ссылочные типы данных

  • Основные типы данных: Undefined, Null, Boolean, String, Number, Symbol
  • Справочные типы данных: объект, массив, дата, регулярное выражение, функция
  • Здесь можно рассмотреть typeof, instanceof; включая ручную реализацию следующих typeof и instanceof
// 实现typeof
function type(obj) {
	return Object.prototype.toString.call(a).slice(8,-1).toLowerCase();
}
// 实现instanceof
function instance(left,right){
    left=left.__proto__
    right=right.prototype
    while(true){
       if(left==null)
       	  return false;
       if(left===right)
          return true;
       left=left.__proto__
    }
}

Сеть прототипов

Поймите, что делает цепочка прототипов, а именно: экземпляры.proto=== Конструктор.прототип

Object.prototype.__proto__ === null // true
Function.prototype.__proto__ === Object.prototype // true
Object.__proto__ === Function.prototype // true

Вот над чем лучше подумать:

function F() {}
Object.prototype.b = 2;
F.prototype.a = 1;
var f = new F();
console.log(f.a) // 1
console.log(f.b) // 2
console.log(F.a) // undefined
console.log(F.b) // 2

Почему в приведенном выше коде F.a не определен?

function F() {}
Object.prototype.b = 2;
Function.prototype.a = 1;
var f = new F();
console.log(f.a) // undefined
console.log(f.b) // 2
console.log(F.a) // 1
console.log(F.b) // 2

Почему в приведенном выше коде f.a не определено?

function F() {}
F.prototype.a = 1;
var f1 = new F()
F.prototype = {
    a: 2
}
var f2 = new F()
console.log(f1.a) // 1
console.log(f2.a) // 2

наследовать

Несколько способов наследования:

  • Наследование цепочки прототипов:
    function SuperType() {
      this.name = 'Yvette';
      this.colors = ['red', 'blue', 'green'];
    }
    SuperType.prototype.getName = function () {
        return this.name;
    }
    function SubType() {
        this.age = 18;
    }
    SubType.prototype = new SuperType();
    SubType.prototype.constructor = SubType;
    
    let instance1 = new SubType();
    instance1.colors.push('yellow');
    console.log(instance1.getName());
    console.log(instance1.colors); // ['red', 'blue', 'green', 'yellow']
    
    let instance2 = new SubType();
    console.log(instance2.colors); // ['red', 'blue', 'green', 'yellow']
    
    недостаток:
    • Когда наследование реализуется через прототип, прототип становится экземпляром другого типа, исходное свойство экземпляра становится текущим свойством прототипа, а свойство ссылочного типа прототипа будет общим для всех экземпляров. (значения ссылочного типа являются общими для всех экземпляров)
    • При создании экземпляра подтипа невозможно передать аргументы конструктору супертипа, не затрагивая все экземпляры объекта.
  • Наследование конструктора:
    function SuperType(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    function SubType(name) {
        SuperType.call(this, name);
    }
    let instance1 = new SubType('draven');
    instance1.colors.push('yellow');
    console.log(instance1.colors);  // ['red', 'blue', 'green', 'yellow']
    
    let instance2 = new SubType('ben');
    console.log(instance2.colors);  // ['red', 'blue', 'green']
    
    преимущество:
    • Параметры могут быть переданы в суперкласс
    • Решена проблема, связанная с тем, что значение ссылочного типа, содержащееся в прототипе, используется всеми экземплярами.
    • Все методы определены в конструкторе, и повторное использование функции невозможно.
    • Методы, определенные в прототипе супертипа, невидимы для подтипа.
  • Наследование композиции:
    function SuperType(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    SuperType.prototype.sayName = function () {
        console.log(this.name);
    }
    function SuberType(name, age) {
        SuperType.call(this, name);
        this.age = age;
    }
    SuberType.prototype = new SuperType()
    SuberType.prototype.constructor = SuberType
    
    let instance1 = new SuberType('draven', 25);
    instance1.colors.push('yellow');
    console.log(instance1.colors); // ['red', 'blue', 'green', 'yellow']
    instance1.sayName(); //draven
    
    let instance2 = new SuberType('ben', 22);
    console.log(instance2.colors);  // ['red', 'blue', 'green']
    instance2.sayName();//ben
    
    недостаток:
    • В любом случае конструктор супертипа вызывается дважды: один раз при создании прототипа подтипа и один раз внутри конструктора подтипа.
    преимущество:
    • Параметры могут быть переданы в суперкласс
    • Каждый экземпляр имеет свои свойства
    • повторное использование функции
  • Паразитическое наследование композиции, паразитное наследование композиции — наиболее рациональная парадигма наследования для ссылочных типов, использующая Object.create для оптимизации на основе наследования композиции:
    function SuperType(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    SuperType.prototype.sayName = function () {
        console.log(this.name);
    }
    function SuberType(name, age) {
        SuperType.call(this, name);
        this.age = age;
    }
    SuberType.prototype = Object.create(SuperType.prototype)
    SuberType.prototype.constructor = SuberType
    let instance1 = new SuberType('draven', 25);
    instance1.colors.push('yellow');
    console.log(instance1.colors); //[ 'red', 'blue', 'green', 'yellow' ]
    instance1.sayName(); //draven
    
    let instance2 = new SuberType('ben', 22);
    console.log(instance2.colors); //[ 'red', 'blue', 'green' ]
    instance2.sayName();//ben
    
  • Наследование ES6:
    class SuperType {
        constructor(age) {
            this.age = age;
        }
    
        getAge() {
            console.log(this.age);
        }
    }
    
    class SubType extends SuperType {
        constructor(age, name) {
            super(age); // 调用父类的constructor(age)
            this.name = name;
        }
    }
    
    let instance = new SubType(18, 'draven');
    instance.getAge(); // 18
    
    • Все методы, определенные внутри класса, не являются перечисляемыми. (Методы прототипов ES5 по умолчанию являются перечисляемыми)

Закрытие:

  • Отверждение:
// 实现固定参数的curry
function add(a, b, c, d) {
    return a + b + c + d
}

function curry(fn) {
    const length = fn.length
    let params = []
    return function func() {
        params = params.concat([].slice.call(arguments))
        if (params.length === length) {
            const res = fn.apply(null, params);
            params = [];
            return res;
        } else {
            return func;
        }
    }
}

const addCurry = curry(add);
console.log(addCurry(1, 2)(3, 4)); // 10
console.log(addCurry(2)(3)(4)(5)); // 14
// 实现随意参数的柯理化
function add() {
    let params = [].slice.call(arguments);
    function func() {
        params = params.concat([].slice.call(arguments))
        return func;
    }
    func.toString = () => {
        return  params.reduce((a, b) => {
            return a + b;
        }, 0);
    }
    return func;
}

console.log(add(1, 2)(3, 4)); // 10
console.log(add(2)(3)(4)(5)); // 14
  • Стабилизация и троттлинг:

Функции защиты от сотрясений и дросселирования — это методы управления частотой срабатывания событий.

// 防抖
export function debounce(func, wait, immediate) {
    let timeout, args, context, timestamp, result;

    let nowTime = Date.now || function () {
        return new Date().getTime();
    };

    const later = function () {
        let last = nowTime() - timestamp;

        if (last < wait && last >= 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function () {
        context = this;
        args = arguments;
        timestamp = nowTime();
        let callNow = immediate && !timeout;
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
};
// 节流
function throttle(fn, threshhold) {
    let timeout
    let start = new Date;
    threshhold = threshhold || 160
    return function () {
        const context = this, args = arguments, curr = new Date() - 0
        clearTimeout(timeout)//总是干掉事件回调
        if (curr - start >= threshhold) {
            fn.apply(context, args)
            start = curr
        } else {
            //让方法在脱离事件后也能执行一次
            timeout = setTimeout(function(){
                fn.apply(context, args)
            }, threshhold);
        }
    }
}

var/let/const

В этой части в основном рассматривается понимание let и var, продвижение переменных и т. д.

Каков результат выполнения следующего кода?

var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};

bar = ?
foo = ?

Результат вышеописанного выполнения:bar = {n:1,x:{n:2}}; foo={n:2};

a();
var a=3;
function a(){
alert(10)
}
alert(a)
a=6;
a()

Результат вышеописанного выполнения:10 3 error; Последняя ошибка связана с тем, что a не является функцией;

== и ===

Шаги неявного преобразования: Легко понять, что делается в случае сильного ожидания и двойного ожидания.

Сильное равенство (===) сначала сравнивает, одинаковы ли типы с обеих сторон, и если они разные, возвращает false напрямую; если типы одинаковы, это оценивается в соответствии с ==, давайте посмотрим на неявный преобразование, вызванное ==.

Неявное преобразование, вызванное двойным знаком равенства

1. Во-первых, проверьте, есть ли NaN до и после знака двойного равенства, Если есть NaN, он всегда будет возвращать false.

Во-вторых, посмотрите, есть ли логическое значение до и после двойного знака равенства.Если есть логическое значение, преобразуйте логическое значение в число. (ложь 0, правда 1)

3. Затем посмотрите, есть ли строка до и после знака двойного равенства, есть три ситуации:

1、对方是对象,对象使用toString()或者valueOf()进行转换;

2、对方是数字,字符串转数字;(前面已经举例)

3、对方是字符串,直接比较;

4、其他返回false

4. Если это число, другая сторона является объектом, и объект сравнивается с valueOf() или toString(), а все остальные возвращают false

Five, null, undefined не будут преобразованы, но они равны

Метод .toString() и преобразование значения метода .valueOf()

Обычно мы думаем, что преобразование объекта в строку требует вызова метода toString(), а преобразование объекта в число требует вызова метода valueOf(), но в реальном приложении это не так просто, см. следующий пример кода:

let obj = {
 name: "draven",
 age: 28
}
console.log(obj.toString()); //[object Object]

Точно так же давайте посмотрим на метод valueOf():

let arr = [1, 2, 3];
console.log(arr.valueOf());//[1, 2, 3]

Как видно из приведенного выше кода, метод valueOf() не преобразует объект в число, отражающее этот объект. Вместо этого мы используем toString()

let arr = [1, 2, 3];
console.log(arr.toString());//1,2,3

Примечание: многие друзья думают, что для преобразования в строку сначала должен быть вызван метод toString(). На самом деле это неправильное понимание. Мы должны понимать, что вызов метода toString() может преобразовать его в строку, но это не так. не обязательно первый вызов метода преобразования строки toString().

Давайте посмотрим на следующий код:

let arr = {};
arr.valueOf = function () { return 1; }
arr.toString = function () { return 2; }
console.log(arr == 1);//true

let arr = {};
arr.valueOf = function () { return []; }
arr.toString = function () { return 1; }
console.log(arr == 1);//true

Из приведенного выше кода видно, что преобразование сначала вызывает valueOf(), если valueOf() не является значением, то для преобразования будет вызываться toString!

let arr = {};
arr.valueOf = function () { return "1"; }
arr.toString = function () { return "2"; }
console.log(arr == "1");//true

Если "1" является строкой, она сначала вызовет valueOf().

let arr = [2];
console.log(arr + "1");//21

В приведенном выше примере вызывается toString(), потому что за arr.toString() следует 2.

Процесс конвертации такой: во-первых, arr вызовет сначала метод valueOf(), но этот метод чисел просто наследуется и не переписывается (разумеется, это переписывание не является нашей реализацией), возвращаемое значение — это сам объект массива , а не тип значения, поэтому вместо этого вызывается метод toString(), поэтому цель преобразования в строку достигается.

иллюстрировать

Большинство объектов неявно преобразуются в типы значений при первой попытке вызвать метод valueOf(). Но объект Date является исключением. Методы valueOf() и toString() этого объекта были тщательно переписаны. По умолчанию используется вызов метода toString(), например, с помощью оператора +. Если он есть в других арифметических операциях , вместо него будет вызван метод valueOf().

let date = new Date();
console.log(date + "1"); //Sun Apr 17 2014 17:54:48 GMT+0800 (CST)1
console.log(date + 1);//Sun Apr 17 2014 17:54:48 GMT+0800 (CST)1
console.log(date - 1);//1460886888556
console.log(date * 1);//1460886888557

пример укрепления Давайте вместе ответим на следующие вопросы!

let a;
console.dir(0 == false);//true
console.dir(1 == true);//true
console.dir(2 == {valueOf: function(){return 2}});//true

console.dir(a == NaN);//false
console.dir(NaN == NaN);//false

console.dir(8 == undefined);//false
console.dir(1 == undefined);//false
console.dir(2 == {toString: function(){return 2}});//true

console.dir(undefined == null);//true

console.dir(null == 1);//false

console.dir({ toString:function(){ return 1 } , valueOf:function(){ return [] }} == 1);//true

console.dir(1=="1");//true
console.dir(1==="1");//false

[] == 0 // true

Все вышесказанное понятно? По какой причине последняя строка кода возвращает true?

es6

В этой части проверяется владение es6, некоторыми новыми типами, синтаксисом и так далее. Рекомендую всем посмотретьСтатья Es6 учителя Руан Ифэн

рукописная реализация

js реализует привязку

// 实现bind
Function.prototype.myBind = function (context,...args) {
    let self = this;
    let params = args;
    return function (...newArgs) {
        self.call(context, ...params.concat(...newArgs))
    }
}
var a = {
    name: 'this is a'
}

function sayName() {
    console.log(this.name, arguments)
}

let newfn = sayName.myBind(a, '1234', '5678')
newfn('1000', '2000')

js реализует вызов

// 实现call
Function.prototype.myCall = function (context,...args) {
    context.fn = this;
    context.fn(...args)
    delete context.fn;
}
var a = {
    name: 'this is a'
}
function sayName() {
    console.log(this.name, arguments)
}
sayName.myCall(a, '1234', '5678')

js реализует setInterval

// setTimeout 实现setInterval
function mySetInterval(fn, time) {
    let timer = {};
    function timeout() {
        timer.t = setTimeout(() => {
            fn();
            timeout()
        }, time)
    }
    timeout();
    return timer;
}


function clearMyInterval(timer) {
    clearTimeout(timer.t)
}

promise

Есть много точек проверки обещаний, в том числе точки знаний для реализации ваших собственных обещаний и некоторых вызовов.

Рекомендуется две статьи:Реализовать обещанияа такжеОбещания

css

  • Блочная модель, каковы характеристики полей и отступов блочной модели?
  • Каковы свойства гибкого макета и что они означают?
  • Каков метод реализации макета с центрированием слева-справа, макета с центрированием сверху-снизу, макета с центрированием сверху-снизу слева-справа?
  • Одна строка превышает опущение..., многострочная превышает опущение...
  • Адаптивная верстка
  • Адаптивный макет
  • меньше, scss, стилус
  • рем, эм, vw и т. д.
  • Как добиться 1px на мобильном телефоне?
  • Как css реализует треугольники?
  • В чем разница между ссылкой и импортом css?

html

  • для чего используется мета
  • Различия и примеры блочных и линейных элементов
  • Какие новые теги в html5?
  • Использование тегов видео, событий и т. д.

внешний фреймворк

vue

базовый

1. Жизненный цикл vue: перед созданием, созданием, перед монтированием, монтированием, перед обновлением, обновлением, перед удалением, уничтожением;

2. Связь компонента Vue:

  • реквизит (излучать);
  • $attr и $listeners,
  • объект шины событий (bus.$on, bus.$emit),
  • предоставлять (вводить),
  • v-модель (реквизит: значение, излучение: ввод),
  • $ дети,
  • vuex

3. Использование и принцип работы алгоритма keep-alive, LRU

4. Разница между v-show и v-if для vue, разница между watch и вычислением для vue;

5. Другое: рендеринг Vue на стороне сервера, например, использование фреймворка nuxt, использование библиотек внешних компонентов, таких как element-ui;

vue2 и vue3

3 — Proxy+Reflect, 2 — Object.defineProperty, оптимизация dom-diff, componentApi и т. д.

vue-router

  • Реализован режим: хеш и история, разница и анализ двух
  • Событие: Глобальное: beforeEach, afterEach; Маршрутизация: beforeEnter; В компоненте: beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave
  • Принцип реализации, исходный код

vuex

  • что такое векс?официальный сайт векс
  • состояние, геттеры, мутации (фиксация), действия (отправка), модуль
  • mapState, mapMutations, mapGetters, mapActions, подписка, subscribeAction
  • Принцип реализации, исходный код и т.д.

react

1. Жизненный цикл

  1.react16之前的生命周期是什么?
  2.react16之后的生命周期是什么?
  3.react16和react16之前的版本有什么区别?
  4.requestAnimationFrame是什么?requestIdleCallback是什么?如何实现requestAnimationFrame
// 实现requestAnimationFrame
var lastTime = 0
window.requestAnimationFrame = function (callback) {
    let now = Date().now;
    let timeCall = Math.max(0, 16 - (lastTime - now));

    let id = setTimeout(function () {
        callback(now + timeCall)
    }, timeCall)
    
    lastTime = now + timeCall;
    return id;
}

2. реагирующие крючки

1.常用的reacthooks都有哪些?
2.使用useEffect模拟componentDidMount和componentDidUpdate
3.useEffect返回的是什么?做什么用的?
4.useEffect和useLayoutEffect的区别是什么?
5、useMemo和useCallback是什么?做什么用的?有什么区别?

3. реактивный маршрутизатор

1.如何实现路由切换,有几种方式?
2.有哪几个钩子函数?onEnter和routerWillLeave
3.link与a标签的区别什么?

В-четвертых, редукс

1.redux是什么?做什么的?与vuex有什么区别?
2.redux包含哪几块?state,reducers,actions

5. Другие:

1.服务端渲染next;
2.组件库antd;
3.PureComponent与Component的区别是什么?
4.react的性能优化有什么建议?
5.封装一个promise的setState
// 使用promise封装setState
function setStateP(state) {
    return new Promise(resolve => {
        this.setState(state, resolve)
    })
}

Тип инструмента - веб-пакет

  • 1. Что такое веб-пакет?
  • 2. Каков принцип работы Webpack?
  • 3. Вы написали плагин? Как?
  • 4. Что делает загрузчик? В чем разница между загрузчиком и плагином?
  • 5. Предложения по оптимизации для веб-пакета и т. д.

Разговор о вебпаке

nodeJs

  • цикл событий: вы можете прочитать эту статьюцикл событий nodejs
  • яйцо: цикл объявления, структура каталогов, общие плагины
  • koa: разница между промежуточным программным обеспечением Koa и промежуточным программным обеспечением Express, функция, которая реализует модель лукового кольца.
    // 洋葱圈模型
    function compose(middleware) {
        return function (context, next) {
            let index = -1;
            function dispatch(i) {
                if (i <= index) {
                    return Promise.reject('err')
                }
                index = i;
                let fn = middleware[i];
                if(i === middleware.length) {
                    fn = next;
                }
                if (!fn) {
                    return Promise.resolve();
                }
                try {
                    return Promise.resolve(fn(context, function next() {
                        return dispatch(i + 1);
                    }))
                } catch (e) {
                    return Promise.reject(e);
                }
            }
            dispatch(0);
        }
    }
    

child_process

    1. спавн, exec, execFile, форк,
    1. Fork похож на spawn, разница в том, что fork должен выполнять файлы js для создания дочерних процессов;
    1. Разница между spawn и exec и execFile заключается в том, что атрибут тайм-аута может быть указан для установки времени тайм-аута при создании последних двух, и когда процесс истечет, он будет уничтожен;
    1. Разница между exec и execFile заключается в том, что exec выполняет существующую команду, а execFile выполняет файл.

pm2

  • общие команды pm2: запуск, остановка, удаление, журналы, перезапуск, список
  • -i параметр, запускать многопоточность, смотреть, -w, следить за изменениями в файле
  • файл конфигурации pm2, вы можете настроить несколько приложений, массив приложений, запустить pm2 start pm2.config.js --only=one-app-name

Основы компьютера

http серия

  • Что такое трехстороннее рукопожатие? Зачем тебе три раза?
  • Что такое четыре волны? Зачем тебе четыре раза?
  • В чем разница между http1, http2, https?
  • Как HTTPS зашифрован?
  • Как отменить запрос? ПрерватьКонтроллер

Сортировать

  • Пузырьковая сортировка
// 从小到大排序:
function bubblingSort(list){
     let temp;
     for(let i=0; i<list.length; i++){
          for(let j=i; j<list.length; j++){
               if(list[i] > list[j]){
                    temp = list[i];
                    list[i] = list[j];
                    list[j] = temp;
               }
          }
     }
     return list;
}
let res = bubblingSort([10, 8, 2, 23, 30, 4, 7, 1])
console.log(res); // [1, 2, 4, 7, 8, 10, 23, 30]
  • сортировка прямым выбором
从小到大排序:
function selectSort(list){
     let r,temp;
     for(let j=0; j<list.length; j++){
          for(let i = j+1; i<list.length; i++){
               if(list[j] > list[i]){
                   temp = list[j];
                   list[j] = list[i];
                   list[i] = temp;
               }
          }
     }
     return list;
}
let res = selectSort([10, 8, 2, 23, 30, 4, 7, 1])
console.log(res); // [1, 2, 4, 7, 8, 10, 23, 30]
  • сортировка прямой вставкой

Весь процесс сортировки состоит из n-1 вставок, то есть первая запись в последовательности рассматривается как упорядоченная подпоследовательность, а затем одна за другой вставляется вторая запись, пока вся последовательность не будет упорядочена.

function insertSort(list) {
    let flag;
    for(let index = 1; index < list.length; index++) {
        flag = list[index];
        let j = index - 1;
        while (flag < list[j]) {
            list[j + 1] = list[j]
            j--;
        }
        list[j + 1] = flag;
    }
     return list;
}
let res = insertSort([10, 8, 2, 23, 30, 4, 7, 1])
console.log(res); // [1, 2, 4, 7, 8, 10, 23, 30]
  • Сортировка холмов

Процесс сортировки: сначала взять натуральное число d1

function shellSort(list) {
    const length = list.length;
    let j, temp;
    for (let d = parseInt(length / 2); d >= 1; d = parseInt(d / 2)) {
        for (let i = d; i < length; i++) {
            temp = list[i];
            j = i - d;
            while (j >= 0 && temp < list[j]) {
                list[j + d] = list[j];
                j -= d;
            }
            list[j + d] = temp;
        }
    }
    return list;
}
let res = shellSort([10, 8, 2, 23, 30, 4, 7, 1])
console.log(res); // [1, 2, 4, 7, 8, 10, 23, 30]

  • быстрая сортировка

В результате одной сортировки сортируемые записи делятся на две независимые части, причем ключевые слова одной части записей меньше ключевых слов другой части записей.

function quickSort(v,left,right){
    if(left < right){
        var key = v[left];
        var low = left;
        var high = right;
        while(low < high){
            while(low < high && v[high] > key){
                high--;
            }
            v[low] = v[high];
            while(low < high && v[low] < key){
                low++;
            }
            v[high] = v[low];
        }
        v[low] = key;
        quickSort(v,left,low-1);
        quickSort(v,low+1,right);
    }
}
let list = [10, 8, 2, 23, 30, 4, 7, 1]
quickSort(list, 0, 7)
console.log(list); // [1, 2, 4, 7, 8, 10, 23, 30]

разное

  • Пятиуровневая модель протокола tcp/ip: прикладной уровень, транспортный уровень, сетевой уровень, канальный уровень, физический уровень
  • Связанный с алгоритмом, почистите его на leetcode
  • Обход бинарных деревьев и т. д., обход до середины и после порядка, в глубину, в ширину;
  • Использование стеков и очередей
  • Использование связанных списков

разное

  • hybird
1、什么是hybrid?
2、jsbridge是什么?如何实现?
3、hybrid开发需要注意什么?
  • Предварительная загрузка и ленивая загрузка:
1.包括图片视频等内容的懒加载(IntersectionObserver的使用封装)
2.数据的预加载,纯h5的prefetch && 与端结合的预加载方案
3.js的按需加载(配合webpack的import().then()的split实现)
  • Каковы шаги загрузки документа dom?
1、 解析HTML结构。
2、 加载外部脚本和样式表文件。
3、 解析并执行脚本代码。
4、 构造HTML DOM模型。//ready
5、 加载图片等外部文件。
6、 页面加载完毕。//load
  • Что произошло от ввода браузером URL-адреса до завершения отображения?
此问题网上有很多回答,属于自由发挥问题;回答的深度和广度能够看出本人的知识面。此处就不多说了。
  • Оптимизация производительности интерфейса и т. д.

Суммировать

Ответа нет, я просто сортирую и обобщаю соответствующий контент, который я разобрал.Если ответа нет, я все равно должен проверить это сам.

Кодировать слова непросто, двигайте пальцем, чтобы поставить лайк, а затем идите~~~

Наконец, я желаю вам всем удачи, если вы смените работу, вы можете найти работу, которая вам нравится.