Дэн Щербаков ⚛️
96 subscribers
20 photos
49 links
Канал для фронтенд-разработчиков о том, как развиваться и увеличивать зарплату.

Senior Frontend Developer с 6 годами опыта. За этот период увеличил зарплату почти в 7 раз.

Начинайте тут: https://yangx.top/code_lab/280
加入频道
SQL. Синтастические тонкости и table constraints

Спасибо неутомимому @darkgenius за деталь:

Колонка в БД называется поле. Применять слово "колонка" в приличном обществе - значит прослыть деревенщиной! :D

Table constraits - это дополнительные определения поля. То есть, полям можно задать определение или даже поведение, которые помогают избегать ошибок и систематизируют информацию.

Примеры table constrainnts:

PRIMARY KEY. Указывает, что значения в поле - уникальны и могут использоваться, например, как ID строки.

AUTOINCREMENT. Только для числовых значений. Задает автоматический инкремент (аналог ++ в JS) значения при создании новой строки.

UNIQE. Указывает, что каждое значение в поле должно быть уникальным: вставить строку с дублем не удастся. От PRIMARY KEY отличается тем, что такое поле нельзя использовать в качестве хранилища ключей.

NOT NULL. В поле не должно быть NULL.

CHECK (expression). Проверяет строку на соответствие выражению - математическому, соответствую массиву и т.д.

FOREIGN KEY REFERENCES field(name). Последовательно проверяет, чтобы PRIMARY KEY соответстволо указанное поле внешней таблицы. Значения в поле, указанном как FOREIGN KEY, не обязательно должны быть уникальными. Пример - соотношение таблиц авторов и книг по уникальному ID автора и повторяющимся ключам книг.

#SQL
SQL. ALTER TABLE

Оператор ALTER TABLE меняет существующие таблицы, а конкретно - добавлять или удалять новые поля, переименовывать таблицы и так далее.

Синтаксис похож на CREATE TABLE:

ALTER TABLE films
ADD new_column или...
DROP some_column или...
RENAME TO old_films

У разных БД - разные методы. Подробности в документации.

#SQL
SQL. Проектирование БД. Общие моменты.

- Cхема БД - это ее представление в виде взаимосвязи таблиц, в виде картинки или текста. По сути - проект. По схеме разработчик понимает структуру БД независимо от ее размера.

- Реляционные БД - значит, БД, построенные на отношениях (relation). Отношения - это просто таблицы.

- Домены. Это множества возможных значений атрибута. Например, домен атрибута пола состоит из множества {M, Ж}. Не следует путать домены с типами данных.

- Кортежи. То же, что и строки.

- Первичный ключ. Уникальный идентификатор кортежа. Может быть составным, потенциальным, несоставным. В третьей форме первичный ключ не может быть составным.

- Внешний ключ. Ключ к главной внешней таблице. Используется в дочерних таблицах.

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

- Теорема Хита:

R (A, B, C) = r1(A, B) join r2(A, C)

Что она означает:
Если в таблице с атрибутами A, B, C имеется зависимость A -> B, то декомпозиция этой таблицы обратима.

То есть, правильная нормализация проводится так, чтобы не потерять данные. Если после операции JOIN выполняется равенство по теореме, значит, декомпозиция проведена правильно.

#SQL
SQL. Пара слов о SQLite

Это легковесный движок реляционной БД. Он хранит БД в одном файле - что сводит миграцию базы до передачи этого файла. Его недостатки:
- Усеченная функциональность;
- Сложнее организовать разграничение доступа к таблицам;
- Только один пользователь может обновлять БД в определенный момент времени, а значит, высоконагруженные сервисы - в пролёте;
- Движок не чекает типы данных. Их можно указать в схеме - и все равно запихнуть неверные.

#SQL
SQL. Switch...case в SQL

В реляционных БД есть и эта знакомая всем логическая конструкция. Выражена она так:

SELECT column,
CASE
WHEN genre = 'romance'
OR genre = 'comedy'
THEN 'Chill'
ELSE 'Intense'
END AS 'Mood'
FROM movies;

Можно заметить, что CASE понимает операторы типа OR. Это полезно для построения логики.

#SQL
Java: тонкости языка и не только

- Цикл do ... while гарантированно выполнит одну итерацию.

- Массив чисел при инициализации по умолчанию заполняется нулями, булевых - false, остальных - null.

- Неявное преобразование типов идет по принципу: "от меньшего объема в памяти - к большему". Например, byte преобразуется в short, short - в int. Обратное преобразование ведет к усечению по тому же принципу.

Для примера - усечение int в byte. Усечем число 258.
В двоичном виде число складывается из двух разрядов. Тип byte состоит только из одного, поэтому результат усечется до 00000010, то есть, 2.

- Многомерные массивы объявляются так:
int arr[][] = new int[][].
Одна скобка - одна размерность.

- Синтаксис foreach по-джавистски:
for(int i : array).

- Передать несколько аргументов можно известным по JS оператором Spread.

#Java #тонкости
Как модифицировать системные переменные:

1. cmd
2. set проверка текущего значения
3. если нужна новая переменная:
setx var value
если нужно модифицировать, например, path:
setx var "%var%value;"

Через setx переменной присваивается строка. %...% возвращают текущее содержимое переменной. В Path необходимо разделять значения точкой с запятой, поэтому в конце аргумента добавлен этот знак.
Терминология ООП и Java

- Геттеры также называют аксессорами. Access - доступ.

- Сеттеры называют мутаторами. Mutation - изменение.

- Инициализатор - код, срабатывающий до корнструктора. В Java заключается в { }. Может быть статическим.

#ООП #Java
Подробно о статике

- Статическая сущность - принадлжедит самому классу, а не его экземплярам.

- Статическими бывают переменные, методы, инициализаторы и даже вложенные классы.

- Класс со статическими методами можно воспринимать библиотекой с готовыми функциями. Пример - класс Math. Методы класса используются без создания нового объекта.

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

- Статические инициализаторы выполняются только для самого первого объекта класса.

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

- Статические методы работают только с другими статическими сущностями.

#ООП #Java
Телеграм и демоны

Привет, кто решил остаться. Вы клёвые!

Щас расскажу важный момент о ботах Телеги.

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

Я нашел два пути это сделать:

1. Создать демона через systemctl. Наиболее правильный и надежный способ. Пишем конфиг, запускаем.

2. Повесить терминал на screen. Не так быстро, зато доки читать не надо:

sudo apt install screen
screen -S botfolder
node bot.js

И второй момент - где хостить. Я просто купил VPS на отечественном хостинге. Облака, heroku и так далее - экономия на спичках. На VPS накатил Убунту, туда - ноду, а дальше дело техники.

Кстати, консольный Vim - это просто! Жмякай i для редактирования, потом ESC + :wq для сохранения и выхода.

#бот #nodejs
Пара тонкостей работы с сетью

- Как определить, что висит на портах, и убить лишнее?

Набираем "netstat -aon" в консоли, где находим нужный порт и PID - идентификатор процесса. Затем открываем диспетчер задач - "Подробности". В колонке "идентификатор процесса" находим нужный ID. Теперь можно завершить процесс, если это требуется.

#сети
React. Раунд 2!

Готовлюсь ко внутреннему собеседованию по фронту. А значит, время нам с вами повторить пройденное!

- JSX-сущность = результат вызова функции createElement = объект с полями props, children етц.
Если держать в голове этот факт, не забудешь, что вообще такое хреновы пропсы.

- Children - это, если очень грубо, все, что между тегами элемента. <h1> -> тут children <- </h1). Это просто потомки, как в HTML.

- Еще внутри объекта есть key, ref, _owner и не только.

- Корневых узлов может быть несколько.

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

- Обновляется только то, что изменилось. Внутри реакта сравниваются версии элемента "до и после", после чего обновляется только то, что изменилось.

#React
- Композиция в React - просто дробление UI на блоки. Больше блок - больше отдельных компонентов. Профит - переиспользуемость.

- Нельзя менять state в обход сеттера setState.

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

- Можно обновлять поля state независимо в отдельных вызовах.

- Вообще state - это как props, только инкапсулированный. Работать со стейтом может исключительно компонент, которому он принадлежит.

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

- Синтетическое событие - это обертка Реакта над стандартными событиями DOM. Используется для кроссбраузерности. Его интерфейс аналогичен стандартным событиям, имеется доступ и к оригинальным.

- Как передать аргумент в обработчик события? Поместить его в функцию-стрелку.
#React
Привязка контекста в React

В компонентах-классах мы передаем обработчики событий в дочерние компоненты. Однако они не выполняются.

Что происходит?
Передавая метод класса в render, мы выполняем примерно следующее:
const newMethod = obj.method
Представим, что метод возвращает что-то вроде "this.something". Что такое this? Это ссылка на контекст объекта. Когда мы присваиваем метод внешней переменной, то и контекст меняем тоже.

Как этого избежать?
Жестко привязать контекст метода к объекту. Для этого используем .bind(), стрелочные функции или замыкания. Старый добрый способ - привязать this в конструкторе:
this.methodName = this.methodName.bind(this).

Подробнее: https://learn-reactjs.ru/faq/passing-functions-to-components

#React
Про Тайпскрипт

Типы указываются после имени переменной или перед {} для функций через двоеточие. Логика проста: именуем сущность и указываем, что возвращает.

Какие бывают типы:

- Примитивные: строки, целые числа, числа с запятой, булевы...
- Составные из нескольких примитивов: number | string
- Массивы, объекты и т.д.
- Кастомные (алиасы):
Login = string | undefined;
const login: Login = ...
- Для функций: любой примитив, либо Never (функция никогда не доходит до return), либо void (ничего не возвращает).
- Null и undefined
- функция при описании интерфейсов: ()

Интерфейсы

Это схематическое типирование обязательных и необязательных полей объекта. Пример:

interface Table {
readonly countertop: boolean
tableLegs: number
tablecloth?: string
}

Далее интерфейс присваивается объекту, и тот может быть определен только по его схеме.
Прочтем построчно поля объекта:
1. неизменяемое обязательное поле "столешница"
2. обязательное поле "ножки стола"
3. необязательное (знак вопроса перед двоеточием) поле "скатерть"

Присвоить интерфейс можно тремя способами:
- const obj: Interface = { ... } (объект описывается)
- const obj = {} as Interface; (объект объявлен пустым)
- const obj = <Interface>obj{} (объект также пуст)

Интерфейсы могут наследоваться:

interface Int2 extends Int1 {
...все поля Int1 под капотом...
getSum: () => number // обязательное поле-функция, возвращающее целое число
}

Также они могут описывать классы. Для этого используется ключевое слово implements:

class Car implements ICar {
...обязательные поля класса...
}

Хорошая практика - называть интерфейсы с буквы I, как у Эпл, только с большой.

Также можно описать сразу все типы полей объекта по ключу:
interface ICss = {
[key: string]: string...
}

#TypeScript
Коротко о Vue-Class-Component:

- Computed properties определяются как геттеры и сеттеры класса:
// Declared as computed property getter
get name() {
return this.firstName + ' ' + this.lastName
}

- Хуки и методы жизненного цикла можно определять как простые методы.

- Хуки из vue router и другие не из коробки нужно регистрировать, желательно в отдельном файле, через Component.registerHooks.

- Можно создавать кастомные декораторы:
@MyDecorator
method(arg)

- Возможно наследование через обычный ES6 синтаксис.

- Нельзя использовать функции-стрелки с this внутри и конструкторы. Вместо них используют обычные методы (вместо стрелок) и методы жизненного цикла. Почему нельзя? Конструктор вызывается под капотом компонента, собирая данные, если вызывать вручную - вызовется дважды:

// DO NOT do this. Use "created" lifecycle hook instead.
constructor() {
fetch('/posts.json')
.then(res => res.json())
.then(posts => {
this.posts = posts
})
}

#Vue #JS
Junior - Middle: внутреннее путешествие

Вопрос лычек, конечно, субъективен и разнится от компании к компании, но мысль этого поста - про самоощущение разработчика.

Меняется оно только с реальным опытом. Паззл складывается: ты "вдруг" начинаешь видеть целостную картину цикла производства. Ты понимаешь, зачем придумали ООП, паттерны проектирования, к чему кажущееся усложнение кода на крупных проектах. Не робеешь перед новыми проектами и технологиями - понимая, что их вводят для облегчения работы или поддержки. Эджайл теперь не пустой звук - ты можешь не любить его, но умеешь подстраиваться. На собеседованиях ты спокоен и уверен в своей ценности - что помогает проходить их.

В то же время, тебе есть куда расти. Организовывать команду ты еще не умеешь, да и не рвешься. Решения об архитектуре системы в целом принимают другие. Базовые и смежные знания все еще неполные - но теперь ты сам себе наставник и знаешь, чем заполнить пробелы.

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

Перед тем, как начать выполнять тестовое:
- Возникли вопросы, двусмысленные моменты? Обсуди с контактом в компании. Даже мелочи. Даже если придется писать через HR. Это важный момент софт-скиллз.

Перед отправкой кода проверь на:
- console.log и другие элементы дебага
- неиспользуемые переменные и стили
- неиспользуемые импорты
- любые другие хвосты и косяки

Написал README - проверь, чтобы описанные в нем методы или команды работали, как написано.

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

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

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

#softskills #собеседования
Что спросить на собеседовании?

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

#1. Какой срок даете на то, чтобы вникнуть в проект, прежде чем начнутся "боевые" задачи?
#2. Онбординг - своими силами или есть человек, к которому можно обращаться и которому это не в тягость?
#3. Если не подойдем друг другу в испытательный, как это отразится на трудовой?
#4. Оформляете в белую?

Пишите в комментах свои пункты.

#собеседования #softskills
Центр вселенной

В разработке нужно понимать один простой принцип:

Программирование - это работа над данными.

Данные - или стейт - центр вселенной. Всё остальное подчиняется данным: обрабатывает, доставляет потребителю... View отрисовывает данные, Model - описывает их, и так далее.

От этого нужно начинать разработку. В изучении фреймворков надо разделять в голове их части на те, что работают с данными, и многочисленные обработчики. Так понять фреймворк проще, чем воспринимая кашей из чужеродного API. И уж тем более проще понять state manager'ы, подходя так к этому вопросу.

Задача фронтендера, таким образом, максимально быстро доставить данные пользователю.

Из этого вытекает еще одна мысль: одна из главных задач в вебе - оптимизация. Именно поэтому мы должны изучать алгоритмы, понимать O-нотацию, использовать лучшие практики.
Место структур данных в программировании

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

Построим осмысленную логическую цепочку.

Данные - это отдельный, обособленный и главный элемент разработки.
Чтобы обрабатывать данные, существуют алгоритмы.
Эффективность алгоритмов зависит от формы данных. Например, связанный список эффективен, когда нужно получить данные с начала или конца списка (O1), а бинарное дерево эффективнее для поиска вглубь, так как отсекает по половине данных за каждую итерацию.
Таким образом, структуры данных служат для упорядочивания данных, чтобы эффективно выполнять бизнес-задачи. А алгоритмы, в свою очередь, изучаются как правильные инструменты обработки этих структур.