Внутренние новости-призраки: серия часто задаваемых вопросов из интервью, это стоит посмотреть!

опрос
Внутренние новости-призраки: серия часто задаваемых вопросов из интервью, это стоит посмотреть!

предисловие

С самого начала Бенгуа знает ваши болевые точки: точки знаний переднего плана слишком сложны, г-н Цин брал интервью для интервью, забыл вспомнить, вспомнил и забыл снова, снова и снова, и бесконечно жаловался.

Пойдемте, пусть Бенгуа покажет вам славные дни заучивания периодической таблицы элементов в мои школьные годы.

Водород, гелий, литий, бериллий, бор, углерод, азот, кислород, фтор, неон, натрий, магний, алюминий, кремний, фосфор, сера, хлор, аргон, калий, кальций, скандий, титан, ванадий, хром, марганец, Железо, кобальт, никель, медь, цинк...

Заучили ли мы первые 30 элементов наизусть? Ответ нет, мы использовали такттандемная память.

Запоминать нужно так или примерно так:

第一周期:氢 氦 ———— 轻嗨:轻轻的打个了招呼:嗨!
第二周期:锂 铍 硼 碳 氮 氧 氟 氖 ———— 你皮捧碳 蛋养福奶:你很皮,手里捧了一把碳。鸡蛋能够滋养福气的奶妈
第三周期:钠 镁 铝 硅 磷 硫 氯 氩 ———— 那美女桂林留绿牙:那美女在桂林留绿色的牙齿
第四周期:钾 钙 钪 钛 钒 铬 猛 铁 钴 镍 铜 锌 ———— 贾盖坑太凡哥 猛铁骨裂痛心:“贾盖”坑了“太凡哥”,导致猛男铁汉骨头碎裂很痛心

Метод тандемных ассоциаций аналогичен методу бинарной цепной ассоциативной памяти, то есть они оба помогают нам достичь цели двойного обучения и памяти посредством воображения, творчества и рассказывания историй. ——происхождение

Есть дрова? Бенгуа помнит это очень отчетливо.Омонимичные истории, соединенные в серии выше, могут чуть ли не написать кровавый сценарий. Особенно простое слово «эта красота (натрий, магний, алюминий)», кажется, способно вызвать гормоны полового созревания. Так разве можно не захотеть учиться? Интерес - лучший учитель! Это трудно забыть!

Итак, я натурализовал эту дыню по аналогии и использовал часто задаваемые вопросы из интервью, с которыми сталкивался.идеи последовательного соединенияБыла проведена «серийная» аранжировка, чтобы сформировать систему и поделиться с вами.

На фото выше!

  • Карта мозга в этой статье поддерживает:processon
Писать не просто ✍ Ставьте лайки и поощряйте 👍 Ваши отзывы 📑 Моя мотивация 💪

Конкатенация один:
Что происходит с момента ввода URL до загрузки страницы?

Этот вопрос является классикой среди классиков, и в нем так много моментов, которые можно раскопать, и он также очень глубок.

Одна картинка стоит тысячи слов

  • Оригинальная карта мозга, пожалуйста, укажите источник для перепечатки

Сцепленные точки знаний: анализ URL-адресов, DNS-запрос, TCP-рукопожатие, HTTP-запрос, ответное сообщение обработки браузера, рендеринг страницы.

Последовательная память: всего шесть шагов, объединенных в одно предложение для запоминания:UDTH, обработка возвратов плюс рендеринг.

"УДТХ"А именно: разрешение URL, DNS-запрос, TCP-рукопожатие, HTTP-запрос,

"Обработка возврата плюс рендеринг", то есть браузер обрабатывает ответное сообщение и отображает страницу.

В то же время Benguaqing отметил «ключевые слова» точек знаний, которые можно исследовать на каждом этапе на карте мозга.Это действительно ключевой момент, и его нельзя упускать!

1. Парсинг URL

URL (унифицированный локатор ресурсов), унифицированный локатор ресурсов, используется для поиска ресурсов в Интернете, широко известных как URL-адреса.

// 示例引自 wikipedia

                    hierarchical part
        ┌───────────────────┴─────────────────────┐
                    authority               path
        ┌───────────────┴───────────────┐┌───┴────┐
  abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
  └┬┘   └───────┬───────┘ └────┬────┘ └┬┘           └─────────┬─────────┘ └──┬──┘
scheme  user information     host     port                  query         fragment


scheme       - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,
               其中最常见的类型是 http,而 https 则是进行加密的网络传输。
host         - 定义域主机(http 的默认主机是 www)
domain       - 定义因特网域名,比如 baidu.com
port         - 定义主机上的端口号(http 的默认端口号是 80)
path         - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
filename     - 定义文档/资源的名称
query        - 即查询参数
fragment     - 即 # 后的hash值,一般用来定位到某个位置

Еще можно увидеть:

  1. URL RFC
  2. Wikipedia-URI

Кодировка URL

Вообще говоря, URL-адреса могут использовать только английские буквы, арабские цифры и определенные знаки препинания и не могут использовать другие слова и символы. DaseinURL RFCЖесткие и быстрые правила были сделаны.

Это означает, что если в URL-адресе есть китайские символы, они должны быть закодированы и использованы. Но проблема в том, что RFC 1738 не определяет конкретный метод кодирования, а оставляет его на усмотрение приложения (браузера). Это привело к тому, что «кодирование URL» стало областью путаницы.

Учитель Руан объяснил еще в 2010 году:О кодировании URL - Жуан Ифэн

Прямой взгляд здесьВ заключение: кодирование URL-адресов в браузере может вызвать путаницу, поэтому, скажем, мы предварительно кодируем URL-адрес в Javascript перед отправкой на сервер. Поскольку вывод Javascript всегда согласован, это гарантирует, что данные, полученные сервером, имеют единый формат.

Мы часто используем: encodeURI(), encodeURIComponent(); первый кодирует весь URL-адрес в utf-8, а второй кодирует часть URL-адреса.

Бенгуа спрашивает: Можете ли вы четко объяснить значение и взаимосвязь ASCII, Unicode, UTF-8 и GBK?

Может быть, мы мало знаем о наших обычных, часто используемых вещах.

Типы имея в виду
ASCII 8 бит — это байт, а 1 байт представляет собой символ, то есть: 2 ** 8 = 256, поэтому код ASCII может представлять только до 256 символов.
Unicode Широко известный как универсальный код, он объединяет все языки в один код, устраняет ограничения кода ASCII и проблему искаженных символов. Код Unicode обычно использует два байта для представления символа, а редкий код использует четыре байта для представления символа.
UTF-8 «Кодировка переменной длины», если это английский символ, он кодируется в ASCII, занимая один байт. Если это обычный китайский иероглиф, он занимает три байта, а если это редкое слово, то он занимает от 4 до 6 байтов.
GBK Отечественная версия, один китайский иероглиф == два байта, английский - один байт.

Сильный кеш, кеш согласования

Голос за кадром: Бенгуа начинал генераломСильный кеш, кеш согласованияПоместите это на третий шаг «HTTP-запрос», а позже узнали, что если вы нажмете сильный кеш, вы больше не сможете выполнить шаг разрешения DNS. Так что ставь сюда.Кэшируется ли сильный кеш браузера по IP или доменному имени?

Надежный кеш и согласованный кеш — обязательные вопросы. Конкретный процесс выглядит следующим образом:

  1. Когда браузер загружает ресурс, согласно заголовку запросаexpiresа такжеcache-controlОпределите, попал ли в сильный кеш.Если да, то ресурс считывается непосредственно из кеша, и запрос на сервер не отправляется.

    expires: период HTTP/1.0, оцениваемый путем сравнения местного времени и времени сервера.

    cache-control: период HTTP/1.1, оцениваемый по относительному времени, например установка максимального возраста, единица измерения — секунды.

  2. Если сильный кеш не попал, браузер обязательно отправит запрос на сервер черезEtagа такжеLast-Modified-IfУбедитесь, что ресурс попал в согласованный кеш.Если это так, сервер вернет этот запрос (304), сообщая браузеру, что нужно прочитать данные из кеша.

    [ETag, If-None-Match] Пара: Etag возвращается сервером в браузер, и браузер запрашивает If-None-Match на сервере. Судя по сравнению двух, они записывают: уникальный идентификатор, сгенерированный файлом.

    Пары [Last-Modified, If-Modified-Since]: Modified-Since возвращается сервером в браузер, а If-Modified-Since запрашивается браузером с сервера. Судя по сравнению двух, они фиксируют время последней модификации.

    Примечание: ETag имеет более высокий приоритет, чем Last-Modified. Большинство веб-серверов включают кеш согласования по умолчанию и одновременно включают [ETag, If-None-Match] и [Last-Modified, If-Modified-Since].

  3. Если ни одно из двух предыдущих не сработало, загрузите ресурс непосредственно с сервера.

Подводя итог, если сильный кеш и кеш согласования срабатывают, оба загружают ресурсы из клиентского кеша, а не с сервера; разница в том, что сильный кеш не будет отправлять запросы на сервер, а кеш согласования будет отправлять запросы на сервер для обработки.Сравнение, чтобы определить, попасть или нет.

  • Заимствуя блок-схему, настоящий источник еще не найден, и ссылка зарезервирована для объяснения ямы.

Другим важным моментом выше является то, чтоcache-controlКлассификация значения: например, «без кеша», «без хранилища», «частное» и т. д., необходимо вычесть. Только два и три приведены здесь для предварительной интерпретации.

  1. no-cache: пропустить текущий сильный кеш и отправить HTTP-запрос, то есть напрямую войти в этап согласования кеша.
  2. no-store: Не выполняйте кэширование в любой форме.
  3. private: в этом случае только браузер может кэшировать, а промежуточный прокси-сервер не может кэшировать.

Еще можно увидеть:

2. DNS-запрос

рекурсивный запрос

URL-адрес разрешения DNS (справа налево), чтобы найти соответствующий IP-адрес

// 例如:查找www.google.com的IP地址过程(真正的网址是www.google.com.):

// 根域名服务器 -> com顶级域名服务器 -> google.com域名服务器 -> www.google.com对应的ip
. -> .com -> google.com. -> www.google.com.

Это рекурсивный процесс запроса.

Дополнительные сведения об именах корневых доменов см.Знание корневых доменных имен - Жуан Ифэн.

Кэш DNS

Помните: где есть DNS, там и кэш DNS.

В DNS есть многоуровневые кэши, по удаленности от браузера они бывают следующих типов:

1. Кэш браузера 2. Кэш системы 3. Кэш маршрутизатора 4. Кэш сервера IPS 5. Кэш корневого DNS 6. Кэш DNS верхнего уровня 7. Кэш первичного DNS.

Проверить кеш:

  1. Просмотр DNS-кеша в браузере: chrome://net-internals/#dns

  2. Системный просмотр DNS-кеша Win10: win+R => cmd => ipconfig /displaydns

Балансировка нагрузки DNS

Принцип реализации технологии балансировки нагрузки DNS заключается в настройке нескольких IP-адресов для одного и того же имени хоста на DNS-сервере.Отвечая на DNS-запрос, DNS-сервер будет возвращать разные IP-адреса в последовательности с IP-адресами, записанными хостом в DNS-файл для каждого запроса.Проанализируйте результат и направьте доступ клиента к разным компьютерам, чтобы разные клиенты могли обращаться к разным серверам, чтобы достичь цели балансировки нагрузки. —— Энциклопедия

3. TCP-рукопожатие

После того, как разрешение DNS возвращает IP-адрес доменного имени, следующим шагом для браузера является установление TCP-соединения с IP-адресом.

Голос за кадром: Соответствующие знания по TCP есть в базовом университетском курсе «Компьютерная сеть», и на душе у меня горько: рано или поздно придется отплатить...

Модель TCP/IP: канальный уровень — сетевой уровень — транспортный уровень — прикладной уровень.

Соответственно, нельзя забывать и об OSI (модель взаимодействия открытых систем). Обычно считается, что три верхних уровня модели OSI (прикладной уровень, уровень представления и сеансовый уровень) соответствуют прикладному уровню в модели TCP/IP.wiki

В модели TCP/IP такие протоколы, как часто используемые HTTP/HTTPS/SSH, находятся на уровне приложений.

Три рукопожатия, четыре волны

Так называемое трехстороннее рукопожатие (Three-way Handshake) означает, что при установлении TCP-соединения клиенту и серверу необходимо отправить в общей сложности 3 пакета.

Трехстороннее рукопожатие такое же, как и ранний телефонный звонок: 1. A: Вы его слышите? 2. Б: Я тебя слышу, а ты? 3. А: Я тоже это слышал. Затем начинается настоящий разговор.

1. 第一次握手(SYN=1, seq=x):

客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。

发送完毕后,客户端进入 SYN_SEND 状态。

2. 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):

服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。

3. 第三次握手(ACK=1,ACKnum=y+1)

客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1

发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。

Так называемое четырехстороннее рукопожатие означает необходимость отправки четырех пакетов для отключения TCP-соединения.

Четыре раза машет рукой, как в сцене, когда учитель тащит класс: 1. Ученик сказал: Учитель, выход из класса окончен. 2. Учитель: Ладно, понятно, я закончил. 3. Учитель: Ладно, все, давайте закончим выход из класса. 4. Ученик: Спасибо, учитель, до свидания, учитель.

1. 第一次挥手(FIN=1,seq=x)

假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。

发送完毕后,客户端进入 FIN_WAIT_1 状态。

2. 第二次挥手(ACK=1,ACKnum=x+1)

服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。

发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。

3. 第三次挥手(FIN=1,seq=y)

服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。

发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。

4. 第四次挥手(ACK=1,ACKnum=y+1)

客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。

服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。

客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。

Если вы спросите меня: детали трех рукопожатий и четырех взмахов руки слишком трудно запомнить, помните ли вы их до сих пор? Бен Гуа: Необходимо попасть на большую фабрику.

Источник анимации:Два движущихся изображения - полностью понять трехстороннее рукопожатие TCP и четырехстороннюю волну

Управление потоком (скользящее окно)

Чтобы увеличить пропускную способность сети, мы хотим отправлять пакеты данных вместе для достижения «управления потоком».В настоящее время создается протокол «скользящего окна».

Скользящие окна позволяют отправителю отправлять несколько сегментов данных до получения подтверждения от получателя. Размер окна определяет максимальное количество сегментов данных, которые могут быть переданы за один раз до получения подтверждения от пункта назначения. Чем больше размер окна, тем больше сегментов данных хост может передать за один раз. Когда хост передает сегменты данных размером с окно, он должен дождаться подтверждения, прежде чем он сможет передать следующие сегменты данных.

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

контроль перегрузки

Спрос> предложение создает заторы

Динамическое разрешение через «окно перегрузки», «медленный старт», «быструю повторную передачу» и «быстрое восстановление».

TCP использует различные стратегии управления перегрузкой, чтобы избежать лавинной перегрузки. TCP поддерживает «окно перегрузки» для каждого соединения, чтобы ограничить общее количество неподтвержденных пакетов, которые могут быть переданы из конца в конец. Это похоже на скользящее окно, используемое в механизме управления потоком TCP. TCP использует механизм «медленного старта» для увеличения размера окна перегрузки после инициализации соединения или истечения времени ожидания. Обычно он начинается с удвоенного максимального размера сегмента (MSS), и хотя он называется «медленным стартом» и начинается с довольно низкого значения, он очень быстро растет: по мере подтверждения каждого сегмента окно перегрузки увеличивается на один MSS, так что окно перегрузки может эффективно удваиваться за каждое время приема-передачи (RTT). ——Контроль перегрузки TCP — Википедия

Слишком много принципов в скользящем окне (управление потоком) и контроле заторов.Бенгуа выражает свою неспособность и временно просит постараться понять и запомнить.

Рекомендуемое чтение:

4. HTTP-запрос

HTTP — основа для передачи данных во всемирной паутине — Википедия

Сообщение HTTP-запроса состоит из трех частей: строки запроса, заголовка запроса и тела запроса.

Сообщение ответа HTTP также состоит из трех частей: кода состояния, заголовка ответа и сообщения ответа.

HTTP, HTTPS

Разница между HTTP и HTTPS?

Пакеты HTTP отправляются в пакетах TCP. Когда сервер получает пакеты TCP, он распаковывает и извлекает пакеты HTTP. Однако в этом процессе есть определенные риски: HTTP-сообщение является незашифрованным, и если его перехватить посередине, возникнет некоторый риск утечки информации.

Эту проблему можно решить, зашифровав HTTP один раз перед вводом TCP-пакета. Суть протокола HTTPS — HTTP + SSL (или TLS). Прежде чем HTTP-пакеты перейдут в TCP-пакеты, используйте SSL для шифрования HTTP-пакетов. Из иерархической структуры сети он расположен между протоколом HTTP и протоколом TCP.

HTTP2

http2 полностью совместим с http/1.x и добавляет к нему 4 основных новых функции:

  1. Двоичный кадр: http/1.x — это текстовый протокол, а http2 — двоичный протокол.
  2. Сжатие заголовков. Заголовок запроса в http/1.x практически не изменился, а в http2 предлагается метод сжатия HPACK для уменьшения трафика, потребляемого заголовком http в каждом запросе.
  3. Push-уведомление сервера: сервер активно отправляет данные клиенту.
  4. Мультиплексирование: http/1.x, каждый http-запрос будет устанавливать TCP-соединение, http2, все запросы будут использовать TCP-соединение.

Для получения дополнительной информации см.Подробное объяснение HTTP2

ПОЛУЧИТЬ, ОТПРАВИТЬ

Интуитивная разница:

  1. GET используется для получения данных, а POST — для отправки данных.
  2. Параметр GET имеет ограничение по длине (ограничено длиной URL-адреса, конкретное значение зависит от ограничения браузера и сервера, до 2 М), в то время как POST не имеет ограничений.
  3. Данные запроса GET будут добавлены к URL-адресу, разделенному «?», а несколько параметров связаны с «&», а запрос POST поместит запрошенные данные в тело запроса HTTP. можно захватить.
  4. Запросы GET сохраняются в истории браузера и, возможно, в журналах веб-сервера.

Скрыть различия (есть различия в браузере):

  1. GET создает один TCP-пакет, POST — два TCP-пакета.

Узнать больше:

Руководство по проектированию RESTful API — Руан Ифэн

Keep-Alive

Мы все знаем, что Keep-Alive используется, чтобы избежать повторного установления соединения.

В настоящее время большинство браузеров используют протокол http1.1 и по умолчанию инициируют запрос на подключение Keep-Alive, поэтому возможность выполнения полного соединения Keep-Alive зависит от настроек сервера.

Длинные HTTP-соединения не могут поддерживаться все время, у него есть два параметра, например Keep-Alive: timeout=5, max=100, что означает, что TCP-канал может поддерживаться в течение 5 секунд, и max=100, что означает, что это длинное соединение может получить не более 100 запросов.

HTTP-сервер не будет автоматически отключаться при отправке данных в режиме Keep-Alive, поэтому об этом нельзя судить по возврату EOF (-1).

Исходя из этого, задайте вопрос: когда HTTP принимает режим поддержки активности, когда клиент запрашивает сервер, как клиент определяет, что данные сервера завершены?

  1. Используйте поле заголовка сообщения Conent-Length: Conent-Length указывает длину содержимого объекта, и клиент может судить, получены ли данные в соответствии с этим значением.

  2. Используйте поле заголовка сообщения Transfer-Encoding: Если это динамическая страница, сервер не может заранее знать размер содержимого, тогда вы можете использовать режим Transfer-Encoding: chunk для передачи данных. То есть, если вы хотите одновременно генерировать данные и отправлять их клиенту, сервер должен использовать «Transfer-Encoding: chunked» вместо Content-Length. Фрагментированные закодированные данные имеют пустой фрагментированный блок в конце, что указывает на окончание этой передачи данных.

— спросил Бенгуа перед интервью с Tencent PCG.Передача-кодирование: чанкПожалуйста, обратите на это особое внимание.

Ссылаться на:

5. Браузер обрабатывает возвращенное сообщение

код состояния

1xx: Информация об индикации — указывает, что запрос получен и обработка продолжается.

2xx: Успех — указывает, что запрос был успешно получен, понят, принят.

3xx: перенаправление — для выполнения запроса необходимо предпринять дополнительные действия.

4xx: Ошибка клиента — запрос содержит синтаксическую ошибку или запрос не может быть выполнен.

5xx: ошибка на стороне сервера — серверу не удалось выполнить допустимый запрос.

Наиболее часто встречающиеся коды состояния: 200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500.

Разделите возвратную головку и возвратный корпус (испытательный центр Tencent PCG)

Тестовый сайт здесь на самом деле пересекается с проблемой в http keep-alive, но я все же хочу это подчеркнуть, потому что эта дыня попала в эту яму и указывала на нее снова и снова, чтобы показать будущим поколениям.

В конце концов, это сводится к этому вопросу:Detect end of HTTP request body - stackoverflow

отвечать:

1. If the client sends a message with Transfer-Encoding: Chunked, you will need to parse the somewhat complicated chunked transfer encoding syntax. You don not really have much choice in the matter -- if the client is sending in this format, you have to receive it. When the client is using this approach, you can detect the end of the body by a chunk with a length of 0.
2. If the client instead sends a Content-Length, you must use that.

То есть: как получить тело возврата HTTP?

  1. Сначала прочитайте весь заголовок до \r\n\r\n (два символа новой строки), то есть весь заголовок запроса;

  2. Если возвращается Transfer-Encoding: Chunked, считывайте до тех пор, пока не встретится пустой фрагментированный фрагмент, а затем закончите.

  3. Если возвращается Content-Length, длина байтов Content-Length считывается с конца заголовка запроса.

  4. В остальных случаях дождитесь возврата.

понять больше:HTTP-ответ

локальное хранилище данных

  1. Cookie: 4K, срок годности можно установить вручную.
  2. localStorage: 5M, который сохраняется до тех пор, пока не будет очищен вручную.
  3. sessionStorage: 5M, доступ к нему через вкладки невозможен и очищается при закрытии страницы.
  4. indexedDB: база данных на стороне браузера с неограниченной емкостью, которая будет существовать всегда, если ее не очистить вручную.
  5. Веб-SQL: реляционная база данных, доступ к которой осуществляется с помощью операторов SQL (заброшен).

Расположение кеша браузера

От высокого к низкому приоритету:

  1. Service Worker: по сути, веб-воркер, скрипт, который работает независимо от веб-страницы.
  2. Кэш памяти: Кэш памяти относится к кешу памяти, который является самым быстрым с точки зрения эффективности.
  3. Кэш диска: Кэш диска — это кеш, хранящийся на диске, он медленнее, чем кеш памяти с точки зрения эффективности доступа, но его преимущества заключаются в емкости и времени хранения.
  4. Push-кэш: Push-кэш — это содержимое HTTP/2.

Более:

Автономный кеш:

<html lang="en" manifest="offline.appcache">

HTML5-автономный кэш (кэш приложения)

Примечание. «Расположение кеша браузера» и «автономный кеш» связаны, просто имейте понятие / впечатление.

6. Рендеринг страницы

CssTree+DomTree

Бенгуа знает, что вы знаете, что процесс происходит следующим образом:

dom tree + css tree = render tree => layout =>painting?

Но вы действительно съели через это?

Процесс преобразования дерева HTML в DOM:

  1. Декодирование: браузер считывает необработанные байты HTML с диска или из сети и преобразует их в соответствующие символы в соответствии с указанным форматом кодировки файла (например, UTF-8).
  2. Токенизация: браузер преобразует символы в различные точные токены, указанные в стандарте W3C HTML5, такие как "", "" и другие строки, заключенные в угловые скобки. Каждый токен имеет особое значение и собственный набор правил.
  3. Лексический анализ: сгенерированные токены преобразуются в объекты, определяющие их свойства и правила.
  4. Построение дерева DOM: Наконец, поскольку теги HTML определяют отношения между различными тегами (некоторые теги вложены в другие теги), созданные объекты связаны друг с другом в древовидной структуре данных, которая также фиксирует исходные отношения родитель-потомок. по тегу: объект HTML является родителем объекта body, тело является родителем объекта p и т. д.

CSS → дерево CSSOM. Процесс преобразования аналогичен предыдущему.

CSSOM выводит только те узлы, которые содержат стили, и окончательный вывод:

Дерево рендеринга (генерирует дерево рендеринга, вычисляет видимые узлы и стили)

  1. Не включает невидимые узлы, такие как заголовок, сценарий, метаданные и т. д.
  2. Некоторые узлы, скрытые с помощью CSS, также будут игнорироваться в дереве рендеринга, например, узлы с примененным правилом display:none, в то время как visible: hidden невидим только визуально, по-прежнему занимает место и не будет игнорироваться.

макет: рассчитать положение и размер каждого узла на экране в соответствии с блочной моделью.

рисование: В соответствии с вычисленными правилами содержимое рисуется на экране через видеокарту.

перерисовывать, перерисовывать

Перекомпоновка:

Перекомпоновка происходит при изменении положения и размера видимого узла.

Перерисовать:

При изменении цвета фона элемента, цвета текста, цвета границы и т. д. свойств, не влияющих на его окружение или внутреннюю компоновку, часть экрана перерисовывается, но геометрия элемента не меняется.

Здесь я поднимаю еще два вопроса.

Q1: Когда браузер отправляет запрос на сервер для получения внешних файлов css и js?

A1: При обнаружении внешней ссылки при анализе DOM, если соединение все еще существует, запрос на загрузку будет запущен немедленно.

Q2: Каковы отношения блокировки между CSSOM DOM и JavaScript?

A2: CSSOM DOM не влияют друг на друга. JavaScript блокирует построение дерева DOM, но HTML до JS можно нормально преобразовать в дерево DOM. Создание CSSOM блокирует выполнение JavaScript.Сомневаетесь в этой фразе?

  • Блокировка загрузки css:
  1. Загрузка CSS не блокирует разбор дерева DOM

// Парсинг DOM и парсинг CSS — это два параллельных процесса, поэтому это также объясняет, почему загрузка CSS не блокирует парсинг DOM.

  1. Загрузка CSS блокирует рендеринг дерева DOM

// Поскольку дерево рендеринга зависит от дерева DOM и дерева CSSOM, оно должно дождаться, пока дерево CSSOM будет построено, то есть после завершения загрузки ресурса CSS (или после сбоя загрузки ресурса CSS), прежде чем можно будет начать рендеринг. Поэтому загрузка CSS будет блокировать рендеринг Dom.

  1. Загрузка CSS заблокирует выполнение последующих операторов js.

// Так как js может работать с предыдущим узлом Dom и стилем css, браузер сохранит порядок css и js в html. Следовательно, таблица стилей будет загружена и выполнена до того, как будут выполнены последующие js. Таким образом, css заблокирует выполнение следующих js.

Справочное чтение:

  1. Будет ли загрузка css вызывать блокировку?
  2. Расчесывание процесса рендеринга страницы браузера

Комплексное дополнение

оптимизация веб-производительности

Вторая серия:
Старый разговор, вы можете поговорить о закрытии?

Если вы думаете, что этот вопрос простой, вы можете закончить его в одном-двух предложениях? Это действительно всплыло. На самом деле, этот вопрос не может быть решен за день или два! Это может включать в себя большую часть знаний о принципах js. Это «мотив» в прямом смысле.

Одна картинка стоит тысячи слов

  • Оригинальная карта мозга, пожалуйста, укажите источник для перепечатки

Объединение точек знаний: замыкание, область видимости, цепочка прототипов, наследование js.

Память конкатенации: этот вопрос не похож на приведенный выше вопрос «Что произошло от ввода URL-адреса до загрузки страницы?», Последняя «точка конкатенации» прогрессивна в соответствии с шагами решения. И "точка соединения" тут большеУ тебя есть я у меня есть ты, до и после дополняют друг друга и улучшают друг друга. Когда вы закончите читать, у вас обязательно возникнет ощущение, что «все вещи возвращаются к своим предкам».

Объединить в стихотворение из пяти символов, чтобы помнить:

сфера закрытия
Прототипы для рассмотрения
Наследование восьми великих законов
хорошая основа

1. Закрытие

закрытое значение

Одним словом.

Лексическое окружение, в котором другая функция может получить доступ к своим внутренним переменным, а другая функция вызывается извне, называется замыканием.

  • эффект:
  1. Читать переменные внутри функции (приватные переменные, не загрязнять глобальные)
  2. Постоянно держите переменные в памяти.

Заявление о закрытии

  • Самые классические тестовые вопросы
for(var i = 0; i < 5; i++){
	(function(j){
		setTimeout(function(){
			console.log(j);
		},1000);
	})(i);
}
console.log(i);

механизм сбора мусора

  • js механизм сборки мусора: удаление меток и подсчет ссылок.

Отметить как очистку просто означает, что переменная хранится в памяти. Когда переменная попадает в среду выполнения, сборщик мусора помечает ее. Переменная покидает среду выполнения и помечает ее как «очищенную», неотслеживаемую и не используемую другими объектами. На ссылку или на два объекта, ссылающихся друг на друга, не ссылается третий объект, а затем они утилизируются сборщиком мусора для освобождения места в памяти.

Защита от сотрясения, дроссельная функция

  • Стабилизатор
function debounce(fn, delay) {
    var timer; // 维护一个 timer
    return function () {
        var _this = this; // 取debounce执行作用域的this
        var args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            fn.apply(_this, args); // 用apply指向调用debounce的对象,相当于_this.fn(args);
        }, delay);
    };
}
  • дросселирование
function throttle(fn, delay) {
    var timer;
    return function () {
        var _this = this;
        var args = arguments;
        if (timer) {
            return;
        }
        timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null; // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
        }, delay)
    }
}

2. Объем

глобальная область

  • Код JS, написанный непосредственно в теге script, находится в глобальной области видимости;
  • Глобальная область создается при открытии страницы и уничтожается при закрытии страницы;
  • В глобальной области видимости есть окно глобального объекта, которое представляет собой окно браузера, которое создается браузером, и мы можем использовать его напрямую;
  • В глобальной области видимости созданные переменные сохраняются как свойства объекта окна;
  • Созданная функция будет сохранена как метод объекта окна;
  • Переменные в глобальной области видимости — это глобальные переменные, к которым можно получить доступ из любой части страницы;

Мы можем попробовать это, напечатав прямо в консоли, как упоминалось выше:

область действия функции (локальная область действия)

  • Переменные объявляются внутри функции, а переменные принадлежат локальной области видимости.
  • Локальные переменные: доступны только внутри функции.
  • Локальные переменные используются только внутри функций, поэтому разные функции могут использовать переменные с одинаковыми именами.
  • Локальные переменные создаются, когда функция начинает выполняться, и локальные переменные автоматически уничтожаются после выполнения функции.

область действия блока

Область действия на уровне блока: Область действия на уровне блока относится к блоку операторов, образованному с помощью if () { }; while () { } ...... эти операторы и переменные должны быть объявлены с помощью let или const, гарантируя, что переменные в блоке операторов нельзя получить доступ извне.

Примечание. Область действия функции и область действия блока напрямую не связаны.

  • const, let, var разница
  1. Объявление константы не может быть изменено, область действия блока и продвижение переменной не разрешены.
  2. let имеет блочную область видимости и не позволяет поднимать переменные.
  3. var не имеет блочной области видимости, что позволяет поднимать переменные.

цепочка прицелов

Когда есть функция, вложенная в функцию, будет цепочка областей видимостиscope chain.

  • Правила обхода цепочки вложенных областей видимости просты: движок начинает искать переменные в текущей области выполнения, и если не находит, продолжает поиск на один уровень вверх. Когда достигается самая внешняя глобальная область, процесс поиска останавливается независимо от того, найдена она или нет.
  • Локальная область (например, область функции) может получить доступ к переменным и методам в глобальной области, в то время как глобальная область не может получить доступ к переменным и методам в локальной области.

Интерпретируйте замыкания с точки зрения цепочек областей видимости:

function outter() {
  var private= "I am private";
  function show() {
    console.log(private);
  }
// [[scope]]已经确定:[outter上下文的变量对象,全局上下文变量对象]
  return show;
}

var ref = outter();
console.log(private);  // outter执行完以后,private不会被销毁,并且只能被show方法所访问,
                          //直接访问它会出现报错:private is not defined
ref(); // 打印I am private

На самом деле, нам нужно понимать, что объявление и вызов функций разделены, и если мы этого не понимаем, многие основные вопросы на собеседовании подвержены ошибкам.

  • добраться до сути:

Лексическая область видимости и динамическая область видимости в JavaScript #3

переменный жизненный цикл

Объявление переменной означает, что мы выделили место в памяти для хранения. Эта память также является рабочей памятью нашего компьютера, если мы продолжаем объявлять переменные и не освобождать их. Будет занимать много памяти.

В c/c++ программисты должны вручную освобождать переменную память в соответствующих местах, в то время как javascript и java имеют механизмы сборки мусора (которые мы объяснили выше).

js переменные делятся на два типа: глобальные переменные и локальные переменные

  1. Жизненный цикл глобальных переменных: от начала выполнения программы и создания до закрытия всей страницы происходит вызов переменных.
  2. Жизненный цикл локальных переменных: от начала вызова функции до конца вызова функции.

Но иногда нам нужно сделать жизненный цикл локальных переменных немного длиннее, что и используется в данный момент.Закрытие.

3. Цепочка прототипов

Экземпляры и прототипы

Невидимые свойства объекта-прототипа указывают на явные свойства конструктора, создавшего его.

Когда объект ищет свои свойства, если он не может их найти, он ищет свойства своего конструктора и продолжает поиск, пока не найдет Object().

Определить тип данных

  1. typeof
  2. instanceof
  3. constructor
  4. Object.prototype.toString.call()

новый объект

шаг:

  1. создать новый объект
  2. назначьте область конструктора новому объекту (так что это указывает на новый объект)
  3. Выполните код в конструкторе (добавьте свойства к этому новому объекту)
  4. вернуть новый объект

это указывает на

это указывает на 5 больших правил:

  1. Если ключевое слово new появляется перед вызываемой функцией, движок JavaScript создаст новый объект, а this в вызываемой функции указывает на вновь созданную функцию.
  2. Если функция запускается с помощью применения, вызова или привязки, this в функции указывает на первый параметр, переданный в функцию.
  3. Если функция является методом объекта, и объект использует точку для запуска функции, то this указывает на объект, функция которого является свойством этого объекта, то есть this указывает на объект слева от точки
  4. Если функция вызывается как FFI, это означает, что функция не соответствует ни одному из вышеперечисленных методов вызова, и это указывает на глобальный объект, которым является окно в браузере.
  5. Если вышеуказанные правила накапливаются, приоритет уменьшается с 1 до 4, и балл этого оценивается в соответствии с правилом с наивысшим приоритетом.

Ссылаться на:это указывает на 5 принципов памяти

  • Это в стрелочных функциях указывает на: this в стрелочных функциях привязывается, когда функция определена, а не когда функция выполняется.

Более:Стрелочные функции в JS и это

связываться, звонить, обращаться

  • call

Первый параметр, полученный методом call(), совпадает с параметром, полученным методом apply(), за исключением того, что остальные параметры передаются непосредственно в функцию. Другими словами, при использовании метода call() параметры, передаваемые в функцию, должны быть перечислены один за другим.

function sum(num1 , num2){
	return num1 + num2;
}
function callSum(num1 , num2){
	return sum.call(this , sum1 , sum2);
}
console.log(callSum(10 , 10)); // 20
  • apply

Метод apply() принимает два параметра: один — это область, в которой должна выполняться функция, а другой — массив аргументов, где массив аргументов может быть экземпляром Array или объектом arguments (массивоподобным объектом). .

function sum(num1 , num2){
	return num1 + num2;
}
function callSum1(num1,num2){
	return sum.apply(this,arguments); // 传入arguments类数组对象
}
function callSum2(num1,num2){
	return sum.apply(this,[num1 , num2]); // 传入数组
}
console.log(callSum1(10 , 10)); // 20
console.log(callSum2(10 , 10)); // 20

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

  • bind

Метод bind() создает новую функцию, которая при вызове устанавливает ключевое слово this в предоставленное значение, а при вызове новой функции предоставляет заданную последовательность аргументов перед любым предоставленным.

Рукописная темная и светлая копия

мелкий:

function clone(target) {
    let cloneTarget = {};
    for (const key in target) {
        cloneTarget[key] = target[key];
    }
    return cloneTarget;
};

Глубокий (рекурсивный):

function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

Чтобы узнать больше, рекомендуем прочитать:Как написать глубокий текст, который удивит интервьюера?

В-четвертых, наследование js

Восемь методов наследования, подробнее см. в этой статье:Восемь распространенных схем наследования в JavaScript.

Эта дыня не буду вдаваться в подробности, но могу перечислить два-три ключевых момента, которые необходимо помнить.

Серия третья:
Не могли бы вы рассказать о принципе Vue?

Эта дыня больше не устанавливается, и разборки окончены. На самом деле, временная шкала написания структуры каталогов для этой статьи находится в«Исходный код Vue (v2.6.11) Wanxing сырой, просто сложный! 》перед этой статьей. В то время именно из-за смутного понимания я решил «съесть исходный код сырым». Теперь, когда исходный код прочитан, ощущения действительно другие. Однако из-за слишком большого количества деталей пространство ограничено. Здесь указан только кадр, основные моменты и ссылки на аннотации перечислены для облегчения запоминания.

Одна картинка стоит тысячи слов

  • Оригинальная карта мозга, пожалуйста, укажите источник для перепечатки

Знания последовательно: инициализация и жизненный цикл Vue, виртуальный DOM, принцип адаптивности, компиляция компонентов, общие дополнения Vue, сегмент семейства Vue.

Последовательная память: сочинить джингл, посмеяться.

V U E так просто
инициализировать живым
Виртуальный дом это круто
Отзывчивый взгляд внимательно
Компонентизация выгодна всем
семейное ведро смеется
Упакую и заработаю 100 миллионов

  • Приглашайте всех редактировать

1. инициализация и рендеринг

смонтировать и инициализировать

Что случилось с новым Vue()?

Vue на самом деле является классом, а классы реализованы в Javascript с помощью функций. Vue можно инициализировать только ключевым словом new, после чего будет вызван метод this._init.

Основная реализация инициализации: слияние конфигурации (mergeOptions), инициализация жизненного цикла (initLifecycle), инициализация центра событий (initEvents), инициализация рендеринга (initRender), инициализация данных, реквизита, вычисляемого, наблюдателя и т.д.

Ссылка на блок-схему выглядит следующим образом:

  • На этом рисунке отсутствует оптимизация процесса компиляции компонентов, возможно, из-за различий в версиях.Исходный код Vue2.4.4
  • Заимствуя изображение, реальный источник не был найден, и ссылка зарезервирована для объяснения ямы.

жизненный цикл экземпляра

схема жизненного цикла, вам все равно придется заглянуть в официальную документацию веб-сайта. Помните эту фразу?

На следующей диаграмме показан жизненный цикл экземпляра. Вам не нужно разбираться во всем сразу, но по мере того, как вы продолжаете изучать и использовать его, его эталонное значение будет становиться все выше и выше.

Аннотированная версия:

рекомендовать:Интерпретация исходного кода

Важные заметки:

  1. И функция beforeCreate, и функция created выполняются в методе _init на этапе создания экземпляра Vue. Из исходного кода вы можете видеть, что вызовы ловушек beforeCreate и created находятся до и после initState.Функция initState заключается в инициализации таких свойств, как реквизиты, данные, методы, часы, вычисляемые и т. д. Тогда, очевидно, функция ловушки beforeCreate не может получить значения, определенные в свойствах и данных, а также не может быть вызвана функция, определенная в методах. И созданная функция ловушки может.
Vue.prototype._init = function (options?: Object) {
  // ...
  initLifecycle(vm)
  initEvents(vm)
  initRender(vm)
  callHook(vm, 'beforeCreate') // beforeCreate 钩子
  initInjections(vm) // resolve injections before data/props
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  callHook(vm, 'created') // created 钩子
  // ...
}
  1. Прежде чем выполнять функцию vm._render() для рендеринга VNode, выполните функцию ловушки beforeMount и выполните установленную ловушку после выполнения vm._update(), чтобы привязать VNode к реальному DOM. (это важно)

  2. Время выполнения beforeUpdate вызывается в функции before рендеринга Watcher. Время выполнения обновления составляетflushSchedulerQueueпри вызове функции.

  3. Время выполнения функций beforeDestroy и уничтоженных хуков находится на стадии уничтожения компонента.

  4. Активированные и деактивированные функции хуков — это настраиваемые хуки для компонентов поддержки активности.

Основные моменты:

  1. В Vue2 для рендеринга всех компонентов Vue в конечном итоге требуется метод рендеринга.Разрабатываем ли мы компоненты в виде одного файла .vue или пишем атрибуты el или шаблона, они в конечном итоге будут преобразованы в методы рендеринга для рендеринга экземпляра в виртуальный узел (Virtual DOM).

2. Виртуальный дом

Самым большим обновлением Vue 2.0 по сравнению с Vue 1.0 является использование Virtual DOM.

vdom

vdom на самом деле представляет собой дерево объектов js, которое содержит как минимум три атрибута: имя тега (tag), атрибут (attrs) и объект дочернего элемента (children). Первоначальная работа узлов DOM (браузер разработал DOM очень сложной) преобразуется в работу объектов js, что ускоряет обработку и повышает производительность.

Создание VNode достигается методом createElement.

Для понимания принципа рекомендуется прочитать:snabbdom

diff & patch

В реальном коде выполняется глубокий обход старого и нового деревьев, и каждый узел будет иметь маркер. Каждый раз при обходе узла узел сравнивается с новым деревом, и если есть различие, оно записывается в объект. То есть используйте алгоритм diff для сравнения различий, а затем вызовите patch, чтобы применить его к реальному DOM. Процесс исправления — это процесс исправления.

Источник изображения

Алгоритм diff представляет собой процесс перекрестного сравнения, который можно кратко охарактеризовать как прямое сравнение, последовательное сравнение, прямое сравнение и прямое сравнение.

Для получения подробной информации о различиях начального уровня рекомендуется прочитать эту статью:LINK

Источник изображения

Примечание. Функция рендеринга возвращает vdom, а сгенерированный патч является настоящим DOM.

3. Принцип отзывчивости

Официальная фотография, высотное здание.

Бенгуа была в«Краткий анализ принципа двустороннего связывания Vue»Я написал эту статью, и теперь я снова чувствую это.

Когда вы передаете обычный объект JavaScript в экземпляр Vue в качестве параметра данных, Vue перебирает все свойства этого объекта и использует Object.defineProperty для преобразования всех этих свойств в геттеры/сеттеры. Object.defineProperty — это функция, которую нельзя изменить в ES5, поэтому Vue не поддерживает браузеры IE8 и более ранних версий.

Публикация шаблона подписчика (экзаменационные вопросы по байтам)

class emit {
}
cosnt eeee =  new emit()
eeee.on('aa' , function() { console.log(1)})
eeee.on('aa' , function() {console.log(2)})
eeee.emit('aa')
//class emit{}

// Требуется рукописный шаблон издатель-подписка

class Subject{
    constructor () {
      this.observers =[]
    }
    add (observer) {
      this.observers.push(observer)
    }
    notify () {
      this.observers.map((item, index) => {
          item.update()
      })
    }
}
class Observer {
    constructor (name) {
        this.name = name
    }
    update () {
        console.log("I`m " + this.name)
    }
}
var sub = new Subject()
var obs1 = new Observer("obs1")
var obs2  = new Observer("obs2")
sub.add(obs1)
sub.add(obs2)
sub.notify() // I`m obs1   I`m obs2

Помимо «шаблона подписки издателя», какие еще шаблоны проектирования js вы знаете? Оставь здесь дырку и заделай потом, слишком много всего...

Observe

Функция наблюдения заключается в отслеживании изменений в данных. Его роль заключается в добавлении геттеров и сеттеров к свойствам объекта для зависимостей для сбора и отправки обновлений:

Вставьте сюда фрагмент исходного кода, мы это чувствуем:

export class Observer {
  value: any;
  dep: Dep;
  vmCount: number; // number of vms that has this object as root $data
  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
    def(value, '__ob__', this)
    ...
  }
  walk (obj: Object) {
   ...
  }
  observeArray (items: Array<any>) {
    ...
  }
}

Считаете ли вы, что это похоже на упомянутый выше шаблон «публикация-подписка». Observer сначала создает экземпляр объекта Dep, а затем добавляет свой собственный экземпляр к значению объекта данных, выполняя функцию def.obхарактеристики. (Функция def — это простая оболочка вокруг Object.defineProperty).

Dep

Dep является ядром всей коллекции зависимостей геттера.

Поскольку существует несколько наблюдателей, необходимо использовать Dep для сбора изменений и централизованного управления ими, а затем уведомлять соответствующие наблюдатели. Также легко понять, что Dep зависит от Watcher.

Вставьте фрагмент исходного кода и почувствуйте его:

export default class Dep {
  static target: ?Watcher;
  id: number;
  subs: Array<Watcher>;
  constructor () {
    this.id = uid++
    this.subs = []
  }
  addSub (sub: Watcher) {
    this.subs.push(sub)
  }
  removeSub (sub: Watcher) {
    remove(this.subs, sub)
  }
  depend () {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }
  notify () {
    // stabilize the subscriber list first
    ...
}

Watcher

Вставьте фрагмент исходного кода, почувствуйте один или два:

export default class Watcher {
  vm: Component;
  expression: string;
  cb: Function;
  id: number;
  deep: boolean;
  user: boolean;
  computed: boolean;
  sync: boolean;
  dirty: boolean;
  active: boolean;
  dep: Dep;
  deps: Array<Dep>;
  newDeps: Array<Dep>;
  depIds: SimpleSet;
  newDepIds: SimpleSet;
  before: ?Function;
  getter: Function;
  value: any;
  
  constructor (
    vm: Component,
    expOrFn: string | Function,
    cb: Function,
    options?: ?Object,
    isRenderWatcher?: boolean
  ) {
    this.vm = vm
    if (isRenderWatcher) {
      vm._watcher = this
    }
    vm._watchers.push(this)
    // options
   ...
    // parse expression for getter
   ...
  }
  get () {
    pushTarget(this)
    ...
  }
  addDep (dep: Dep) {
    const id = dep.id
    ...
  }
  cleanupDeps () {
    ...
  }
  // ...
}

Наблюдатель будет уведомлять о просмотре обновленийre-render.

Распространенные сценарии обновления представления:

  1. Изменение данных → изменение представления с использованием данных (соответствует: render-watcher отвечает за обновление представления)
  2. изменение данных → использовать изменение вычисляемого свойства данных → использовать изменение представления вычисляемого свойства (соответственно: выполнить вычисляемый-наблюдатель, который требует обновления вычисляемого свойства)
  3. Изменение данных → Выполняется функция обратного вызова наблюдения, активно зарегистрированная разработчиком (соответствует: обычному наблюдателю, зарегистрированному пользователем (watch-api или атрибут наблюдения))

4. Компиляция компонентов

Идея компонентов также является ядром Vue, и компиляция компонентов в vdom — тоже непростая задача!

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

компоненты

Официальный пример:

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

<div id="components-demo">
  <button-counter></button-counter>
</div>

new Vue({ el: '#components-demo' })

Компоненты также включают в себя: связь между компонентами, слоты, динамические компоненты и т. д. Последующая таблица (ОС: Вот такую ​​большую яму я себе выкопал).

parse

Процесс компиляции сначала анализирует шаблон для создания AST, который представляет собой абстрактное синтаксическое дерево и древовидное представление абстрактной синтаксической структуры исходного кода. Во многих методах компиляции, таких как babel, при компиляции кода ES6 сначала создается AST. Этот процесс будет использовать большое количество регулярных выражений для разбора строки,Исходный код трудно читать.

Но что нам нужно знать, так это четыре функции начала, конца, комментария и символов.

Процесс обработки обычных тегов примерно таков:

  1. Определите начальный тег и сгенерируйте соответствие структуры.
  2. Обработать атрибуты, обработать массив в {имя: 'xxx', значение: 'xxx'}
  3. Сгенерируйте astElement, обработайте теги if и Once.
  4. Определите закрывающие теги и обработайте элементы, не закрывая теги вместе.
  5. Установите отношения родитель-потомок и, наконец, выполните всю обработку пары, связанной с атрибутами Vue, на astElement. слот, компонент и т. д.

Справочное чтение:Подробный анализ Vue из шаблона в исходный код astElement

optimize

Когда наш шаблон шаблона пройдет процесс разбора, он выведет дерево AST, затем нам нужно оптимизировать это дерево — оптимизировать.

Самое главное в оптимизации — пометить статические корни (markStaticRoots) и статические узлы (markStatic). В случае статических узлов генерируемая ими модель DOM никогда не нуждается в изменении, что делает обновление шаблонов еще более забавным (неизменные узлы не нужно обновлять).

Вопрос: Почему тип элемента дочернего узла является статическим текстовым типом, что увеличивает стоимость процесса оптимизации?

Прежде всего, давайте проанализируем, почему этот статический корневой узел оптимизируется в процессе оптимизации, какова цель и какова стоимость?

Цель: В процессе исправления уменьшить ненужный процесс сравнения и ускорить обновление.

Стоимость: а) Необходимость поддерживать объект хранения для статических шаблонов. B. Вызовы функций многослойного рендеринга.

Рекомендуемое чтение

codegen

Последним шагом компиляции является преобразование оптимизированного дерева AST в исполняемый код, то есть в ссылку codegen.

Основные шаги (вызов функции):

  1. generate
  2. genIf
  3. genFor
  4. genData & genChildren

Экзаменов в этом разделе не много, просто для понимания. Чтобы узнать больше, см. исходный код.

5. Часто используемые добавки

поддерживающий жизнь

keepalive — это компонент, встроенный в Vue, который может сохранять состояние содержащихся компонентов или избегать повторного рендеринга. Также известен как кеш компонентов.

v-если, v-показать, v-для

Три высокочастотные подпроблемы:

  1. В чем разница между v-if и v-show?

Ответ: v-if эквивалентно отображению; v-show эквивалентно видимости; первое управляет созданием, второе — только скрытием и отображением.

  1. Почему нельзя использовать v-if и v-for вместе?

A: Поскольку v-for имеет более высокий приоритет, чем v-if, он будет проходить по всему списку каждый раз при повторном отображении, а затем выполнять if, чтобы определить, отображать ли его, что снижает производительность.

  1. Можно ли использовать индекс в качестве ключа в v-for?

Ответ: Ключ используется для сравнения в алгоритме diff.Использование индекса в качестве ключа не идентифицирует однозначно.При вставке элементов ключ также будет меняться. index в качестве ключа применим только к выходным данным рендеринга списка (описание официального веб-сайта), которые не зависят от состояния дочернего компонента или временного состояния DOM (например, входное значение формы).

Я не буду давать здесь подробный ответ, если вы хотите узнать больше, пожалуйста, решите это сами.

пользовательская директива

Миксины, пользовательские директивы и фильтры в Vue имеют нечто общее: при регистрации вам необходимо сбалансировать преимущества и недостатки локальной регистрации и глобальной регистрации.

transition

В процессе чтения исходного кода я обнаружил, что в исходном коде много места, описывающегоtransition. В официальной документации переход также описывается как самостоятельный важный раздел.Ввод/выход и список переходов, анимацию и переходы Vue легко не заметить.

Шесть, вся семейная бочка

После использования Vue Family Bucket мои ноги больше не болят, а талия не болит. Эй, написав пять страниц за один раз, маме больше не нужно беспокоиться о моей учебе. (Кажется, это реклама...)

Vue-Router

Официальный менеджер маршрута

Разделен на два режима: хэш и история

  • Режим хеширования по умолчанию, путем добавления точек привязки
  • история реализована с помощью API history.pushState

Родной: В HTML5 появились методы history.pushState() и history.replaceState(), которые соответственно добавляют и изменяют записи истории. Эти методы обычно используются в сочетании с window.onpopstate.Ссылка на подробности

Vuex

Управление официальным статусом

Он состоит из следующих основных частей:

  1. состояние: состояние данных;
  2. мутации: состояние изменения (состояние вычисления);
  3. геттеры: фильтруют состояние в состоянии и получают новое состояние;
  4. действия: выполнять множественные мутации, которые могут выполнять асинхронные операции (async);
  5. модули: классифицируйте статус и правила управления, чтобы сделать структуру каталогов более понятной;

VueCLI

официальные леса

  • Самое главное в VueCLI4 — это конфигурация файла vue.config.js.

VuePress

генератор статических сайтов

  • Используя Vue + webpack, вы можете использовать компоненты Vue в Markdown, страница проста и элегантна, а стиль официального сайта Vue унифицирован.

NuxtJS

рендеринг на стороне сервера

Семь, веб-пакет

Если у вас есть около двух лет опыта работы с интерфейсом, вы должны попросить себя освоить инструмент упаковки.

принцип веб-пакета

Официальное объяснение:

webpack — это сборщик статических модулей для современных приложений JavaScript. Когда веб-пакет обрабатывает приложение, он внутренне строит граф зависимостей, который сопоставляет каждый модуль, требуемый проектом, и генерирует один или несколько _bundle_s.

Основная идея:

  1. Entry: Entry, первый шаг в выполнении сборки Webpack начнется с Entry, который можно абстрагировать во входные данные.
  2. Модуль: модуль, все является модулем в Webpack, а модуль соответствует файлу. Webpack будет рекурсивно находить все зависимые модули, начиная с настроенного Entry.
  3. Чанк: блок кода, фрагмент состоит из нескольких модулей для слияния и разделения кода.
  4. Загрузчик: преобразователь модулей, который используется для преобразования исходного содержимого модуля в новое содержимое по мере необходимости.
  5. Плагин: Плагины-расширения, которые транслируют соответствующие события в определенное время в процессе создания Webpack. Плагины могут отслеживать возникновение этих событий и выполнять соответствующие действия в определенное время.

Функция:

Преобразование кода, оптимизация файлов, разделение кода, объединение модулей, автоматическое обновление, проверка кода, автоматическая публикация.

Оптимизация скорости упаковки

  1. Оснащен плагином webpack-parallel-uglify-plugin для ускорения процесса «сжатие JS => компиляция в AST => восстановление JS».
  2. Используйте HappyPack для повышения скорости парсинга загрузчика.
  3. Предварительно упакован с использованием подключаемых модулей DLLPlugin и DLLReferencePlugin.
  4. tree-shaking используется для исключения бесполезных модулей.

АМД, ЦМД

Существует четыре спецификации модуляризации внешнего интерфейса: CommonJS, AMD, CMD, ES6.

  1. AMD (определение асинхронного модуля)
  2. CMD (Общее определение модуля)
AMD (определение асинхронного модуля) CMD (Общее определение модуля)
высокоскоростной плохая работа
будут тратить ресурсы Загружайте зависимости только тогда, когда они действительно нужны
Все зависимости предварительно загружены и не выполняются до тех пор, пока они не будут использованы Зависимости не определены, пока они не используются
  1. Node.js является основным практиком спецификации commonJS: модуль,module.exports (экспорт),require, Глобальный.

  2. На уровне языковых стандартов ES6 реализует функцию модуля, которая в основном состоит из двух команд:exportа такжеimport. Команда экспорта используется для указания внешнего интерфейса модуля, а команда импорта используется для импорта функций, предоставляемых другими модулями.

В: Сравните разницу между импортом и требованием?

import require
Модульные решения в стандарте ES6 Это модульное решение на узле, соответствующее спецификации CommonJS.
Динамический импорт не поддерживается Поддержка динамического импорта
ключевое слово не ключевое слово
Загружается во время компиляции, должен быть размещен в верхней части модуля Загружается во время выполнения, теоретически его можно разместить где угодно
лучшая производительность плохая работа
Режим привязки в реальном времени, то есть как импортированные, так и экспортированные значения указывают на одно и то же место в памяти. При экспорте значение копируется, даже если экспортируемое значение изменится, импортированное значение не изменится.
Будет скомпилирован в require/export для выполнения -

Более:Модульность интерфейса: CommonJS, AMD, CMD, ES6.

Реализовать подключаемый модуль (тестовый центр Tencent WXG)

  1. Создайте файл plugins/demo-plugin.js;
  2. Параметры передачи параметров;
  3. Запись в файл через компиляцию;
  4. Управление предупреждениями и ошибками

Реализация плагина Webpack с нуля

Серия четвертая:
Какой ваш любимый алгоритм?

На самом деле Бенгуа хочет ответить: мне больше всего нравится вычитание! Потому что счастливая жизнь требует вычитания. 😄

Алгоритм — это часть, которая существует уже давно, так как от него нельзя убежать, бросьте ему вызов! На самом деле это не так сложно.

Одна картинка стоит тысячи слов

  • Оригинальная карта мозга, пожалуйста, укажите источник для перепечатки

Объединение точек знаний: структура данных, базовый алгоритм, алгоритм сортировки, расширенный алгоритм.

Серийная память:

Я не боюсь алгоритмов
структура данных
Сортировка обхода Я самый скользкий
Указательная динамическая жадная кисть

1. Структура данных

очередь

Первым прибыл, первым обслужен.

куча

Первый пришел, последний вышел.

куча

Куча обычно представляет собой объект массива, который можно рассматривать как дерево.

Куча всегда удовлетворяет следующим свойствам:

  1. Значение узла в куче всегда не больше и не меньше значения его родительского узла;
  2. Куча всегда является полным бинарным деревом.
  • Полное бинарное дерево: в бинарном дереве, если все слои, кроме последнего слоя, заполнены, а последний слой либо заполнен, либо не имеет нескольких последовательных узлов справа, бинарное дерево является полным бинарным деревом (Complete Binary Tree) — wiki .

(Бенгуа замучили по этому поводу, большая фабрика должна пройти тест «Структура данных», не убегайте, вам придется рано или поздно вернуть его, если вы выйдете и возитесь.)

связанный список

  • Круговой список (испытательный участок)
// 循环链表
function Node(element){
    this.element = element;
    this.prev = null;
    this.next = null;
}
function display(){
    var current = this.head;
    //检查头节点当循环到头节点时退出循环
    while(!(current.next == null) && !(current.next.element=='head')){
        print(current.next.element);
        current = current.next;
    }
}
function Llist(){
    this.head = new Node('head');
    this.head.next = this.head;
    this.find = find;
    this.insert = insert;
    this.display = display;
    this.findPrevious = findPrevious;
    this.remove = remove;
}

хэш

Хэш-функция (англ. Hash function) также известна как хеш-алгоритм, хеш-функция. Хранить данные как Key:Value.

Самая большая особенность хеш-таблицы заключается в том, что данные для поиска можно быстро найти, а временная сложность запроса близка к O (1). Bengua предполагает, что вы можете позаботиться о временной сложности операций «добавить, удалить, изменить и проверить» всех структур данных здесь, и они также будут протестированы.

временная сложность, пространственная сложность

Простое понимание:

  1. Количество циклов записывается в виде выражения n, что является временной сложностью.
  2. Количество применяемых переменных записывается как выражение n, которое является пространственной сложностью.

Временная сложность важнее, общая временная сложность: O(1), O(n), O(logn), На2).Эта дыня маленький СОВЕТ: Если вы не знаете, как рассчитать собеседование/письменный тест, просто угадайте это здесь. Если это не сработает, ответьте: O(n) ~ O(n2), есть большая вероятность, что не ошибется🐶.

обход дерева (ширина, глубина)

Обход в ширину (BFS):

Очереди необходимы для хранения узловых объектов.Пример

Обход в глубину (DFS):

  1. Предварительный порядок (корневой узел -> левое поддерево -> правое поддерево)
  2. В порядке (левое поддерево -> корневой узел -> правое поддерево)
  3. Postorder (левое поддерево -> правое поддерево -> корень)

2. Основной алгоритм

рекурсивное мышление

  • Знаменитую последовательность Фибоначчи, которую нужно знать!
function result(){
    if(n==1||n==2){
        return 1
    }
    return reslt(n-2)+result(n-1)
}
  • Функцию каррирования вам тоже нужно знать!

Каррирование функций: метод преобразования функции, которая принимает несколько параметров, в функцию, которая принимает один параметр (первый параметр исходной функции) и возвращает новую функцию, которая принимает остальные параметры и возвращает результат. - вики

    // 普通方式
    var add1 = function(a, b, c){
        return a + b + c;
    }
    // 柯里化
    var add2 = function(a) {
        return function(b) {
            return function(c) {
                return a + b + c;
            }
        }
    }
    // demo
    var foo = function(x) {
        return function(y) {
            return x + y
        }
    }
    foo(3)(4)       // 7

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

дихотомия

Дихотомии надо писать от руки, что на самом деле нехорошо.Можно и под диктовку писать!

// 二分法:先排序,再找目标
function binary_search(arr,target) {
    let min=0
    let max=arr.length-1
    while(min<=max){
    	let mid=Math.ceil((min+max)/2)
    	if(arr[mid]==target){
    		return mid
    	}else if(arr[mid]>target){
    		max=mid-1
    	}else if(arr[mid]<target){
    		min=mid+1
    	}
    }
	return "null"
}
console.log(binary_search([1,5,7,19,88],19))//3

В-третьих, алгоритм сортировки

Сортировка — относительно распространенная и важная часть, и здесь не все перечислено. только ударениеБыстрый ряда такжепузырь, вы также можете использовать двойные петли.

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

// 快排:选取基准,比基准大的放右边,比基准小的放左边,然后两边用递归
function quickSort(arr, i, j) {
  if(i < j) {
    let left = i;
    let right = j;
    let pivot = arr[left];
    while(i < j) {
      while(arr[j] >= pivot && i < j) {  // 从后往前找比基准小的数
        j--;
      }
      if(i < j) {
        arr[i++] = arr[j];
      }
      while(arr[i] <= pivot && i < j) {  // 从前往后找比基准大的数
        i++;
      }
      if(i < j) {
        arr[j--] = arr[i];
      }
    }
    arr[i] = pivot;
    quickSort(arr, left, i-1);
    quickSort(arr, i+1, right);
    return arr;
  }
}

Пузырьковая сортировка

// 冒泡:双层循环
    var arr=[10,20,50,100,40,200];
    for(var i=0;i<arr.length-1;i++){
        for(var j=0;j<arr.length-1-i;j++){
        if(arr[j]>arr[j+1]){
            var temp=arr[j]
            arr[j]=arr[j+1]
            arr[j+1]=temp
        }
    }
    }
    console.log(arr)

Четвертый, продвинутый алгоритм

двойной указатель

См. «упорядоченный» и «массив». Мгновенно занесите метод двойного указателя в память вашего мозга. Обычные двойные указатели не могут работать, а я сразу хочу столкнуться с указателями!

Пример: объединение двух отсортированных массивов (решение с двойным указателем)

示例: 输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
const merge = function(nums1, m, nums2, n) {
    // 初始化两个指针的指向,初始化 nums1 尾部索引k
    let i = m - 1, j = n - 1, k = m + n - 1
    // 当两个数组都没遍历完时,指针同步移动
    while(i >= 0 && j >= 0) {
        // 取较大的值,从末尾往前填补
        if(nums1[i] >= nums2[j]) {
            nums1[k] = nums1[i] 
            i-- 
            k--
        } else {
            nums1[k] = nums2[j] 
            j-- 
            k--
        }
    }
    
    // nums2 留下的情况,特殊处理一下 
    while(j>=0) {
        nums1[k] = nums2[j]  
        k-- 
        j--
    }
};

передовой!

динамическое программирование

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

В то же время для динамического программирования необходимо выполнение следующих двух важных свойств:

  1. оптимальное основание
  2. Перекрывающиеся свойства подзадачи

Пример динамического программирования: последовательность Фибоначчи (упомянутая выше)

Последовательность Фибоначчи: используется рекурсия, хотя код очень простой, но, очевидно, по мере увеличения количества раз дерево рекурсии становится очень большим и занимает много времени.

Реализуйте последовательность Фибоначчи с помощью динамического программирования, код выглядит следующим образом

    function feiBoLaQie(n) {
        //创建一个数组,用于存放斐波拉契数组的数值
        let val = [];
        //将数组初始化,将数组的每一项都置为0
        for(let i =0 ;i<=n;i++){
            val[i] = 0;
        }
        if (n==1 || n==2){
            return 1;
        } else{
            val[1] = 1;
            val[2] = 2;
            for (let j =3; j<=n;j++){
                val[j] = val[j-1] + val[j-2];
            }
        }
        return val[n-1];
    }
    console.log(feiBoLaQie(40));//102334155

Промежуточные результаты хранятся в массиве val.Если вычисляемое число Фибоначчи равно 1 или 2, оператор if вернет 1. В противном случае значения 1 и 2 будут храниться в позициях 1 и 2 в массиве val.

Цикл будет проходить от 3 до входных параметров, назначать каждый элемент массива как сумму первых двух элементов и заканчивать цикл, значение последнего элемента массива является окончательным вычисленным значением Фибоначчи. Это значение также будет используется как возвращаемое значение функции.

Динамическое программирование решает быстрее.

как дела

Жадный алгоритм следует методу приближенного решения задач, надеясь достичь глобального оптимума (глобального оптимального решения) посредством выбора локального оптимума (текущего лучшего решения) на каждом этапе.

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

Пример: задача минимальной сдачи монеты

是给出要找零的钱数,以及可以用硬币的额度数量,找出有多少种找零方法。
如:美国面额硬币有:1,5,10,25
我们给36美分的零钱,看能得怎样的结果?
function MinCoinChange(coins){
    var coins = coins;
    var cache = {};
    this.makeChange = function(amount){
        var change = [], total = 0;
        for(var i = coins.length; i >= 0; i--){
            var coin = coins[i];
            while(total + coin <= amount){
                change.push(coin);
                total += coin;
            }
        }
        return change;
    }
}
var minCoinChange = new MinCoinChange([1, 5, 10, 25]);
minCoinChange.makeChange(36);
//[25, 10, 1] 即一个25美分、一个10美分、一个1美分

Серия пятая:
веб-безопасность вы знаете, что?

Одна картинка стоит тысячи слов

  • Оригинальная карта мозга, пожалуйста, укажите источник для перепечатки

Объединенные точки знаний: междоменные, XSS (атака с использованием межсайтовых сценариев), CRFS (подделка межсайтовых запросов), SQL-инъекция, перехват DNS, перехват HTTP.

Серийная память:Три кросса, два угона и одна инъекция

1. Междоменный

междоменное определение

Когда любой из протоколов, доменных имен и портов URL-адреса запроса отличается от URL-адреса текущей страницы, он является междоменным.

Междоменные ограниченияЭто защитный механизм браузера, если он кроссдоменный, то:

  1. Файлы cookie, LocalStorage и IndexedDB для страниц из разных источников не могут быть прочитаны.
  2. Невозможно коснуться DOM страниц разного происхождения.
  3. Невозможно отправить запрос AJAX на адрес другого происхождения

междоменное разрешение

Междоменное решение:

  1. JSONP;
  2. CORS (обмен ресурсами между источниками);
// 普通跨域请求:只需服务器端设置 Access-Control-Allow-Origin。
// 带cookie跨域请求:前后端都需要进行设置。

// 如前端在 axios 中设置
axios.defaults.withCredentials = true
  1. прокси-сервер проекта vue;
  2. nginx-прокси;
  3. Установите document.domain, чтобы решить проблему с файлами cookie, которые невозможно прочитать с веб-страниц другого происхождения;
  4. API междокументного взаимодействия: window.postMessage();

2. XSS

Принципы XSS

Принцип XSS заключается в том, что веб-приложение смешивает данные, отправленные пользователем, и границу кода JS-скрипта, в результате чего браузер выполняет ввод пользователя как JS-код. Целью XSS-атаки являются обычные пользователи на стороне браузера.

Пример:

<input type="text" value="<%= getParameter("keyword") %>">
<button>搜索</button>
<div>
  您搜索的关键词是:<%= getParameter("keyword") %>
</div>

когда браузер запрашивает

http://xxx/search?keyword="><script>alert('XSS');</script>

вредоносный код, он выполнит

Отраженный XSS

Сохраненные шаги атаки XSS:

  1. Злоумышленники отправляют вредоносный код в базу данных целевого веб-сайта.
  2. Когда пользователь открывает целевой веб-сайт, сервер веб-сайта извлекает вредоносный код из базы данных, встраивает его в HTML и возвращает браузеру.
  3. После получения ответа браузер пользователя разбирает и выполняет его, а также выполняется подмешанный в него вредоносный код.
  4. Вредоносный код крадет пользовательские данные и отправляет их на сайт злоумышленника или имитирует поведение пользователя и вызывает интерфейс целевого веб-сайта для выполнения операции, указанной злоумышленником.

Этот тип атаки распространен в функциях веб-сайта с сохраненными пользователем данными, такими как сообщения на форуме, обзоры продуктов, личные сообщения пользователей и т. д.

Сохраненный XSS

Этапы атаки отраженного XSS:

  1. Злоумышленники создают специальные URL-адреса, содержащие вредоносный код.
  2. Когда пользователь открывает URL-адрес с вредоносным кодом, сервер веб-сайта извлекает вредоносный код из URL-адреса, объединяет его в HTML и возвращает браузеру.
  3. После получения ответа браузер пользователя разбирает и выполняет его, а также выполняется подмешанный в него вредоносный код.
  4. Вредоносный код крадет пользовательские данные и отправляет их на сайт злоумышленника или имитирует поведение пользователя и вызывает интерфейс целевого веб-сайта для выполнения операции, указанной злоумышленником.

Разница между отраженным XSS и сохраненным XSS заключается в том, что вредоносный код сохраненного XSS хранится в базе данных, а вредоносный код отраженного XSS хранится в URL-адресе.

Тип DOM XSS

Этапы атаки XSS типа DOM:

  1. Злоумышленники создают специальные URL-адреса, содержащие вредоносный код.
  2. Пользователь открывает URL с вредоносным кодом.
  3. После получения ответа браузер пользователя анализирует и выполняет его, а интерфейсный JavaScript извлекает вредоносный код из URL-адреса и выполняет его.
  4. Вредоносный код крадет пользовательские данные и отправляет их на сайт злоумышленника или имитирует поведение пользователя и вызывает интерфейс целевого веб-сайта для выполнения операции, указанной злоумышленником.

Разница между XSS типа DOM и первыми двумя типами XSS: в атаках XSS типа DOM извлечение и выполнение вредоносного кода осуществляется браузером, что является уязвимостью безопасности самого интерфейса JavaScript, в то время как два других типа XSS являются уязвимостями безопасности на стороне сервера.

XSS-защита

  1. Фильтрация ввода, не доверяйте вводу клиента;
  2. Полностью избежать HTML;
  3. Установите только для HTTP: запретите JavaScript читать некоторые конфиденциальные файлы cookie, и злоумышленники не смогут украсть этот файл cookie после внедрения XSS.
  4. Captcha: не позволяет сценариям выдавать себя за пользователей и выполнять опасные действия.
  5. Используйте с осторожностью: .innerHTML, .outerHTML, document.write();

3. CSRF

Принципы CSRF

Подделка межсайтового запроса: злоумышленник побуждает жертву войти на сторонний веб-сайт, а на стороннем веб-сайте отправляет межсайтовый запрос на атакуемый веб-сайт. Используя регистрационные данные, которые жертва получила на атакованном веб-сайте, аутентификация пользователя в фоновом режиме обходится, и достигается цель выдачи себя за пользователя для выполнения операции на атакуемом веб-сайте.

Известный случился в 2009 году«Кража почты Google»событие, использование "CSRF".

Основной процесс:

  1. Жертва входит на сайт a.com и сохраняет учетные данные для входа (файлы cookie).
  2. Злоумышленник заманил жертву на сайт b.com.
  3. b.com отправляет запрос на a.com: a.com/act=xx. Ваш браузер по умолчанию будет содержать файлы cookie a.com.
  4. Получив запрос, a.com проверяет запрос и подтверждает, что это учетные данные жертвы, принимая его за запрос, отправленный самой жертвой.
  5. A.com выполняет ACT = XX во имя жертвы.
  6. Атака завершена, и злоумышленник притворяется жертвой, не зная жертвы, пусть A.com выполняет свое собственное определение.

Примечание. Злоумышленник не может напрямую украсть информацию о пользователе (файлы cookie, заголовок, содержимое веб-сайта и т. д.), а только мошенническим образом использовать информацию, содержащуюся в файлах cookie.

Это говорит нам о том, что мы не можем просто нажать на ссылку при серфинге, это рискованно.

CSRF-защита

Защитная стратегия:

  1. Стратегия автоматической защиты: обнаружение одного и того же источника (проверка источника и реферера).
  2. Меры активной защиты: проверка токена или двойная проверка файлов cookie и сопоставление файлов cookie Samesite.
  3. Чтобы обеспечить идемпотентность страницы, внутренний интерфейс не должен выполнять пользовательские операции на странице GET.

4. SQL-инъекция

Принцип внедрения SQL

Sql-инъекция — это атака путем вставки вредоносного Sql-запроса или добавления оператора во входные параметры приложения, а затем их анализа и выполнения на фоновом Sql-сервере.В настоящее время это один из наиболее распространенных методов атаки баз данных хакерами.

Защита от SQL-инъекций

Защита: предварительная компиляция и связывание переменных с операторами SQL — лучший способ защититься от SQL-инъекций. Его также можно защитить, строго проверяя тип данных параметра.

5. DNS угонает

Как работает перехват DNS

Перехват DNS, также известный как перехват доменного имени, относится к перехвату запросов на разрешение доменного имени в пределах захваченного сетевого диапазона, анализу запрошенного доменного имени и выпуску запросов, выходящих за рамки проверки, в противном случае он вернет поддельный IP-адрес или ничего не сделает для сделать запрос неотвечающим, в результате чего конкретная сеть недоступна или является поддельным URL-адресом. По сути, суть в том, чтобы манипулировать сервером разрешения DNS.

Защита от перехвата DNS

Решение:

Процесс захвата DNS достигается путем атаки на сервер разрешения оператора. Мы можем обойти разрешение DNS оператора, используя наш собственный сервер разрешения без разрешения DNS оператора, или заранее отправив разрешенное доменное имя в форме IP в нашем собственном приложении, что позволит избежать перехвата DNS. Проблема.

6. Перехват HTTP

Принцип перехвата HTTP

На маршрутизаторе оператора настройте обнаружение протокола.Как только будет обнаружено, что запрос является HTTP-запросом и является запросом типа html, он будет перехвачен и обработан злонамеренно.

Есть два распространенных типа:

  1. Подобно перехвату DNS, возврат 302 заставляет браузер пользователя перенаправляться на другой адрес. (Это то, что делают фишинговые сайты)
  2. Вставьте узлы js или dom (объявления) в данные HTML, возвращаемые сервером. (общий)

Защита от перехвата HTTP

Способ защиты:

  1. использовать HTTPS;
  2. Использовать заявление о запрете транскодирования;
  3. Добавьте фильтрацию кода на разрабатываемую веб-страницу: используйте js, чтобы проверить, принадлежат ли все внешние ссылки к белому списку;
  4. связаться с оператором;

Эта часть больше концептуальная вещь, я не хочу ее запоминать полностью, но в ней должна быть возможность рассказать о ней в общих чертах. Как гласит старая поговорка:Знание есть знание, незнание есть незнание, интервьюер не предъявляет строгих требований по некритическим вопросам. Не гони поезд с набитым ртом или просто не говори, что не знаешь. Это две крайности и ни одна из них не желательна.

резюме

Очевидно, что проблема «серии» фронтенд-интервью не только ограничена, но дыня будет продолжать организовывать идею этого «Синоекса», постоянно ломать систему, формировать систему (самим себя копать). С нетерпением жду поиска следов правды во время этого повторяющегося процесса!