Просмотр больших логов на сервере
head filename.log
- просмотр начала файла (10 строк по умолчанию).
tail -15 filename.log
- просмотр конца файла, 15 строк.
tail -f filename.log
- просмотр 10 строк с конца файла + отслеживать добавление новых строк.
Как браузер рисует страницу
- Загружает HTML и строит DOM.
- Загружает CSS и строит CSS Object Model (CSSOM).
- На основе DOM и CSSOM строит дерево рендеринга. Дерево похоже на DOM но там нет невидимых элементов (
<head>
,display:none
), это дерево описывает визуальное представление DOM. - Для каждого элемента дерева расчитывается его положение на странице(flow), layouting.
- Происходит отрисовка всего этого в браузере.
В процессе взаимодействия со страницей она может меняться и потребуется повторное выполнение некоторых операций.
Repaint
В случае изменения стилей элемента не влияющих на его размеры и положение (border-color
, background-color
) - браузер повторяет реднеринг элемента с новыми стилями.
Reflow
Если изменения затрагивают структуру документа происходит пересчет положения элементов (reflow/relayout).
Изменения которые могут привести к reflow:
- манипуляция с DOM деревом
- изменение содержимого, в т.ч. в полях форм
- расчет/изменение свойств CSS
- добавление/удаление таблиц стилей
- изменение размеров окна браузера/прокрутка
Какие свойства CSS заставляет браузер выполнять перекомпозицию (outline box model)
Свойства: display
, position
, margin
, padding
, z-index
, left/right/top/bottom
, [min-/max-]height/width
Doctrine lazy, extra_lazy, eager
При загрузке сущности, если у нее есть связанная сущность/сущности то при:
fetch="eager"
- связанная сущность/сущности тоже будет загружена из БД.
fetch="lazy"
- будет создан прокси-объект, данные будут загружены только после обращения.
fetch="extra_lazy"
- усиление ленивой загрузки. C этим режимом загрузки будут доступы методы count
, contains
, get
, slice
Deep copy / Shallow copy
Shallow copy - копирует самый возможный минимум.
Если поле - примитив, будет скопировано значение, если поле адрес - будет скопирован адрес. Это дешевле и быстрее, но при редактировании значения по адресу в копии - значение будет изменено и у оригинального объекта:
$arr = array(1,2);
$arr1 = &$arr;
$arr1[0]++
echo $arr[0]; // 2
echo $arr1[0]; // 2
Deep copy - полное копирование объекта.
Это дольше, нужно больше памяти, но объекты не будут связаны друг с другом и можно не переживать за порчу данных при модификации копии.
$arr = array(1,2);
$arr1 = $arr;
$arr1[0]++
echo $arr[0]; // 1
echo $arr1[0]; // 2
Стандарты написания PHP кода
PHP Standards Recommendations (PSR)
1 - базовый стандарт оформления
3 - интерфейс протоколирования (Logger Interface)
4 - стандарт автозагрузки
6 - интерфейс кэширования
…
и их много
Типизация в PHP
По виду типизации, языки программирования делятся на языки с динамической и статической.
Статическая типизация - когда тип переменной точно известен во время компиляции.
Например, в Clang int a = 1;
и при выполнении тип переменной a
может быть только int
.
С динамической типизацией попроще - тип переменной определяется во время выполнения.
Например, в PHP $a = 1;
и при выполнении переменная $a
может быть числом 1
или даже строкой(если туда записать строку).
Тип переменной определяет операции, которые мы можем с ней производить.
Например, числа - складывать, а в строках искать вхождение подстроки.
Типизация, в свою очередь, делится на сильную (strong) и слабую (weak).
Когда мы выполняем какую-либо операцию при сильной типизации, то два операнда должны иметь один и тот же тип.
Например, в Python 1 + 'string' (пример слабый конечно, ведь умножение строки на число в питоне допустимо) вызовет ошибку, потому что 1 - число, а «string» - строка.
А вот в языках со слабой типизацией ошибки не будет.
Например, в PHP 1 + "string" вернёт цифру 1.
И причиной всему является приведение типов.
serialize
и unserialize
в PHP
Функция serialize
генерирует пригодное для хранение представление переменной. Используется для передачи значений между скриптами без потери структуры и типов данных. На выходе возвращает строчку.
При сериализации объектов php пытается вызывать магические методы __serialize
и __sleep
перед сериализацией, чтобы позволить объекту произвести очистку некоторых ресурсов перед тем как выполнять сериализацию.
Функция unserialize
выполняет обратную операцию и декодирует строку в объекты, так же проверяя и вызывая магические методы __unserialize
и __wakeup
, чтобы объект мог настроить необходимые для работы ресурсы, например соединение с БД.
Потоки в JS в браузере
В каждом окне выполняется только один главный поток, который занимается выполнением JavaScript, отрисовкой и работой с DOM.
Он выполняет команды последовательно, может делать только одно дело одновременно и блокируется при выводе модальных окон, таких как alert
.
Есть и другие, служебные потоки, например, для сетевых коммуникаций.
Существует спецификация Web Workers, которая позволяет запускать дополнительные JavaScript-процессы(workers).
Они могут обмениваться сообщениями с главным процессом, но у них свои переменные, и работают они также сами по себе.
Такие дополнительные процессы не имеют доступа к DOM, поэтому они полезны, преимущественно, при вычислениях, чтобы загрузить несколько ядер/процессоров одновременно.
Event loop
Параллелизм/Многопоточность в JavaScript работает за счёт цикла событий (event loop), который отвечает за выполнение кода, сбора и обработки событий и выполнения под-задач из очереди (queued sub-tasks).
Вызов любой функции создает контекст выполнения (Execution Context). При вызове вложенной функции создается новый контекст, а старый сохраняется в специальной структуре данных - стеке вызовов (Call Stack).
Объекты размещаются в куче. Куча - это просто имя для обозначения большой неструктурированной области памяти.
Среда выполнения JavaScript содержит очередь задач. Эта очередь - список задач, подлежащих обработке. Каждая задача ассоциируется с некоторой функцией, которая будет вызвана, чтобы обработать эту задачу.
Когда стек полностью освобождается, самая первая задача извлекается из очереди и обрабатывается. Обработка задачи состоит в вызове связанной с ней функции с параметрами. Вызов функции создаёт новый контекст выполнения и заносится в стек вызовов.
Обработка задачи заканчивается, когда стек снова становится пустым. Следующая задача извлекается из очереди и начинается её обработка.
Каждая задача выполняется полностью, прежде чем начнет обрабатываться следующая. Благодаря этому мы точно знаем: когда выполняется текущая функция - она не может быть приостановлена и будет целиком завершена до начала выполнения другого кода (который может изменить данные, с которыми работает текущая функция).
Есть и минусы - если задача занимает слишком много времени, то веб-приложение не может обрабатывать действия пользователя в это время (например, скролл или клик). Браузер старается смягчить проблему и выводит сообщение "скрипт выполняется слишком долго" и предлагает остановить его.
Хорошей практикой является создание задач, которые исполняются быстро, и если возможно, разбиение одной задачи на несколько мелких.
Особенностью цикла событий в JavaScript является то, что поток выполнения никогда не блокируется. Обработка I/O обычно осуществляется с помощью событий и функций обратного вызова, поэтому даже когда приложение ожидает запрос от IndexedDB или ответ от XHR, оно может обрабатывать другие процессы, например пользовательский ввод.
Однобайтовые и Многобайтовые кодировки
Прародителем всех современных кодировок можно считать ASCII (American Standard Code for Information Interchange /американская стандартная кодировочная таблица для печатных символов и некоторых специальных кодов).
Это однобайтовая кодировка, в которую изначально заложено всего 128 символов.
Позже она была расширена до 256 символов, чтобы использовать в кодировании байт целиком.
Это позволило добавлять символы национальных языков, помимо существующей латиницы(например KOI8-R/Windows-1251).
В 1991 году Консорциум Юникода предложил UTF-32 - многобайтовую кодировку, в которой каждый символ кодировался 32 битами(4 байта).
Проблема кодировки в том, что для кодирования того же количества информации стало требоваться в 4 раза больше памяти!
На смену ей пришла UTF-16 (16 бит / 2 байта). Символов меньше, но все еще в 2 раза больше памяти, в сравнении с однобайтовыми кодировками.
Подумали и придумали UTF-8 - многобайтовая кодировка с переменной длиной символа. Из названия можно подумать, что тут используется 8 бит для кодирования.
Нет.
Все латинские символы кодируются 1 байтом, иначе говоря базовая часть ASCII перешла в UTF-8. А все остальные символы кодируются двумя байтами. Таким образом для хранения файлов, которым было достаточно ASCII, не требуется больше памяти, и при этом мы можем использовать расширенный набор символов.
Работа с UTF-8 в PHP
Так как UTF-8 является многобайтовой кодировкой, то использование функций для работы со строками может вызвать сложности.
Для работы с многобайтовыми кодировками необходимо использовать функции с префиксом mb_
echo substr("hi mémé", 0, 5); // will print hi m�
echo mb_substr("hi mémé", 0, 5); // will print hi mé
До PHP7.2 можно было использовать механизм перегрузки функций - задать настройке mbstring.func_overload
в php.ini
положительное значение, которое представляет собой комбинацию битовых масок, определяющих категории функций, которые нужно перегружать.
Значения:
1 для перегрузки функции mail()
2 для строковых функций
4 для функций регулярных выражений
7 для всего что выше вместе
Отличие POST от GET
GET/POST/PUT/DELETE - HTTP методы которые представляют операцию которую необходимо провести с ресурсом.
В GET данные формы передаются как часть URL, в POST в теле запроса.
Общепринято использовать POST для создания ресурсов, GET для получения, PUT/PATCH - для обновления, DELETE - для удаления.
Но никто не запрещает делать все GET или DELETE запросами.