Недавно я видел, как кто-то поделился 16-м интерфейсом с Али (владелец группы группы обучения интерфейсу) и предложением урожая 17-го фронта в Ханчжоу (отличные прохожие).
Я оказался в 17 классе и недавно легко получил 2 предложения, но я видел, что ответы на вопросы, которые они писали, были не очень подробными, поэтому я также хочу поделиться с вами как обсессивно-компульсивное расстройство. не удалось, и те, которые умерли, были разделены, и каждая встречавшаяся тема была подробно проанализирована, поэтому статья немного длинная.
Чан Вэнь очень осторожен, но есть вина и рассказы, я сдвинул для тебя скамеечку, садись!
История начинается~
Сначала я хотел подождать, пока вернусь после нового года, чтобы сменить работу, но некоторое время назад один хедхантер написал мне личное сообщение в Цзяньшу, сказав, что с моей статьей все в порядке, и спросил, не хочу ли я сменить работу. Затем я обновил свое резюме, отправил его и пригласил на собеседование, но компания находилась в Пекине/Сиане, и я туда не поехал, но там и началась история, которая подтолкнула меня к смене работы.
Опубликуйте несколько статей, которые я считаю хорошо написанными:
CSS3-анимация застряла, решение для оптимизации производительности
Углубленный анализ причин 0,1 +0,2===0,30000000000000004
Как решить задачи класса 0.1 +0.2===0.300000000000000004
Вспомните простой эксперимент по атаке DOM XSS.
Вы действительно понимаете разницу между == и ===?
Классическая яма CSS: как идеально добиться вертикального и горизонтального центрирования?
Я работаю более полугода с моей юниорской летней стажировки по настоящее время, почти 1,5+ года, я посвятил себя фронтенд-разработке, высокоинтенсивной работе и учебе, покупке книг и чтению книг, письму код, чтобы читать код, писать блоги и читать блоги, а также улучшать вопросы, отвечать на вопросы и тратить почти столько же времени, сколько сумма времени первокурсника и младшего года обучения, чтобы изучить разработку интерфейса.
Недавно я случайно начал письменный тест и собеседование.Хотя я особо не готовился, я легко получил предложение от компании, которая началась с Али, компании из Чжэцзянского университета, и вчера меня похвалил третий интервьюер.Его высокомерие растворился в воздухе.
Из-за этой смены работы я надеюсь остаться в компании как минимум на 2 года. Я действительно надеюсь исследовать и изучать интересный мир фронтенда с группой друзей, у которых есть идеи, мысли и занятия по фронтенд-технологиям. . Поэтому я решил попробовать больше интервью и присоединиться к команде, которая мне больше подходит.
В то же время я надеюсь, что с помощью этого интервью и обмена информацией я смогу немного подбодрить своих друзей, которые работают так же усердно, как и я, и я надеюсь, что смогу показать вам самого настоящего себя.
Интервью 1 - предложение1
После отклонения первой компании, которая взяла на себя инициативу найти меня, другая стартап-компания Ализи отправила мне личное сообщение в прямом наборе BOSS, а затем столкнула меня с менталитетом уровня тестирования. Письменный тест на месте был не очень хорош, но они увидели, что мое короткое сочинение в порядке, и попросили меня повторить вопрос:Несколько действительно отличных вопросов для интервью[0], Расширение последнего вопроса о сопоставлении слов и строк проводилось интервьюером шаг за шагом, и я почувствовал, что многому научился.
Я не ожидал, что результат будет более удивительным. Старший сказал, что мои способности к обучению относительно сильны, поэтому я был готов дать мне эту возможность. Зарплата на 2 тысячи выше, чем текущая зарплата. Главное услышать, что есть Есть много проектов, которые можно сделать.Говорят, что до интервью с моим боссом Также технический эксперт Али.
Опубликуйте вопрос интервью и мой ответ.
1.说一下你熟悉的设计模式
2.说一下你理解的模块机制
3.MVVM原理
4.最熟悉的框架路由机制
5.状态管理
6.统计字符串中单词出现次数
1. Расскажите о шаблонах проектирования, с которыми вы знакомы
Шаблоны проектирования, с которыми я больше всего знаком: Factory Pattern (ES5), Component Design Pattern (ES6). Шаблон Factory (ES5, на основе прототипа. В данном примере базовый класс Base, подкласс Factory)
var Factory = function () {
if(!(this instanceof Factory)){
return new Factory();
}
}
Factory.prototype = Object.assign(new Base(), {
version: '0.0.1',
defaultOption:{
title:'标题'
},
init:function (cfg) {
this.title = cfg.title || '';
this.currentOption = Object.assign(this.defaultOption,{
//...
})
},
render: function () {
var option = this.currentOption;
this.chart.setOption(option);
},
showTitle: function () {
this._showTitle();
}
})
Шаблон проектирования компонентов (ES6, основанный на классах, легко наследуемый и инициализируемый, а также рекомендуемый способ написания компонентов React, который я предпочитаю. В этом примере родительский класс Compnent, подкласс Retriv)
class Retrive extends Component {
constructor (props) {
super(props);
this.state = {
name:''
};
this.getRemoteData = this.getRemoteData.bind(this);
}
getRemoteData (data) {
this.state.retriveResult = data;
}
render(){
return (
<div className="Retrive">
<Button name="search" onClick={this.getRemoteData}>查询</Button>
</div>
);
}
}
2. Расскажите о понятном вам механизме модуля
AMD: Спецификация загрузки асинхронного модуля. a.js определяет компонент, зависящий от jQuery и echrts.
define(['jquery', 'echarts'], function ($, echarts) {
var AMD = function(){}
AMD.prototype = {
title:'',
foo: function(){}//AMD类或者继承AMD类的子类的属性
}
function bar(){}//返回,公共属性
function baz(){} //未返回,私有属性
return {
main:AMD,
bar: bar
}
});
Если b.js зависит от a.js, вы можете сделать это
define(['./a'], function (a) {
//调用构造函数,foo
var instance_amd = new a.main();
instance_amd.foo()
//调用bar
a.bar()
});
Модули ES6: аналогично механизму пакетов Python, импорт импорт и экспорт экспорт.
1.场景:vue,react推荐机制,需要babel转义成es5以兼容浏览器。
2.关于import...(from...)
①.import...from...的from命令后面可以跟很多路径格式,若只给出vue,axios这样的包名,则会自动到node_modules中加载;若给出相对路径及文件前缀,则到指定位置寻找。
②.可以加载各种各样的文件:.js、.vue、.less等等。
③.可以省略掉from直接引入。
3.关于export
①.导出的可以是对象,表达式,函数,类
②.导出是为了让别人导入
4.言外话:使用es6的话,有一个特别好的规范去遵守,airbnb的es6规范(https://github.com/airbnb/javascript)
CommonJS: Он широко используется в nodejs. Ключевое слово - требуется. Я никогда не писал пакет узла. Я только ссылался на чужие модули, поэтому внутренний принцип реализации не очень ясен.
3. Принцип МВВМ
MVVM — это шаблон архитектуры программного обеспечения, MVVM помогает разделить интерфейс и серверную часть. Вид: слой просмотра, примерно понимаемый как DOM. Модель: модель, соответствующая базе данных, как правило, в формате json, как тело запроса для связи с базой данных через http(s). ViewModel: View и Model реализуют двустороннюю привязку через ViewModel.
Суть в том, чтобы обеспечить двустороннюю привязку данных между View и ViewModel, чтобы ViewModel немедленно меняла View.Внешняя реализация MVVM включает в себя: angular, vue, react.
Двусторонняя привязка общих данных в vue.
view:{{message}}
viewModel v-model="message"
model:message
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
В компоненте с одним файлом есть дополнительный тег шаблона HTML5 для переноса представления и модели представления, а часть модели остается в части тега скрипта.
<template>
view
viewModel
</tamplate>
<script>
model
</script>
<styles>
为了让view好看点
</styles>
В случае с реакцией я никогда не слышал о двухстороннем связывании в процессе его использования, и я впечатлен рекомендацией редукторов писать как чистые функции.Для чистых функций это немного похоже на единую поток данных.
Теперь, когда мы говорим о фреймворке, наиболее интересным моментом для меня является связь между компонентами.Для простых компонентов задействована только связь на уровне родитель-потомок.Vue использует метод on emit, а react использует props. Для общения на сложном уровне, дедушка, отец, сын, внук и т. д., vue рекомендует vuex, а react рекомендует redux.Единое глобальное дерево состояний очень хорошо подходит для управления состоянием, что может сделать логику очень понятной. Файловая структура проекта Vue глубоко не изучена.В случае файловой структуры проекта React метод проектирования презентаций и контейнеров кажется очень разумным.Один отвечает за представление, а другой отвечает за данные, что очень освежает .
4. Самый знакомый механизм маршрутизации фреймворка
Зависимость маршрутизации Vue: vue-router Чтобы составить одностраничное приложение путем объединения компонентов, вам нужно всего лишь сопоставить компоненты с маршрутами. Суть front-end маршрутизации заключается в изменении представления без запроса к back-end. Необходимо обратить внимание на разницу между двумя режимами: хеш-режим и режим истории, хеш-режим добавит уродливый # сзади, вы можете включить историю для удаления. Принцип хэш-режима: Его характеристики таковы: хотя хеш появляется в URL-адресе, он не будет включен в HTTP-запрос и вообще не повлияет на серверную часть, поэтому изменение хеша не приведет к перезагрузке страницы. Хэш можно понимать как якорь, например ./index.html/#/foo, значение хеш-функции #/foo, которое не будет переходить на страницу. Это эквивалентно различным точкам привязки единой страницы, а переход между страницами аналогичен переходу с ./index.html/#foo на ./index.html/#bar.
./store/index.js
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/common',
name: 'common',
component: Common
}
]
Уровень маршрутизации также будет включать в себя вложенную маршрутизацию, динамическую маршрутизацию и перенаправление, что эквивалентно имитации запроса браузера, а затем режима ответа сервера, по сути не предполагает запроса к бэкенду, а переход на страницу может быть реализован только в браузере. Некоторое время назад я сделал vue-router используется для управления разрешениями пользователей. По сравнению с внутренней маршрутизацией в структуре MVC, это намного понятнее, так что серверная часть должна отвечать только за маршрутизация и написание API.
5. Управление статусом
Ниже приведены некоторые из моих мыслей, когда я использовал vuex для создания проекта: я сделал простую модификацию и добавил некоторые мысли о избыточности.
векс состояние, внешние данные вид, внешний DOM Действия, действия пользователя, вызывают изменения данных и, следовательно, изменения DOM.
Несколько компонентов (представлений) имеют общее состояние: вообще говоря, когда несколько компонентов взаимодействуют друг с другом, данные, полученные из серверной части, изменяются.Когда имеется много компонентов, если связь между компонентами-близнецами зависит от родительского компонента для связи, который будет приводят к очень сильной связи между компонентами, что приводит к запутанной логике проекта и сложности в обслуживании.
Несколько компонентов (представлений) зависят от одного и того же состояния. Действия из разных представлений требуют изменения одного и того же состояния.
Управление глобальным одноэлементным режимом, извлечение общего состояния компонентов Любой компонент может получить состояние или вызвать действия, независимо от того, где он находится в дереве компонентов!
Практикуйте истинное знание:
1.state存放在index.js中,创建的Store实例getter,mutations,actions等,可以分离出来
2.getters存放在getter.js中,数据流为state→getter→组件,getter相当于一个数据获取过滤器,从仓库拿特定数据到组件,相当于对computed的集中处理。
3.mutations存放在mutations.js中,数据流为组件→mutations→state,mutations相当于一个数据提交发射器,从组件提交数据到仓库
4.actions存放在actions.js中,数据流为组件→actions→mutations→state,异步操作的主要场所。
5.modules是开发大型应用时需要用到的,每个module都有单独的states,getters,actions以及mutation,有一股nodejs模块的味道。
Три принципа Vuex:
1.唯一数据源
2.保持状态只读
3.数据改变只能通过纯函数完成 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
Обязательно обратите внимание на разницу между мутацией и действием!
Мутация изменяет только локальное состояние, то есть напрямую изменяет только данные в хранилище. Действие включает асинхронные операции, прямой вызов API, передачу данных API и последующую отправку мутации.
Можно сказать, что у действия есть только одна дополнительная операция для асинхронного вызова API, чем мутация, потому что после вызова API обычно есть два типа возвращаемых результатов: успех или ошибка, или различные состояния обещания, в зависимости от разных.
Недавно изучив redux, компонент отправляет в магазин действие, что эквивалентно отправке http-запроса, а затем магазин отвечает и возвращает ответ компоненту. Подобно vuex, единственное отличие состоит в том, что vuex также необходимо ввести react-redux, ввести Provider и подключиться для подключения компонентов и хранилищ.
6. Подсчет вхождений слов в строку
«Привет, как дела, я в порядке, спасибо, YouTube, я», подсчитайте количество вхождений «вы».
function wordCount(str,word){
var str = str || "";
var word = word || "";
var strArr = str.split(" ");
var count = 0;
for(var i=0;i<strArr.length;i++){
if(word===strArr[i]){
count++
}
}
return count;
}
wordCount("hi how are you i am fine thank you youtube am am","you");
Что делать, если в строке нет пробелов?
function wordCount(str,word){
var str = str || "";
var word = word || "";
var count = 0;
var index = str.indexOf(word);
while(index!==-1){
count++;
str = str.substr(index+word.length);
index = str.indexOf(word)
}
return count;
}
wordCount("hihowareyouiamfinethankyouyoutubeamam","you");
Что, если вы не используете встроенную в js строковую функцию и не сравниваете каждый символ самостоятельно?
function wordCount(str,word){
var num = 0;
var str = str+" " || "";
var word = word || "";
var strArr = str.split("");
var wordArr = word.split("");
var count = 0;
function compare(arr1,a,arr2,b){
if(b+a<arr2.length){
if(arr1[a]===arr2[b+a]){
num++;
return compare(arr1,a+1,arr2,b+1)
}
if(num===arr1.length){
count++
num = 0;
}
}
}
for(var i=0;i<strArr.length;i++){
for(var j=0;j<wordArr.length;j++){
if(wordArr[wordArr.length-1]===strArr[i+wordArr.length-1]){
compare(wordArr,0,strArr,i+0)
}
}
}
return count;
}
wordCount("hihowareyouiamfinethankyouyoutubeamam","am");
Может ли он быть более эффективным?
function wordCount (str,word) {
var str = str+" " || "";
var word = word || "";
var strArr = str.split("");
var wordArr = word.split("");
var wordArrLen = wordArr.length;
var count = 0;
var num = 0;
function compare (arr1,a,arr2,b) {
if(b+a<arr2.length){
if(arr1[a]===arr2[b+a]){
num++;
return compare(arr1,a+1,arr2,b+1)
}
if(num===arr1.length){
count++;
num = 0;
}
}
}
var j = 0;
while(j<wordArrLen){
var i = 0;
while(i<strArr.length){
if(wordArr[wordArrLen -1]===strArr[i+wordArrLen -1]){
compare(wordArr,0,strArr,i+0);
}
i++;
}
j++;
}
return count;
}
wordCount("hihowareyouiamfinethankyouyoutubeamam","a");
//1.调整最高层级遍历数组,从37的2次方降到3的2次方,从1369降到9
//2.合并控制变量和控制条件,使用while替代for,去除JS引擎查询i,j是否存在的消耗,会稍微降低代码可读性
//3.对重复引用的wordArr.length,赋值给局部变量wordArrLen,在这里,Array.prototype.length的查询次数从3次降低到1次
Интервью 2 - предложение2
Я не хотел продолжать искать его, но сегодня мой друг дал мне предложение. Я проголосовал еще за несколько компаний, прежде чем сменить работу, может быть, я мог бы найти лучшую. Потом я подумал, что видел много объявлений о вакансиях на Станция V, так что я просто попробовал еще раз, попробуй посмотреть, есть ли яма получше.
РЕЗЮМЕ:Front-end разработка - короткая книга - пока ты молод 233
Краткая книга:пока ты еще молод 233
гитхаб:FrankKai
СегментОшибка:пока ты еще молод
Координаты: Ханчжоу
Затем я разместил пост на станции V. Это было очень судьбоносно. Друг V добавил меня в друзья и назначил встречу для телефонного интервью. После понимания технической атмосферы компании и переговоров о зарплате я успешно получил предложение. Зарплата составляет похожа на первую, которая является компанией из Чжэцзянского университета.
Я хорошо поговорил с интервьюером и, наконец, даже поговорил о еде курицы.Поскольку телефонное интервью было таким приятным, я помню только один междоменный вопрос из этого телефонного интервью. Собеседник третьей компании тоже очень хорош.Погода холодная, и дружелюбие напоминает мне обратить внимание на заморозки на дороге.Однако, так как собеседование третьей компании состоится не раньше завтрашнего вечера, я тоже резюмировать прямые вопросы занятости третьей компании:Несколько действительно отличных вопросов для интервью [1]
Опубликуйте вопрос интервью и мой ответ.
1.平时有遇到过跨域问题吗?
2.下面这段代码最终输出什么?
3.["1","2","3"].map(parseInt)返回的是什么?
4.下面代码中“入库”的颜色是?
1. Вы когда-нибудь сталкивались с междоменными проблемами?
Когда дело доходит до междоменных вопросов, мы должны говорить об одном и том же происхождении. Что такое одно и то же происхождение? Один и тот же протокол, одно и то же доменное имя и один и тот же порт — это одно и то же происхождение.
Связь между разными источниками будет иметь междоменные проблемы.Вообще говоря, клиент обращается к серверу, а сервер настраивает междоменный доступ. Междоменные проблемы, с которыми я столкнулся, можно решить, настроив серверную часть. Например, когда я использую официально рекомендованную библиотеку асинхронных запросов axios Vue для запроса серверной службы, открытой koa на серверной части, я буду столкнуться с междоменными службами. Например, для доменных проблем koa может полагаться на koa-cors. В частности, это Access-Control-Allow-Origin: имя источника, которое может быть * или специальным источником. Или на традиционном maven или nginx, тоже очень удобно настраивать кроссдоменность.
Использовался ли JSONP? JSONP не использовался, но принцип, по-видимому, заключается в загрузке тега DOM сценария через js, а затем введении кода для выполнения в src нового сценария. По сути кроссдоменная проблема аналогична в бэкенде, но называется она межпроцессным взаимодействием, а для межпроцессного взаимодействия есть IPC, RPC и т.д.
2. Каков окончательный результат следующего кода?
let O = function(name){
this.name = name || 'world';
};
O.prototype.hello = function(){
return function(){
console.log('hello ' + this.name);
};
};
let o = new O;
let hello = o.hello();
hello();
Мой молодой ответ: привет, мир.
Ответ явно неверный, потому что это вопрос-ловушка. Ловушка в том, что после вызова O.prototype.hello возвращается функция. Если вы сделаете это, то при выполнении метода hello нового экземпляра o этот на самом деле стал окном.
Итак, ответ привет не определен?
Молодые вы снова ошибаетесь, это не так.
Вместо привет.
Обратите внимание, что это hello, а не hello undefined, а пустая строка
Причина в том, что имя окна определено заранее, и его значение пусто.
Если вы мне не верите, вы можете напечатать в консоли окно.имя, и возвращенное значение будет "". Вы можете попробовать снова напечатать окно.вашеимя, например, окно.франк, и возвращаемое значение будет неопределенным.
Спасибо @ygh1 за напоминание, результат печати также связан с работающей средой, потому что глобальный в узле является глобальным, а глобальный в браузере — это окно.
Я только что столкнулся с проблемой с ловушками в узле, и печать действительно не определена, потому что глобальный объект в узле не имеет начального атрибута имени.
Таким образом, наиболее правильным ответом должен быть:
node环境:hello undefined
browser环境:hello _____(非零宽空字符)
В моей работе наиболее распространенные фабричные функции, подобные приведенным выше, записываются таким образом.
let O = function(name){
this.name = name || 'world';
};
O.prototype.hello = function(){
console.log('hello ' + this.name);
};
let o = new O("frank");
let hello = o.hello("frank");
Результат печати: привет, Фрэнк.
Если frank не передан, печатается значение по умолчанию hello world.
3. Что возвращает ["1","2","3"].map(parseInt)?
A. [1,2,3] B.["1","2","3"] C.[1,1,1] D.Другое
Это еще один вопрос-ловушка К счастью, я увидел эту ловушку, когда раньше смотрел на функцию карты MDN.
Правильный ответ Д: Другое.
Каковы другие конкретные значения? [1,НаН,НаН].
Не могу поверить, почему не мило [1,2,3]?
Поскольку обратный вызов карты имеет 3 параметра, текущее значение, индекс и массив, у parseInt есть 2 параметра, строка и основание (система), если в карту передается только parseInt, третий массив параметров будет автоматически игнорироваться, но не индекс игнорируется. , поэтому 0, 1 и 2 передаются в качестве второго параметра функции parseInt.
Если вы еще не поняли, давайте разберем каждый шаг ["1","2","3"].map(parseInt) отдельно.
parseInt("1",0) 此时将字符"1"转换为O进制数,由于0进制数不存在,所以返回Number类型的1。
parseInt("2",1) 此时将字符"2"转换为1进制数,由于超出进制数1,所以返回NaN。
parseInt("3",2) 此时将字符"3"转换为2进制数,由于超出进制数2,所以返回NaN。
В этот момент открывается правда. Итак, каков обычно используемый метод записи карт без ловушек?
нравится:["1","2","3"].map(x=>parseInt(x))
Передайте полную функцию с формальными параметрами и обратным вызовом, чтобы результат не был неправильным из-за неправильного ввода параметра, и, наконец, верните красивый новый массив, обработанный чистой функцией.
На самом деле, если вы пойдете глубже, вы сможете изучить, что такое чистая функция?
Чистая функция на самом деле является функцией, которая не изменяет ввод, но может использовать ввод для создания функции, которая использует ввод в качестве исходного материала и после обработки выводит новый вывод.Ключ в том, чтобы не изменять ввод. Функция обязательна для редюсеров, которые пишут redux.Skill points.
Только что пришел большой босс компании и сказал, что он никогда не использовал parseInt, он использовал знак плюс, +"1" Возвращает 1, +"2" возвращает 2. Даниэль — это действительно Даниэль, и там действительно много черных технологий.
4. Какого цвета «Входящие» в приведенном ниже коде?
<ul class="list" id="list">
<li class="favorite">
<span>出库</span>
</li>
<li class="favorite">
<span class="highlight">入库</span>
</li>
</ul>
<style>
#list .favorite:not(#list) .highlight{
color: red;
}
#list .highlight:nth-of-type(1):nth-last-of-type(1){
color: blue;
}
</style>
A. red B.blue C.black
Мой ответ: я думаю, это может быть A, потому что вес A самый большой, а вес селектора псевдокласса должен быть относительно небольшим.
Интервьюер прислал 👍, можно завтра прийти в компанию на собеседование? У меня завтра назначено собеседование.
На этом ответ на этот вопрос заканчивается, потому что я действительно не интересуюсь CSS, простите меня, господа.
Интервью-3 не удалось
1. Расскажите мне о сходствах и различиях между следующими двумя единицами размера шрифта?
em rem
Цель этих двух состоит в том, чтобы гарантировать, что когда пользователь изменяет размер шрифта, размер шрифта в вертикальном направлении остается прежним. В отличие от px, оба являются единицами расчета размера шрифта, то есть ему необходимо вычислить его размер и преобразовать его в px.То же самое верно для rpx апплета WeChat и, наконец, преобразовать в px, который может быть заимствован из rem , Подумайте об этом.
Но em относится к унаследованному родительскому элементу, а rem относится к корневому элементу. Я слышал от Даниэля, что rem часто используется в Китае, и это может быть проблемой привычек использования. Я также думаю, что rem проще в использовании.Назначьте начальное значение размера шрифта корневого элемента, а затем сотрудничайте с медиа-запросом css для динамического изменения глобальной единицы.Можно сказать, что это влияет на все тело. Это очень удобно, но читабельность em очень плохая.Иногда, чтобы вычислить размер шрифта, нужно найти его уровень за уровнем, что очень неинтуитивно.
В современных распространенных браузерах 1rem равен 16px, но может быть передан черезhtml{font-size:percentage/num }контролировать.
Давайте сравним два примера rem и em.
сокращенная структура html:
<html>
<body>
<div></div>
</body>
</html>
пример рем:
html { font-size:62.5%; } /* =10px */
body { font-size: 2.0rem; } /* =20px */
div { font-size: 1.0rem; } /* =10px */
пример:
html { font-size:62.5%; } /* =10px */
body { font-size: 2.0em; } /* =20px */
div { font-size: 1.0em; } /* =20px */
В главе о размере шрифта MDN дается очень хорошее объяснение em и rem. Оригинальная английская версия очень интуитивно понятна. Я опубликую ее здесь:
em
Represents the calculated font-size of the element. If used on the font-size property itself, it represents the inherited font-size of the element.
rem
Represents the font-size of the root element (typically ). When used within the root element font-size, it represents its initial value (a common browser default is 16px, but user-defined preferences may modify this).
На самом деле em и rem чем-то похожи на связь между компонентами фреймворка MVVM, и оба имеют концепцию иерархического наследования и глобального влияния. em передается уровень за уровнем, то есть наследование.То же самое относится и к тому, как во фреймворке используются пропсы и подписки на события.Передачу дедушки, отца и внука нужно проходить уровень за уровнем.Дедушка хочет напрямую учить некоторым навыкам внуку надо сначала научить отца,дедушка → отец → внук;а rem очень похожа на библиотеку управления состоянием во фреймворке, типа vuex и redux, которая извлекает глобальное дерево состояний, и не нужно идти по очень сложному наследованию уровень за уровнем.Если дедушка хочет научить своего внук, он может научить этому непосредственно внука,дедушка → внук.
2. Реализуйте светофоры с таймером только с одним div
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<title>仅用一个DIV实现红绿灯</title>
<style>
@keyframes light{
0%{
background-color: green;
left: 0;
}
33.3%{
background-color: green;
left: 0;
}
33.4%{
background-color: yellow;
left: 200px;
}
66.6%{
background-color: yellow;
left: 200px;
}
66.7%{
background-color: red;
left: 400px;
}
99.9%{
background-color: red;
left: 400px;
}
}
.traffic-light{
position: relative;
width: 200px;
height: 200px;
border-radius: 50%;
animation: light 3s ease-in-out 0s infinite;
}
.container{
width: 600px;
border:10px solid #000;
border-radius: 20% 20%;
}
</style>
</head>
<body>
<div class="container">
<div class="traffic-light"></div>
</div>
</body>
</html>
Интервью-4 не удалось
По разным причинам начался новый раунд интервью, и этот раунд интервью был весьма полезным. После общения с разными интервьюерами, помимо получения некоторых пропусков в знаниях, я обнаружил, что собеседование на самом деле является проверкой уровня интервьюера. Выясните, как стать квалифицированным фронтенд-интервьюером.
И очень важный опыт моего брата: подготовка, которую нужно сделать перед входом на большой завод, и вопрос написан за месяц вперед.
1.setTimeout и стек вызовов функций
console.log(1);
setTimeout(function(){
console.log(2);
},0);
console.log(3);
Выход: 1 3 2 Причина: стек вызовов будет вызывать обратный вызов setTimeout последним, а обратный вызов в setTimeout является асинхронной функцией. Часть стека вызовов функций может быть упомянута здесь:blog.rising stack.com/node-is-at-…
2. Приоритет продвижения функций foo и var foo
console.log(typeof foo);
var foo = "foo";
function foo(){}
вывод: функция
console.log(typeof foo);
function foo(){}
var foo = "foo";
вывод: функция
функция имеет более высокий приоритет, чем var, и переопределит объявление var с тем же именем, независимо от того, до или после него.
3.пусть область блока и setTimeout
for(let i=0;i<6;i++){
setTimeout(function(){
console.log(i)
},0)
}
console.log(i)
вывод:
0
Uncaught ReferenceError: i is not defined
1
2
3
4
5
- Uncaught ReferenceError: i is not defined
Видно, что блочная область действия оператора for действует не только в фигурных скобках, но и в круглых скобках.
- Причина вывода 0 1 2 3 4 5
Обратный вызов setTimeout — это асинхронная функция. Цикл for — это, по сути, асинхронная циклическая очередь. Обратный вызов setTimeout будет вызываться 5 раз. Поскольку let будет выделять отдельное адресное пространство для каждого i, каждый раз будет передаваться другое значение.
Почему порядок печати перепутался во время отладки?(Подождите, пока глава стандартных таймеров не будет переведена, а затем решите ее) Точка останова попадает в console.log(i).
Uncaught ReferenceError: i is not defined
0
2
5
4
3
1
Что если заменить let на var?
for(var i=0;i<6;i++){
setTimeout(function(){
console.log(i)
},0)
}
console.log(i)
вывод: 6 6 причина:
- печатает окно.i
Каждый входящий i указывает на один и тот же i. При передаче значения window.i равны 1, 2, 3, 4, 5, 6 в последовательности, но все они являются одной и той же ссылкой. Когда начинается стек вызова функции чтобы выполнить обратный вызов setTimeout , window.i стало 6
- var не ограничивает область действия блока
Не будет выделять 6 отдельных адресных пространств для обратного вызова setTimeout.
4. Почему Object.toString.call([1,2,3]) возвращает [массив объектов]? Может ли [].toString() вернуть [массив объектов]?
Чтобы ответить на этот вопрос, нам нужноГлубокое понимание Object.prototype.toString.call().
Вы действительно передаете [1, 2, 3] как фактический параметр Object.toString через вызов, как вы это понимаете? нет. Не может ли Object.toString([1,2,3]) выполнить ту же функцию напрямую? не может. А на самом деле есть еще и Array.proto.toString() находится в этой форме, поэтому можно вызвать arr.toString() напрямую.Можно ли это обнаружить? нет.
Так в чем причина? Начнем со стола.
| тип данных | пример | return |
|---|---|---|
| нить | "foo".toString() | "foo" |
| номер | 1.toString() | Uncaught SyntaxError: Invalid or unexpected token |
| Логическое значение | false.toString() | "false" |
| undefined | undefined.toString() | Uncaught TypeError: Cannot read property 'toString' of undefined |
| null | null.toString() | Uncaught TypeError: Cannot read property 'toString' of null |
| String | String.toString() | "function String() { [native code] }" |
| Number | Number.toString() | "function Number() { [native code] }" |
| Boolean | Boolean.toString() | "function Boolean() { [native code] }" |
| Array | Array.toString() | "function Array() { [native code] }" |
| Function | Function.toString() | "function Function() { [native code] }" |
| Date | Date.toString() | "function Date() { [native code] }" |
| RegExp | RegExp.toString() | "function RegExp() { [native code] }" |
| Error | Error.toString() | "function Error() { [native code] }" |
| Promise | Promise.toString() | "function Promise() { [native code] }" |
| Obejct | Object.toString() | "function Object() { [native code] }" |
| Math | Math.toString() | "[object Math]" |
Почему возникает следующая ситуация?
Object.toString.call(Array)//"function Array() { [native code] }"
Object.prototype.toString.call(Array)//"[object Function]"
Ответ здесь!
Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"
Объект Object и его цепочка прототипов имеют метод toString(), первый возвращает функцию, а второй возвращает тип значения.
Теперь, когда мы знаем разницу, давайте снова проанализируем ее.Object.prototype.toString.call(Array)//"[object Function]".
Сам объект Array возвращает конструктор, Array//ƒ Array() { [собственный код] }, в то время как Object.prototype.toString() возвращает форму //"[тип объекта]", вызывая this массива Контекст переключается на Object, который вызывает Object.prototype.toString(), таким образом возвращая[object Function].
Примечание: Math.toString() возвращает "[объект Math]" напрямую.
В реальной разработке мы можем использовать большинство из них: Object.prototype.toString.call([1,2,3])//"[object Array]".
Суммировать:
- Как правило, toString() объекта в js возвращает строку, а содержимое связано с синтаксисом объявления функции, например [1,2,3].toString()//"1,2,3"
- Большинство возвращает полный исходный код функции, Array.toString()//"function Array() { [собственный код] }"
- Встроенные функции часто возвращают тело функции, похожее на «[собственный код]», которое необходимо сопоставить с методом вызова, например Object.prototype.toString.call([1,2,3])//"[ массив объектов]"
Так нельзя ли сделать Array.prototype.toString.call([1,3,4]) напрямую? нет! Поскольку массив, функция, дата создаются на основе объекта, но ониНаследуется Object.toString(), а не Object.prototype.toString().Чтобы еще раз усилить впечатление:
Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"
Вот почему для определения типа необходимо использовать Object.prototype.toString().
Что касается внутренней реализации Object.prototype.toString(), подождите, пока не придет время углубиться.
5. Всесторонне изучить вопросы собеседования связывать, звонить и применять
var obj = {
a: 1,
name: 'world',
objSayName: function (fn) {
fn();
}
}
function sayName () {
return console.log(this.name);
}
obj.objSayName(sayName);
// 输出:undefined
Зачем? Внутри objSayName obj это не изменяется, чтобы указывать на текущий вызывающий объект.
Тема 1: Внутренние методы объектов, вызов глобальных функций Применимо: несколько объектов (локальные методы) повторно используют одну и ту же глобальную функцию. Оптимизация: локальное (метод) повторное использование глобальных функций Метод: измените эту точку и явно измените эту точку на текущий вызывающий объект через Function.prototype.bind(). Причина: Вызов f.bind(someObject) создает новую функцию с тем же телом и областью действия, что и f, но там, где это происходит в исходной функции, в новой функции она постоянно привязывается к первому аргументу bind, независимо от того, как функция используется. bind работает только один раз!
var obj = {
name: '1',
objSayName: function (f) {
var g = f.bind(this);
console.log(g());
}
};
function sayName(){
return this.name;
}
obj.objSayName(sayName);
вывод: '1'
расширять: Вопрос 2: Что делать, если глобальный метод хочет вывести локальные свойства объекта? Применимо: одна и та же глобальная функция выводит несколько объектов (внутренние переменные). Уточнение: локальный вывод глобальной функции (переменная) Метод: используйте команду «apply» или «вызов», чтобы изменить это так, чтобы оно указывало на вызываемый объект. Причина: объект может быть передан в качестве первого аргумента для вызова или применения, и это будет связано с ним.
var obj = {
name: '1',
say: function (fn) {
fn();
}
};
function sayName(){
return this.name;
}
sayName.apply(obj);
sayName.call(obj);
// 输出:'1'
Ссылаться на:developer.Mozilla.org/en-US/docs/…
Интервью-5 предложение 3 Весь мир во мне, моя жизнь как песня
Вопросы для интервью с нынешним владельцем - это набор вопросов для интервью, которыми я восхищаюсь больше всего. Я проработал здесь почти год и сильно вырос.
Тема разделена на 4 части:
- HTML
- CSS
- JS
- код
Ответы не проверяются на точность и подлежат проверке и обновлению. Я отвечу с точки зрения «год назад» и «сегодня», что также является рекордом моего собственного роста.
HTML
1. Пожалуйста, опишите разницу между файлами cookie, sessionStorage и localStorage.
1 year before:Файлы cookie, необходимо взаимодействовать с серверной частью, метод аутентификации, истекает срок действия sessionStorage, текущий сеанс действителен localStorage, локальный кеш, истекает срок действияtoday:
cookies
- HTTP-куки (web cookie,browser cookie) — это небольшой фрагмент данных, который сервер отправляет веб-браузеру пользователя.
- Браузер может сохранить его локально и отправить на исходный сервер данных в следующем запросе.
- Типичный сценарий применения состоит в том, чтобыОпределить, являются ли два запроса с одного и того же сервера----от того же вошедшего в систему пользователя, которая представляет собой память с отслеживанием состояния для протокола HTTP без сохранения состояния.
sessionStorage
- хранилище ключей/значений, хранилище сессий
- Поддерживайте отдельную зону хранения для каждого данного происхождения, вДоступно во время сеансов страницы
localStorage
- Хранилище ключей/значений, постоянное хранилище
- После закрытия и повторного открытия браузера пара ключ-значение localStorage все еще существует.
2. Пожалуйста, объясните<script>,<script async>и<script defer>разница
1 year before:Обычная синхронная, асинхронная, отложенная загрузка.
today:
-
<script async>Управляйте браузером, чтобы загружать скрипты синхронно и асинхронно. Если для параметра async задано значение false, браузер синхронно загружает скрипт во время синтаксического анализа HTML. Обычно по кодуdocument.creatElement()Сценарии вставки являются асинхронными, установите для async значение false, чтобы сделать их синхронными. -
<script defer>Атрибут defer используется дляОпределяет, выполняется ли скрипт после завершения разбора HTML., но будет вDOMContentLoadДелается перед сжиганием.
расширять:
1. Что такоеDOMContentLoadedсобытие?
Событие DOMContentLoaded будет запущено при загрузке и анализе исходного HTML-документа, не дожидаясь окончания загрузки таблиц стилей, изображений и текстовых фреймов.Loadсобытия иDOMContentLoadedСобытия очень похожи, и люди часто путают эти два события.
2. Что такоеLoadсобытие?
Событие загрузки запускается после завершения полной загрузки.
3. Как решить проблему синхронного js, блокирующего рендеринг DOM, и как можно быстрее рендерить DOM?Асинхронный js,Оптимизирована загрузка таблиц стилей.4. Как проверить, закончилась ли загрузка документа?document.readyState.
- загрузка Загрузка.
- Интерактивный документ завершил загрузку, документ был проанализирован, но подресурсы, такие как изображения, таблицы стилей и фреймы, загружены.
- Весь документ и вложенные ресурсы были загружены, и будет запущено событие загрузки.
Таким образом, есть 3 состояния загрузки ресурса документа одновременно,loading``interactiveиcomplete.
3. Почему обычно рекомендуется размещать CSS в<head></head>между ними, а js<script></script>Установить в</body>До?
1 year before:Чтобы предотвратить блокировку рендеринга в браузере, сначала выполните CSSOM, затем нарисуйте DOM, а затем манипулируйте DOM. Пользовательский интерфейс однопоточного рендеринга основного потока.
todayС точки зрения технической реализации сначала загрузите таблицы стилей и отрисуйте, а затем загрузите и выполните файлы js, которые могут включать операции DOM после рендеринга DOM, чтобы избежать блокировки рендеринга, вызванной выполнением js. С точки зрения взаимодействия с пользователем загрузка таблиц стилей предпочтительно сокращает время, которое пользователи тратят на просмотр пустых веб-страниц, и улучшает взаимодействие с пользователем.
CSS
1. Разница между классами и идентификаторами в CSS
1 year before①Высокий приоритет ID ②ID уникален и не может быть повторен
today① Синтаксис другой, #idname, .classname ② Затронутые элементы разные, #idname действует на один элемент, а .classname действует на все элементы. ③Вес селектора другой, и вес #idname выше, чем у .classname
2. Какие есть способы скрыть DOM
1 year before
- display: none
- position: top right bottom left
- transform
- z-index
- удалить узел DOM (JS)
today Как скрыть элементы DOM?
3. Пожалуйста, объясните*{ box-sizing: border-box }, и каковы преимущества его использования?
1 year beforeСтранная коробочная модель. Легко рассчитать, ширина включает рамку, адаптивный макет в процентах.
todayЕсть два значения box-sizing, одно — content-box, другое — border-box, а content-box содержит только контент. Ширина рамки будет включать в себя содержимое, отступы и границу. Например, ширина: 100% относится к ширине, включающей содержимое, отступы и границу, что более управляемо во время макета.
Например, дочерний элемент наследует ширину: 100 % от родительского элемента. В это время устанавливаются отступы и границы дочернего элемента. Если box-sizing дочернего элемента — это content-box, это вызовет переполнение , а для рамки ширина: 100 % будет очень большой. Удобно включает отступы и границы.
Так как существует много таких сценариев применения, мы просто устанавливаем border-box для всех меток и вручную устанавливаем для него content-box в особых случаях.
На стене есть статья, продвигающая странную блочную модель IE:Установите для всех элементов box-sizing значение border-box!
4. Как определяется приоритет в процессе определения стиля (приведите пример)? Как пользоваться этой системой?
1 year before
- свойство стиля
<div style=""></div> - id
- название ярлыка
- class
- псевдокласс
Каждый селектор имеет вес, вес — это сумма, а сумма #foo>.class::before — это вес, вес id>tag>class>псевдокласс.
todayприоритет от высокого к низкому
- !важная устаревшая практика
- Встроенные стили
<span style=""></span> - Селектор идентификатора #foo
- класс selector.foo, селектор атрибутов [type="radio"], псевдокласс: hover
- Селектор типа p, span, псевдоэлемент::before
Отличная диаграмма, иллюстрирующая приоритет селектора CSS:specifishity.com/
Общие селекторы (*), комбинаторы (+, >, ~, '', ||) и псевдоклассы отрицания (:not()) не влияют на веса.
5. Зачем использовать translate() вместо абсолютного позиционирования или наоборот? Зачем?
1 year before absolute
- Удалить из обычного документооборота
- Не занимает место на макете страницы
- Откройте новый контекст стека
- Воздействовать на другие элементы макета
- удалить перекрытие краев
Сокращение вычислений, translate() не влияет на другие элементы, лучшая производительность, меньше вычислений GPU
todayУ меня есть ответ в этом сообщении в моем блоге:CSS3-анимация застряла, решение для оптимизации производительности
translate() включает поток компоновщика, который не зависит от основного потока, поэтому он будет быстрее. А абсолютное позиционирование задействует основной поток, что приведет к перерисовке макета и выполнению js, за которое отвечает основной поток, поэтому оно будет медленнее.
JS
1. В чем разница между .call и .apply?
1 year before
- Параметры передаются по-разному, но все они динамически изменяются в этом контексте.
- call будет иметь функцию для выполнения операций со стеком
- apply просто передает аргументы в новый класс
todayОб этой проблеме было 2 блога:Как работает Function.prototype.apply из спецификации? Как работает Function.prototype.call из спецификации? Звоните, чтобы спросить, подайте заявку, чтобы заплатить.Как видно из буквального значения вызова и применения, вызов вызова, применение приложения, вызов функции и применение параметров. Основное различие между вызовом и применением состоит в том, что вызов только переключает этот контекст на другие классы, чтобы вызывать методы, которых не существует, в то время как применение в основном предназначено для передачи других типов параметров в себя, а затем вызывает свои собственные методы.
Предположим, есть foo, bar.foo.call(bar) bar вызывает метод foo, экземпляр Object.toString([1,2,3])->"[object Array]", экземпляр массива вызывает метод toString класса Object.foo.apply(null, bar) Метод foo применяет аргументы bar, Math.max.apply(null, [1,2,3])->3, а метод Math max применяет каждый аргумент из [1,2,3].
2. Объясните, пожалуйста, как работает JSONP и почему на самом деле это не Ajax?
1 year beforeJSONP
Принцип: асинхронно вставляет<script></script>, будут проблемы с XSS
Причина: объект XMR не вызываетсяtodayДревний и небезопасный метод доступа к междоменным запросам, без вызова объекта XMR, сервер позволяет браузеру передать функцию, определенную в браузере в параметре запроса, и эта функция, вероятно, будет переписана XSS-атаками.
Проголосовавший за ответ от StackOverflow:stackoverflow.com/questions/2…
JSONP не очень сложная проблема.
Предположим, мыexample.comдоменное имя, в настоящее время мы хотим датьexample.netДоменное имя отправляет запрос. Чтобы запрос был успешным, необходимо пересечь границы домена, что недопустимо для браузеров.
Один из способов обойти это ограничение —<script>Этикетка. При использовании тега script ограничение доменного имени игнорируется, но с результатом ничего нельзя сделать, скрипт оценивается.
Начните вводить JSONP. Когда вы отправляете запрос на сервер, поддерживающий JSONP, вы передаете на сервер некоторые специальные данные о своей странице. Таким образом, сервер упаковывает ответ таким образом, чтобы ваш браузер мог его обработать.
Например, серверу нужен параметр, называемый обратным вызовом, чтобы включить функциональность JSONP. Тогда ваш запрос будет выглядеть так:http://www.example.net/sample.aspx?callback=mycallback
Без JSONP это может вернуть некоторые основные объекты JS, такие как:{foo: 'bar'}
Однако, в случае поддержки JSONP, сервер получает параметр обратного вызова и оборачивает результат по-другому, возвращая следующие данные:mycallback({foo: 'bar'});
Когда вы уменьшите его, он вызовет метод на стороне браузера. Итак, определите обратный вызов на своей странице следующим образом:
mycallback = function(data){
alert(data.foo);
};
Теперь, после успешной загрузки скрипта, он оценивается и функция выполняется. Междоменный запрос выполнен успешно!
Итак, у JSONP есть серьезная проблема: вы теряете контроль над запросом. Например, невозможно узнать возврат кода ошибки. Можно использовать таймер для отслеживания запросов, но это не очень хорошо. JSONRequest — отличный способ выполнить скрипты из разных источников, обезопасить себя и получить больший контроль над запросом.
В 2015 году CORS был конкурентом JSONRequest. JSONP по-прежнему полезен в старых браузерах, но он небезопасен. CORS — это более безопасный и эффективный способ запроса доступа между доменами.
3. Использовали ли вы систему шаблонов JavaScript? Какие библиотеки вы использовали?
1 year before
jade
vue angular react
{ ... }или{{ ... }}
today: Некоторые полезные библиотеки движка шаблонов
Обычно используются те, которые поставляются с интерфейсной структурой и мопсом.Поскольку я знаком только с vue.js, я не перечислил демонстрации реакции и углового.
4. В чем разница между == и ===?
1 year beforeЯ написал об этой проблеме в блоге и прочитал спецификацию. ①=== является подмножеством == ②== имеет преобразование типов ③Механизм реализации в спецификации отличаетсяtoday Вы действительно понимаете разницу между == и ===?
5. Пожалуйста, объясните политику того же происхождения в Javascript
1 year beforeМеханизмы безопасности браузера
- тот же источник: тот же протокол, тот же хост, тот же порт
- Проблемы с несколькими источниками: CORS может разрешать доступ к информации из разных источников в настройках серверной части.
today Как понять политику того же происхождения?
6. Использовали ли вы промисы и их полифиллы? Пожалуйста, напишите основное использование Promise (ES6)
1 year before axios
- axios get() post()
- Интерфейсные перехватчики запросов и ответов
today
- Promise.all() возвращает обещание только тогда, когда все асинхронные обещания разрешены и находятся в разрешенном состоянии.
- Promise.prototype.catch() Перехватывать исключения во время выполнения Promise
- Promise.prototype.finally() — это объединение catch и then, часто используемое в коде, который выполняется как в catch, так и во избежание дублирования.
- Promise.prototype.then() Промис выполнен, переходим к следующему шагу
- Соревнование Promise.race() Promise возвращает промис, который разрешается или отклоняется первым в коллекции промисов; он часто используется для контроля времени и прерывания промисов.Вы можете обратиться к сообщению, которое я сделал:Когда будет использоваться Promise.race()?
- Promise.reject() Класс Promise перехватывает исключения
- Promise.resolve() Класс Promise разрешает данные
7. Каковы преимущества и недостатки использования промисов вместо обратных вызовов?
1 year beforeРешена проблема с callback hell.
todayЗагрузите и нарисуйте холст как ресурс изображения.
class CanvasImage {
constructor(url, width, height) {
this.width = width || 500;
this.height = height || 500;
this.url = url || '';
this.element = new Image(this.width, this.height);
}
get imageElement() {
return this.element;
}
}
ад обратного звонка
source.onload = function() {
const target = new CanvasImage(url, 80, 80).imageElement;
target.onload = function() {
const main = new MainCanvas(source, target, 'right').canvasElement;
context.drawImage(main, 0, 0, 500, 500);
};
};
Обещай путь
const sourcePromise = new Promise((resolve) => {
setTimeout(() => {
const target = new CanvasImage(url, 80, 80).imageElement;
resolve(target);
}, 0);
});
source.onload = function() {
sourcePromise.then((target) => {
const main = new MainCanvas(source, target, 'right').canvasElement;
context.drawImage(main, 0, 0, 500, 500);
});
};
асинхронный/ожидающий метод
function sourceCanvasImage() {
return new Promise((resolve) => {
setTimeout(() => {
const target = new CanvasImage(url, 80, 80).imageElement;
resolve(target);
}, 0);
});
}
async function mergeCanvas() {
const targetElement = await sourceCanvasImage();
const main = new MainCanvas(source, targetElement, 'right').canvasElement;
context.drawImage(main, 0, 0, 500, 500);
}
source.onload = function() {
mergeCanvas();
};
8. Что такое цикл событий?
1 year before
- Асинхронный принцип
- подписка на события, публикация событий
- Асинхронные неблокирующие события
todayОфициальное объяснение более авторитетно:узел будет .org//docs/gui...
Что такое цикл событий? Цикл событий позволяет Node.js выполнять неблокирующие операции ввода-вывода — хотя JS является однопоточным — за счет максимально возможной разгрузки операций на системное ядро.
Поскольку большинство современных ядер являются многопоточными, они могут выполнять несколько операций в фоновом режиме. Когда один из них завершится, ядро сообщит Node.js, что соответствующий обратный вызов можно добавить кpoll queue(очередь опроса) и выполнить.
Дополнительные принципы см.:[Перевод] Цикл событий Node.js, таймеры и process.nextTick()
цикл событий, основные детали включают в себя следующее
- call stack
- (macro)task queue
- microTask queue
- background thread
Первые три части относятся к основному потоку, вы можете прочитать исходный код узла, чтобы узнать. Последний фоновый поток относится к части libuv, и вы можете углубиться в исходный код libuv (это библиотека языка c, которая специализируется на асинхронной обработке), чтобы понять механизм его реализации.
Но чтение исходного кода требует очень хорошей основы. Вот очень вдумчивая статья, которая включает в себя вышеуказанные знания:blog.rising stack.com/node-is-at-…
код
1. Какова ценность foo?
var foo = 10 + '20';
1 year before: 30
today: "1020"
2. Как реализовать следующие функции?
add(2, 5);// 7
add(2)(5);// 7
1 year beforeЧерез объект, подобный массиву аргументов.
function foo(){
var sum = 0;
for(var i = 0; i<arguments.length; i++){
sum += arguments[i]
}
if(arguments.length>=2){
return sum;
}else{
return foo;
}
}
добавить (2) (5) не удалось.
today
const add = (a, b) => {
const result =
a && b
? a + b
: function(b) {
return a + b;
};
return result;
};
3. Каковы результаты следующих двух предупреждений?
var foo = "Hello";
(function() {
var bar = " world";
alert(foo + bar);
})();
alert(foo + bar);
1 year before "undefined World" "Hello undefined"
today"Hello world" // Немедленно выполняемая область действия может получить доступ к глобальным переменным Uncaught ReferenceError: панель не определена // глобальная область не может получить доступ к локальным переменным
4. Что выводит приведенный ниже код?
console.log('one');
setTimeout(function() {
console.log('two');
}, 0);
console.log('three');
1 year before one three two
today one three two
причина:Задачи в стеке вызовов функций выполняются первыми, а setTimeout помещается в очередь задач макросов для отложенного выполнения.Цикл событий включает в себя стек вызовов, очередь (макросов) задач, очередь микрозадач и фоновый поток, и сначала выполняется обычный код в стеке вызовов, setTimeout войдет в очередь макрозадач через фоновый поток, а микро -очередь задач выполняется между очередями макрозадач.
5. Что выводит следующий код?
function getResult(value, time){
return new Promise((resolve)=>{
setTimeout(()=>{
console.log(value);
resolve();
}, time);
});
}
(async () => {
const a = getResult(1, 300);
const b = getResult(2, 200);
await a;
await b;
})();
(async () => {
await getResult(1, 300);
await getResult(2, 200);
})();
1 year before 1 2
today 2 1 1 2
Это вопрос для изучения асинхронности:Как понять асинхронную функцию?
6. Что выводит следующий код?
var obj = {
a: 1,
name: 'world',
objSayName: function(fn) {
fn();
}
}
var name = 'hello';
var arr = [1, 2, 3, 4, 5];
function foo(o) {
var bar = arr || [6, 7, 8];
var arr = [4, 2, 9];
var baz = o;
baz.a = 2;
console.log(bar, obj.a);
}
function sayName() {
return console.log(this.name);
}
foo(obj);
obj.objSayName(sayName);
1 year later [4,2,9] 2 'hello'
today [6,7,8] 2 'hello'
причина: Вариативное продвижение.
var bar,arr,baz;
bar = arr || [6, 7, 8];// 此时arr是undefined,因此bar得到了[6, 7, 8]赋值
arr = [4, 2, 9];
baz получает ссылку на obj, и все модификации baz эквивалентны модификации obj, поэтому выведите 2.
Из-за замыкания this в глобальной функции sayName указывает на глобальную, так что привет.
Я хочу быть великим человеком и сделать мир немного другим из-за меня, хотя бы немного
Опубликуйте фокус вашей идеальной команды
1. Пространство роста персональных интерфейсных технологий
Например, руководство старшего фронтенда для младшего фронтенда, обучение и совершенствование членов команды фронтенда и т. д. Это самое главное, моя цель — стать разработчиком с прочным фундаментом и независимыми техническими инсайтами в течение 2 лет.
2. Акцент компании на росте и прогрессе сотрудников
Например, обучение новичков, обмен технологиями, технический перевод и т. д.
3. Является ли сверхурочная работа компании 996 или 10105 или в соответствии с графиком проекта
Пока это группа людей, стремящихся к совершенству, 996 вполне подходит.
4. Субсидии работникам, льготы
Например, отпускные субсидии, профсоюзные пособия.
5. Оценка эффективности и бонусы
такие как аттестация, премия в конце года
Я надеюсь, что смогу остаться в компании как минимум на 2 года, когда я поменяю работу после этого года, поэтому мне нужно понять эти аспекты, прежде чем принимать решения.Мне нужно быть более осторожным и надеяться присоединиться к интересной и сильной команде~
Резюме нажмите здесь:Front-end разработка - короткая книга - пока ты молод 233
Наконец, отступление, три компании используют vue, и все они спрашивают меня, использовал ли я vue...
That's it !
пока ты еще молод
31 января 2018 г.
Вмороженный в собаку во льду и снегу в Ханчжоу
Как стать квалифицированным интервьюером?
- научиться слушать
Независимо от того, о скольких неудачах на работе хочет поговорить с вами интервьюер, вы должны терпеливо слушать его и не перебивать.
- научиться находить
В соответствии с опытом работы и рабочим сценарием интервьюера производится простое позиционирование способности, хотя оно иногда и необъективно, но будет очень полезно для уточняющих вопросов.
- научиться понимать
Поймите, что интервьюер пытается передать, даже если он расплывчат, и постарайтесь уловить то, что он понимает.
- научиться вести
Когда интервьюируемый сталкивается со сложным вопросом, если логика другой стороны неясна, научитесь упрощать сложное и вести от более мелкого к более глубокому; предполагая, что другая сторона устраивает текущую тему, направляйте углубленные принципы или расширяйте применение сценарии
- научиться копать
Научитесь выискивать в собеседнике светлые пятна, умный, настойчивый, это все очень хорошие качества
- научиться уважать
Когда интервьюер хочет узнать оценку интервьюера, независимо от того, довольны вы им или нет, используйте подход «если есть новый прогресс, мы сообщим вам позже».
- научиться молчать
Когда интервьюер хочет узнать ваше мнение по вопросу, не давайте слишком глубоких объяснений, просто нажмите здесь, потому что основная цель ограниченного времени интервью — проверить способности интервьюера.
Я с нетерпением жду возможности пообщаться с вами и вместе добиться прогресса. Приглашаем вас присоединиться к созданной мной технической дискуссионной группе, тесно связанной с фронтенд-разработкой:
- Технологический кружок SegmentFault:Синтаксический сахар новой спецификации ES
- Столбец SegmentFault:Будь хорошим фронтенд-инженером, пока ты еще молод
- Знать столбец:Будь хорошим фронтенд-инженером, пока ты еще молод
- Блог на гитхабе:личный блог 233, пока ты еще молод
- Группа QQ фронтенд-разработки: 660634678
- Публичный аккаунт WeChat: Human Beast Ghost/excellent_developers
Стремитесь стать отличным front-end инженером!