На моем youtube вышло новое видео про асимптотическую сложность алгоритмов
🔥40❤🔥5👍5😍4👀1
  Не могу не поделиться этой новостью, ибо я ждал этого несколько лет!
На прошлой неделе вышел релиз Rust 1.74.0, в котором добавили секции lints и workspace.lints в Cargo.toml
Наконец можно конфигурировать линты глобально на весь проект.
Как это было раньше?
Каноничным способом было прописывать атрибуты forbid/deny/warn/allow в корневом модуле каждого 😡 крейта или управлять этим через переменную окружения RUSTFLAGS, что было крайне не удобно.
Альтернативным способом была установка cargo cranky, который хоть и решал проблему, но плохо интегрировался с другим инструментарием Rust.
Релизы Rust выходят каждые 6 недель, но действительно значимые улучшения происходят далеко не в каждом из них.
На прошлой неделе вышел релиз Rust 1.74.0, в котором добавили секции lints и workspace.lints в Cargo.toml
Наконец можно конфигурировать линты глобально на весь проект.
Как это было раньше?
Каноничным способом было прописывать атрибуты forbid/deny/warn/allow в корневом модуле каждого 😡 крейта или управлять этим через переменную окружения RUSTFLAGS, что было крайне не удобно.
Альтернативным способом была установка cargo cranky, который хоть и решал проблему, но плохо интегрировался с другим инструментарием Rust.
Релизы Rust выходят каждые 6 недель, но действительно значимые улучшения происходят далеко не в каждом из них.
👍30🤔7❤🔥4
  Иногда система типов может предложить интересные решения дающие больше контроля над типизированными сущностями. В этом посте я хочу рассмотреть 2 таких решения, которые сосредоточены на управлении ресурсами посредством системы типов, а именно линейных и аффинных типах.
Линейные типы описывают объекты, которые должны быть использованы строго 1 раз. Это означает, что получив сущность линейного типа мы обязаны ей воспользоваться, а воспользовавшись однажды сделать это второй раз не выйдет. Если же нарушить эти правила, то программа не пройдет проверку типов.
Попробовать линейные типы можно в языках Haskell (пока что включив расширение компилятора) и Idris 2.
Аффинные типы описывают объекты, которые могут быть использованы не более одного раза. Отличие от линейных типов здесь в том, что у нас нет обязательства использовать сущность аффинного типа.
На аффинных типах построена концепция владения в языке Rust. Все типы в Rust являются аффинными по умолчанию, при передаче по значению используется move семантика, а корректность ее использования (невозможность использовать перемещенное значение) возлагается на проверку типов.
Однако в Rust есть 2 послабления касательно аффинных типов:
- тип может быть промаркирован трейтом Copy, что отключает для него move семантику (при передаче по значению происходит копирование) и делает такой тип обычным;
- дополнительно вводится концепция заимствования через ссылки, что позволяет обращаться к сущности многократно, правда с рядом ограничений.
В целом линейные и аффинные типы позволяют языку вводить дополнительные гарантии управления ресурсами на уровне системы типов. Линейные типы так же дают дополнительную гарантию освобождения ресурсов, тогда как в случае аффинных типов такой гарантии нет, хотя она и может быть переложена на другие механизмы языка (Rust например дает такую гарантию за счет идиомы RAII).
Линейные типы описывают объекты, которые должны быть использованы строго 1 раз. Это означает, что получив сущность линейного типа мы обязаны ей воспользоваться, а воспользовавшись однажды сделать это второй раз не выйдет. Если же нарушить эти правила, то программа не пройдет проверку типов.
Попробовать линейные типы можно в языках Haskell (пока что включив расширение компилятора) и Idris 2.
Аффинные типы описывают объекты, которые могут быть использованы не более одного раза. Отличие от линейных типов здесь в том, что у нас нет обязательства использовать сущность аффинного типа.
На аффинных типах построена концепция владения в языке Rust. Все типы в Rust являются аффинными по умолчанию, при передаче по значению используется move семантика, а корректность ее использования (невозможность использовать перемещенное значение) возлагается на проверку типов.
Однако в Rust есть 2 послабления касательно аффинных типов:
- тип может быть промаркирован трейтом Copy, что отключает для него move семантику (при передаче по значению происходит копирование) и делает такой тип обычным;
- дополнительно вводится концепция заимствования через ссылки, что позволяет обращаться к сущности многократно, правда с рядом ограничений.
В целом линейные и аффинные типы позволяют языку вводить дополнительные гарантии управления ресурсами на уровне системы типов. Линейные типы так же дают дополнительную гарантию освобождения ресурсов, тогда как в случае аффинных типов такой гарантии нет, хотя она и может быть переложена на другие механизмы языка (Rust например дает такую гарантию за счет идиомы RAII).
👍25❤5
  Хочу собрать немного статистики.
Сколько языков программирования вы знаете (на уровне не меньше чем "могу что-то написать для себя")?
  Сколько языков программирования вы знаете (на уровне не меньше чем "могу что-то написать для себя")?
Anonymous Poll
    25%
    1
      
    27%
    2
      
    16%
    3
      
    7%
    4
      
    3%
    5
      
    1%
    6
      
    2%
    7 или больше
      
    12%
    ни одного
      
    8%
    посмотреть результаты
      
    👍2
  Полиморфизм - какая первая ассоциация всплывает у вас, когда вы слышите это понятие? Вопрос может показаться странным, если не знать на сколько полиморфизм многогранен. Полиморфизм - он не един, его есть несколько видов, многие языки могут включать в себя сразу несколько таких видов. Хотя все эти виды все же имеют одну общую черту - связь с системой типов, а если точнее любой полиморфизм дает возможность иметь сущности, работающие не с конкретными типами, а с некоторым множеством типов.
Прежде чем рассмотреть основные виды полиморфизма, стоит упомянуть одну важную характеристику любого вида полиморфизма - полиморфизм бывает статическим и динамическим. При статическом полиморфизме полиморфные сущности разрешаются в конкретные (обладающие конкретными типами) в compiletime. При динамическом - сущности остаются полиморфными после компиляции, а разрешаются уже в runtime за счет метаинформации о типах (например с помощью таблиц виртуальных функций или средствами рефлексии).
Полиморфизм подтипов
Данный вид возникает, когда система типов поддерживает возможность выстраивать типы в иерархии. При этом типы стоящие ниже по иерархии по отношению к типам стоящим выше называют подтипами. Основная идея тут в том, что сущность представленная подтипом так же представлена любым его надтипом (типом стоящим по иерархии выше).
Этот вид полиморфизма часто ассоциируют с ООП (с самым распространенным на сегодня его видом, смотри видео про парадигмы если непонятно о чем речь). Иерархия здесь образуется при наследовании классов (наследник является подтипом базового класса) и при имплементации интерфейсов (имплементатор является подтипом интерфейса).
Однако иерархия может появляться и в других случаях, яркий пример тут система типов в TypeScript, в которой все типы (за исключением разве типа
Параметрический полиморфизм
Данный вид дает возможность сущностям языка принимать типы в качестве параметров. Полиморфные сущности в данном виде имеют возможность работать с типами обобщенно. Самый распространенный представитель параметрического полиморфизма - это дженерики.
Вершиной параметрического полиморфизма являются типы высших порядков (HKT - Higher-Kinded Types), при поддержке которых возможно частичное применение параметров типа, а так же возможность передачи частичных типов в качестве параметров. Всю мощь HKT позволяет оценить язык Haskell.
Ad-hoc полиморфизм
Данный вид позволяет сущностям иметь несколько реализаций, при этом конкретная реализация определяется на основе типов в составе сущности. Самым ярким представителем тут являются перегрузки функций, когда мы имеем несколько реализаций для функции, а конкретная реализация выбирается на основе типов аргументов. Важное уточнение, перегрузки в TypeScript относятся к параметрическому полиморфизму, так как у всех перегрузок будет единая реализация. Сюда же можно отнести специализацию шаблонов в C++. Шаблоны в C++ одновременно являются представителем как параметрического так и ad-hoc полиморфизма.
Утиная типизация
Так же является видом полиморфизма, в котором полиморфные сущности определяются по наличию у их типа некоторого набора свойств (например наличия набора методов с определенными сигнатурами). Яркий представитель - интерфейсы в языке Go.
Так же условно к этому виду можно отнести все системы типов основанные на структурной типизации, условно так как чаще всего структурная типизация использует полиморфизм подтипов.
В завершении хочу упомянуть динамическую типизацию, в которой все сущности являются полиморфными по самой природе таких систем типов.
Прежде чем рассмотреть основные виды полиморфизма, стоит упомянуть одну важную характеристику любого вида полиморфизма - полиморфизм бывает статическим и динамическим. При статическом полиморфизме полиморфные сущности разрешаются в конкретные (обладающие конкретными типами) в compiletime. При динамическом - сущности остаются полиморфными после компиляции, а разрешаются уже в runtime за счет метаинформации о типах (например с помощью таблиц виртуальных функций или средствами рефлексии).
Полиморфизм подтипов
Данный вид возникает, когда система типов поддерживает возможность выстраивать типы в иерархии. При этом типы стоящие ниже по иерархии по отношению к типам стоящим выше называют подтипами. Основная идея тут в том, что сущность представленная подтипом так же представлена любым его надтипом (типом стоящим по иерархии выше).
Этот вид полиморфизма часто ассоциируют с ООП (с самым распространенным на сегодня его видом, смотри видео про парадигмы если непонятно о чем речь). Иерархия здесь образуется при наследовании классов (наследник является подтипом базового класса) и при имплементации интерфейсов (имплементатор является подтипом интерфейса).
Однако иерархия может появляться и в других случаях, яркий пример тут система типов в TypeScript, в которой все типы (за исключением разве типа
any) выстроены в одну огромную иерархию.Параметрический полиморфизм
Данный вид дает возможность сущностям языка принимать типы в качестве параметров. Полиморфные сущности в данном виде имеют возможность работать с типами обобщенно. Самый распространенный представитель параметрического полиморфизма - это дженерики.
Вершиной параметрического полиморфизма являются типы высших порядков (HKT - Higher-Kinded Types), при поддержке которых возможно частичное применение параметров типа, а так же возможность передачи частичных типов в качестве параметров. Всю мощь HKT позволяет оценить язык Haskell.
Ad-hoc полиморфизм
Данный вид позволяет сущностям иметь несколько реализаций, при этом конкретная реализация определяется на основе типов в составе сущности. Самым ярким представителем тут являются перегрузки функций, когда мы имеем несколько реализаций для функции, а конкретная реализация выбирается на основе типов аргументов. Важное уточнение, перегрузки в TypeScript относятся к параметрическому полиморфизму, так как у всех перегрузок будет единая реализация. Сюда же можно отнести специализацию шаблонов в C++. Шаблоны в C++ одновременно являются представителем как параметрического так и ad-hoc полиморфизма.
Утиная типизация
Так же является видом полиморфизма, в котором полиморфные сущности определяются по наличию у их типа некоторого набора свойств (например наличия набора методов с определенными сигнатурами). Яркий представитель - интерфейсы в языке Go.
Так же условно к этому виду можно отнести все системы типов основанные на структурной типизации, условно так как чаще всего структурная типизация использует полиморфизм подтипов.
В завершении хочу упомянуть динамическую типизацию, в которой все сущности являются полиморфными по самой природе таких систем типов.
👍54❤4👎1🔥1
  При использовании статической типизации типы всех переменных должны быть известны на этапе компиляции. Однако явное указание типов для всех переменных может утомлять и отвлекать от решаемой задачи. Решением этой проблемы стал вывод типов - способность компилятора вычислить тип для переменной из контекста, в котором эта переменная используется, а значит допустимостью для программиста не указывать такие типы явно.
В этом посте поговорим про вывод типов.
Простейшим способом вывода типов является задание переменной того же типа, что и тип выражения, которым данная переменная инициализирована. На этом принципе работает
Литералы 5 и 2 имеют тип int,
Такой подход позволяет так же выводить типы для дженериков/шаблонов из выражений переданных в аргументы функции.
Хотя такой способ достаточно просто реализуется в компиляторе, но у него есть недостатки. Нельзя вывести тип для переменных, которые инициализируются не в момент их объявления. А в сложных системах типов такой вывод может преподносить сюрпризы:
Более продвинутым способом вывода типов является алгоритм Хиндли-Милнера.
В данном способе вывод типов анализирует функцию целиком, строя на её основе систему уравнений, неизвестными в которой являются типы. Затем алгоритм за несколько шагов пытается разрешить эту систему, постепенно замещая неизвестные конкретными типами, вычисленные способом похожим на предыдущий. Вычисления останавливаются, когда больше ничего невозможно вычислить, в результате чего получаются или полностью конкретные типы или могут остаться обобщенные типы.
В случае чистых функций, которые по сути являются выражением из аргументов функции в ее возвращаемое значение оставшиеся обобщенные типы не представляют большой проблемы, мы просто получим обобщенную функцию (дженерик). Данный алгоритм применяется в языках семейства ML (Haskell, OCaml), где он может выводить даже сигнатуру для функции, пусть и зачастую в обобщенном виде.
Однако и данный алгоритм не всесилен, бывает что для некоторых переменных удается вывести лишь обобщенный тип, и если тип данной переменной не получится однозначно связать с типами в сигнатуре, то и не получится вывести обобщенную сигнатуру функции. Обычно компиляторы в этом случае требуют указать тип явно:
Метод parse у строк в Rust является дженериком по возвращаемому значению (сигнатура
Так же для такого вывода типов может стать большой проблемой неявная типизация. Если типы могут неявно кастоваться в другие, то может возникнуть неоднозначность в местах где одна и та же переменная используется в выражениях, требующих разные типы, непонятно какой из типов считать предпочтительным. Поэтому языки использующие вывод типов по Хиндли-Милнеру как правило стремятся к явной типизации.
Еще одной проблемой для данного вывода типов может стать мощная система обобщений (дженериков) внутри системы типов. Rust например обходит это ограничение требованием явного указания типов в сигнатуре функций (и явного объявления дженериков).
Вывод типов - достаточно мощный инструмент современных языков, сильно упрощающий написание кода. Он так же может давать некоторые дополнительные возможности, вроде анонимных типов, которые без вывода типов были бы просто невозможны.
В этом посте поговорим про вывод типов.
Простейшим способом вывода типов является задание переменной того же типа, что и тип выражения, которым данная переменная инициализирована. На этом принципе работает
auto в C++ и var в Java/C#. На нём же работает вывод типов в TypeScript и некоторых других языках.auto v = 5 * 2; // выведется int
Литералы 5 и 2 имеют тип int,
operator*(int, int) возвращает int - результирующий тип всего выражения, а значит и тип переменной v, которая инициализирована этим выражением.Такой подход позволяет так же выводить типы для дженериков/шаблонов из выражений переданных в аргументы функции.
function foo<T>(arg: T): void;
foo(10); // T выведется в number
foo('hello'); // T выведется в string
Хотя такой способ достаточно просто реализуется в компиляторе, но у него есть недостатки. Нельзя вывести тип для переменных, которые инициализируются не в момент их объявления. А в сложных системах типов такой вывод может преподносить сюрпризы:
let array = []; // выведется never[]
array.push(10); // ошибка типов
Более продвинутым способом вывода типов является алгоритм Хиндли-Милнера.
В данном способе вывод типов анализирует функцию целиком, строя на её основе систему уравнений, неизвестными в которой являются типы. Затем алгоритм за несколько шагов пытается разрешить эту систему, постепенно замещая неизвестные конкретными типами, вычисленные способом похожим на предыдущий. Вычисления останавливаются, когда больше ничего невозможно вычислить, в результате чего получаются или полностью конкретные типы или могут остаться обобщенные типы.
В случае чистых функций, которые по сути являются выражением из аргументов функции в ее возвращаемое значение оставшиеся обобщенные типы не представляют большой проблемы, мы просто получим обобщенную функцию (дженерик). Данный алгоритм применяется в языках семейства ML (Haskell, OCaml), где он может выводить даже сигнатуру для функции, пусть и зачастую в обобщенном виде.
Однако и данный алгоритм не всесилен, бывает что для некоторых переменных удается вывести лишь обобщенный тип, и если тип данной переменной не получится однозначно связать с типами в сигнатуре, то и не получится вывести обобщенную сигнатуру функции. Обычно компиляторы в этом случае требуют указать тип явно:
let v = "10".parse(); // ошибка компиляции
println!("{:?}", v);
Метод parse у строк в Rust является дженериком по возвращаемому значению (сигнатура
fn parse<T>(&self): T), из контекста не понятен тип переменной v и нужно либо указать его явно либо явно задать дженерик у parse.let v: i32 = "10".parse(); // ok
let v = "10".parse::<i32>(); // ok
Так же для такого вывода типов может стать большой проблемой неявная типизация. Если типы могут неявно кастоваться в другие, то может возникнуть неоднозначность в местах где одна и та же переменная используется в выражениях, требующих разные типы, непонятно какой из типов считать предпочтительным. Поэтому языки использующие вывод типов по Хиндли-Милнеру как правило стремятся к явной типизации.
Еще одной проблемой для данного вывода типов может стать мощная система обобщений (дженериков) внутри системы типов. Rust например обходит это ограничение требованием явного указания типов в сигнатуре функций (и явного объявления дженериков).
Вывод типов - достаточно мощный инструмент современных языков, сильно упрощающий написание кода. Он так же может давать некоторые дополнительные возможности, вроде анонимных типов, которые без вывода типов были бы просто невозможны.
❤31👍11
  Сегодня анонсировали Rust 1.75
Обновиться можно будет на следующей неделе.
Главной фишкой новой версии станет поддержка синтаксиса
Ну а так как
Анонс конечно описывает некоторые нюансы, но развитие языка - это всегда хорошо.
В следующем году ожидается новая редакция языка (они выходят раз в 3 года), вероятно разработчики языка Rust ещё не раз порадуют нас стабилизацией полезных фич в ближайшие месяцы.
Последние пару недель у меня не хватало времени на контент, надеюсь вы простите мне такое затишье. Но всё же и я сделаю пару анонсов:
- В процессе большая статья про систему типов в TypeScript, надеюсь дописать и опубликовать на этих выходных.
- В процессе сценарий для видео, где расскажу зачем разработчику изучать несколько языков, планирую снять и выпустить его до конца года.
- 4, 5 и 6 января хочу на пробу провести стримы на ютубе, ориентируйтесь на старт в 19:00 мск, будем общаться + буду кодить небольшие штуки с нуля в прямом эфире, а если на первых двух стримах будет хотя бы по 50 зрителей, то на третьем возьму новый для себя ЯП и покажу как можно быстро разобраться в новом языке.
Обновиться можно будет на следующей неделе.
Главной фишкой новой версии станет поддержка синтаксиса
impl Trait в качестве возвращаемого типа функций объявленных в трейтах:trait MyTrait {
    fn some_function() -> impl SomeTrait;
}
impl MyTrait for MyType {
    fn some_function() -> impl SomeTrait {
        todo!();
    }
}Ну а так как
async fn - это по факту сахар над функциями, возвращающими impl Future, async fn так же будут доступны нативно для трейтов:async fn f() -> i32 { 10 }
// рассахаривается в:
fn f() -> impl Future<Output = i32> { async { 10 } }
// что позволяет теперь делать так:
trait MyTrait {
    async fn f();
}Анонс конечно описывает некоторые нюансы, но развитие языка - это всегда хорошо.
В следующем году ожидается новая редакция языка (они выходят раз в 3 года), вероятно разработчики языка Rust ещё не раз порадуют нас стабилизацией полезных фич в ближайшие месяцы.
Последние пару недель у меня не хватало времени на контент, надеюсь вы простите мне такое затишье. Но всё же и я сделаю пару анонсов:
- В процессе большая статья про систему типов в TypeScript, надеюсь дописать и опубликовать на этих выходных.
- В процессе сценарий для видео, где расскажу зачем разработчику изучать несколько языков, планирую снять и выпустить его до конца года.
- 4, 5 и 6 января хочу на пробу провести стримы на ютубе, ориентируйтесь на старт в 19:00 мск, будем общаться + буду кодить небольшие штуки с нуля в прямом эфире, а если на первых двух стримах будет хотя бы по 50 зрителей, то на третьем возьму новый для себя ЯП и покажу как можно быстро разобраться в новом языке.
👍57🔥11🆒1
  Обещанная статья про систему типов в TypeScript.
В ней подробный разбор как данная система типов работает.
  
  В ней подробный разбор как данная система типов работает.
Telegraph
  
  Система типов в TypeScript
  Язык программирования TypeScript обладает поистине уникальной системой типов и это делает её очень интересной для разбора. Во-первых, это один из немногих представителей структурной типизации. Во-вторых, в основе проверки типов здесь лежит теория множеств…
🔥39
  Где-то Новый Год уже наступил, а где-то только на подходе.
В новом году я желаю своим подписчикам счастья, благополучия, мира во всем мире, высоких зарплат и карьерных достижений, прибыльных инвестиционных портфелей!
Продолжайте развиваться и будьте себе на уме.
🥂🍾☃️❄️🎉
В новом году я желаю своим подписчикам счастья, благополучия, мира во всем мире, высоких зарплат и карьерных достижений, прибыльных инвестиционных портфелей!
Продолжайте развиваться и будьте себе на уме.
🥂🍾☃️❄️🎉
🎉82🔥14❤12👍2
  Сегодня в 19:00 мск будет ещё один стрим (запись останется, ссылку выложу примерно за пол часа).
В первой части поговорим про то как изучать языки программирования и зачем это нужно.
Во второй части попробую освоить новый для себя язык zig и написать на нём небольшую программку.
В первой части поговорим про то как изучать языки программирования и зачем это нужно.
Во второй части попробую освоить новый для себя язык zig и написать на нём небольшую программку.
👍16🔥7
  В стриме, где я разбирался с языком zig, я упомянул такой термин, как алгебраический тип данных (algebraic data type, ADT). Давайте разберемся, что это такое и зачем нужно.
ADT появились в функциональных языках, таких как Haskell или OCaml, но встречаются и в языках ориентированных на другие парадигмы, например в Rust, Zig и TypeScript.
ADT представляют собой тип-сумму, объединяющий в себе данные разных типов по принципу ИЛИ, что позволяет хранить в одной переменной данные разных типов, но при этом типобезопасно их получать. Основным способом извлечения данных из ADT является pattern matching (сопоставление с образцом), который позволяет проверить, какой вариант данных сейчас находится в переменной с ADT типом.
Давайте посмотрим примеры на различных языках. Пусть у нас есть типы
На Haskell объявление будет выглядеть так:
А на Rust так:
А вот так на TypeScript:
Имея переменную такого типа
ADT - это достаточно мощный инструмент в тех системах типов и языках, где он есть, позволяющий оперировать данными разных типов в рамках одной сущности, при этом сохраняя безопасность с точки зрения типов.
ADT появились в функциональных языках, таких как Haskell или OCaml, но встречаются и в языках ориентированных на другие парадигмы, например в Rust, Zig и TypeScript.
ADT представляют собой тип-сумму, объединяющий в себе данные разных типов по принципу ИЛИ, что позволяет хранить в одной переменной данные разных типов, но при этом типобезопасно их получать. Основным способом извлечения данных из ADT является pattern matching (сопоставление с образцом), который позволяет проверить, какой вариант данных сейчас находится в переменной с ADT типом.
Давайте посмотрим примеры на различных языках. Пусть у нас есть типы
Cat и Dog, а мы хотим объединить их в ADT типе Pet.На Haskell объявление будет выглядеть так:
data Pet = PetCat Cat | PetDog Dog
А на Rust так:
enum Pet {
    Cat(Cat),
    Dog(Dog),
}А вот так на TypeScript:
type Pet = {
  kind: 'Cat';
  cat: Cat;
} | {
  kind: 'Dog';
  dog: Dog;
};Имея переменную такого типа
Pet мы можем однозначно определять, что внутри - Cat или Dog и выполнять в зависимости от этого разную логику:f :: Pet -> IO ()
f (PetCat _) = print "Cat"
f (PetDog _) = print "Dog"
match pet {
    Pet::Cat(cat) => println!("Cat: {:?}", cat),
    Pet::Dog(dog) => println!("Dog: {:?}", dog),
}switch (pet.kind) {
  case 'Cat':
    console.log('Cat', pet.cat);
    break;
  case 'Dog':
    console.log('Dog', pet.dog);
    break;
}ADT - это достаточно мощный инструмент в тех системах типов и языках, где он есть, позволяющий оперировать данными разных типов в рамках одной сущности, при этом сохраняя безопасность с точки зрения типов.
👍33🔥10🤔3❤2
  Настало время для серии постов про сети, сетевые протоколы и сетевое программирование.
А начнём мы с рассмотрения сетевой модели OSI.
Работа сетей обеспечивается большим количеством различных протоколов, многие из которых работают поверх других протоколов.
Модель OSI классифицирует сетевые протоколы по 7 уровням:
7. Application (прикладной, уровень приложений).
Оперирует формализованными данными, формат которых задается каждым конкретным протоколом. Обеспечивает общение приложений между собой.
Примеры: HTTP, FTP, WebSocket, SMTP, DNS
6. Presentation (представление).
Оперирует абстрактными данными (наборами байт). Обеспечивает функции преобразования данных (шифрование, сжатие).
Примеры: TLS, SSL
5. Session (сессии, сеансы связи).
Оперирует абстрактными данными + мета данными обеспечивающими постоянные соединения и аутентификацию соединения.
Примеры: TLS (частично), TCP (частично), PAP, L2TP, OpenVPN, WireGuard
4. Transport (транспортный).
Оперирует сегментами или датаграммами. Обеспечивает передачу данных на логическом уровне.
Примеры: TCP, UDP
3. Network (сетевой).
Оперирует пакетами. Обеспечивает логическую адресацию (ip адрес, порт) и маршрутизацию.
Примеры: IPv4, IPv6, ICMP
2. Link (канальный).
Оперирует кадрами. Обеспечивает физическую адресацию (mac адрес).
Примеры: Ethernet, IEEE 802.11 (WiFI), LTE (мобильные сети), PPP, DSL
1. Physical (физический).
Оперирует отдельными битами. Обеспечивает передачу данных по физическим каналам связи.
Примеры: RJ (витая пара), SFP (оптоволокно), USB
Согласно данной модели любые данные проходят все уровни от 7 до 1 при отправке данных и от 1 до 7 при получении. Каждый протокол должен взаимодействовать только с протоколами своего и соседних уровней, что на практике не всегда соблюдается.
Так же при передаче данных через множество сетей (что просто необходимо в том же internet) данные могут многократно переходить между уровнями 1, 2 и 3 (маршрутизация), а иногда и между более высокими уровнями (например при балансировке).
Кроме того, технологии виртуальных сетей (например VLAN или VPN) могут делать программную эмуляцию более низких уровней фактически передавая данные на более высоких.
А границы между уровнями 4, 5, 6 и 7 очень часто оказываются размытыми, например протокол HTTP, находящийся на 7 уровне, может работать прямо поверх протокола TCP, находящегося на 4 уровне.
С уровнями 4, 5, 6 и 7 чаще всего взаимодействует прикладное программное обеспечение. В системной разработке можно столкнуться с уровнями 3 и 4. Но и на уровне 2 так же применяются программные решения при разработке прошивок для сетевых устройств. И лишь уровень 1 является полностью аппаратным.
Модель OSI не идеальна, но она позволяет соотнести практически каждый сетевой протокол с определенным уровнем модели, что даёт первичное представление о протоколе и его назначении.
А начнём мы с рассмотрения сетевой модели OSI.
Работа сетей обеспечивается большим количеством различных протоколов, многие из которых работают поверх других протоколов.
Модель OSI классифицирует сетевые протоколы по 7 уровням:
7. Application (прикладной, уровень приложений).
Оперирует формализованными данными, формат которых задается каждым конкретным протоколом. Обеспечивает общение приложений между собой.
Примеры: HTTP, FTP, WebSocket, SMTP, DNS
6. Presentation (представление).
Оперирует абстрактными данными (наборами байт). Обеспечивает функции преобразования данных (шифрование, сжатие).
Примеры: TLS, SSL
5. Session (сессии, сеансы связи).
Оперирует абстрактными данными + мета данными обеспечивающими постоянные соединения и аутентификацию соединения.
Примеры: TLS (частично), TCP (частично), PAP, L2TP, OpenVPN, WireGuard
4. Transport (транспортный).
Оперирует сегментами или датаграммами. Обеспечивает передачу данных на логическом уровне.
Примеры: TCP, UDP
3. Network (сетевой).
Оперирует пакетами. Обеспечивает логическую адресацию (ip адрес, порт) и маршрутизацию.
Примеры: IPv4, IPv6, ICMP
2. Link (канальный).
Оперирует кадрами. Обеспечивает физическую адресацию (mac адрес).
Примеры: Ethernet, IEEE 802.11 (WiFI), LTE (мобильные сети), PPP, DSL
1. Physical (физический).
Оперирует отдельными битами. Обеспечивает передачу данных по физическим каналам связи.
Примеры: RJ (витая пара), SFP (оптоволокно), USB
Согласно данной модели любые данные проходят все уровни от 7 до 1 при отправке данных и от 1 до 7 при получении. Каждый протокол должен взаимодействовать только с протоколами своего и соседних уровней, что на практике не всегда соблюдается.
Так же при передаче данных через множество сетей (что просто необходимо в том же internet) данные могут многократно переходить между уровнями 1, 2 и 3 (маршрутизация), а иногда и между более высокими уровнями (например при балансировке).
Кроме того, технологии виртуальных сетей (например VLAN или VPN) могут делать программную эмуляцию более низких уровней фактически передавая данные на более высоких.
А границы между уровнями 4, 5, 6 и 7 очень часто оказываются размытыми, например протокол HTTP, находящийся на 7 уровне, может работать прямо поверх протокола TCP, находящегося на 4 уровне.
С уровнями 4, 5, 6 и 7 чаще всего взаимодействует прикладное программное обеспечение. В системной разработке можно столкнуться с уровнями 3 и 4. Но и на уровне 2 так же применяются программные решения при разработке прошивок для сетевых устройств. И лишь уровень 1 является полностью аппаратным.
Модель OSI не идеальна, но она позволяет соотнести практически каждый сетевой протокол с определенным уровнем модели, что даёт первичное представление о протоколе и его назначении.
👍64🔥14❤11🥰3
  Telegraph
  
  Сетевая задачка с собеседований
  На собеседованиях, в контексте сетей, иногда могут предложить следующую задачу:
Всем привет, наконец-то нашёл время порадовать Вас постом, который неожиданно не влез в лимиты телеги и превратился в небольшую статью.
Надеюсь вы простите мне длительное молчание, последние полтора месяца у меня выдались достаточно загруженными. Помимо работы был какой-то нереальный наплыв запросов на моё менторство и вечера уходили на проведение занятий. Немного подкосило здоровье, почти каждые выходные катался в клинику, оставил там круглую сумму с 5 нулями, но зато сейчас всё нормализовалось. Так ещё и на работе, помимо основных задач проводил по несколько технических собеседований в неделю. Что-то написать сил просто не оставалось.
Но вот именно проведение собеседований натолкнуло меня на идею сегодняшней мини статьи. Предыдущим постом я начал писать про сети, а в работе моей текущей команды понимание сетей очень важно и мы спрашиваем о них на собеседованиях. Я стал предлагать кандидатам одну задачку на рассуждение, которую позаимствовал у коллеги с одного из предыдущих мест работы, он подписан на этот канал и думаю узнает задачку. Хочу ему сказать спасибо за неё.
В статье я расписал то, как бы я сам ответил на подобную задачу, надеюсь и вам будет полезен подобный разбор.
Почитать его можно тут: Сетевая задачка с собеседований
Надеюсь вы простите мне длительное молчание, последние полтора месяца у меня выдались достаточно загруженными. Помимо работы был какой-то нереальный наплыв запросов на моё менторство и вечера уходили на проведение занятий. Немного подкосило здоровье, почти каждые выходные катался в клинику, оставил там круглую сумму с 5 нулями, но зато сейчас всё нормализовалось. Так ещё и на работе, помимо основных задач проводил по несколько технических собеседований в неделю. Что-то написать сил просто не оставалось.
Но вот именно проведение собеседований натолкнуло меня на идею сегодняшней мини статьи. Предыдущим постом я начал писать про сети, а в работе моей текущей команды понимание сетей очень важно и мы спрашиваем о них на собеседованиях. Я стал предлагать кандидатам одну задачку на рассуждение, которую позаимствовал у коллеги с одного из предыдущих мест работы, он подписан на этот канал и думаю узнает задачку. Хочу ему сказать спасибо за неё.
В статье я расписал то, как бы я сам ответил на подобную задачу, надеюсь и вам будет полезен подобный разбор.
Почитать его можно тут: Сетевая задачка с собеседований
👍35❤🔥21❤8
  Подкаст о мотивации
    
  Подкаст с моими мыслями о такой вещи как мотивация, о том как она влияет на нашу деятельность + немного саморефлексии.
После длительного перерыва возвращаюсь к работе над каналом. Будут некоторые изменения в контенте, за перерыв я многое переосмыслил, о чём так же говорю на записи.
После длительного перерыва возвращаюсь к работе над каналом. Будут некоторые изменения в контенте, за перерыв я многое переосмыслил, о чём так же говорю на записи.
👍32
  Forwarded from Tina
Бесплатные моковые собеседования, разбор CV и помощь с поиском работы для бэкенд-разработчиков
Знаете это чувство, когда вы тратите кучу времени на поиски работы, но вас нигде не берут и кажется, что крутая работа в IT доступна только избранным? Эту систему можно хакнуть! Для этого нужно:
1️⃣  Научиться правильно презентовать свой опыт в резюме и на собеседовании
2️⃣  Понять, какие вопросы задают рекрутеры на интервью и заранее подготовить ответы на них
3️⃣  Выписать вопросы, которые чаще всего задают на технических собеседованиях и потренироваться отвечать на них
4️⃣  Много практиковаться на реальных или тестовых собеседованиях.
С этими задачами помогут наши партнеры — Solvery — сервис по подбору менторов из IT.
На следующей неделе ребята проводят Backend Fest по трудоустройству!🚀 
Будут не только технические собеседования, но и моковый скрининг с рекрутером, а также разбор CV и вебинар по поиску работы в 2024 году. Их проведут действующие специалисты из Яндекса, Райффайзен Банка, Wildberries и других компаний.
Расписание феста:
13.05 в 18:30 — Разбор CV
14.05 в 19:00 — Моковое собеседование по С++
15.05 в 19:00 — Моковый скрининг с рекрутером
16.05 в 19:00 — Моковое собеседование по Rust
20.05 в 19:00 — Моковое собеседование по Python
21.05 в 19:00 — Моковое собеседование по Java
22.05 в 19:00 — Как искать работу в 2024 году?
23.05 в 19:00 — Моковое собеседование по С#
Вы можете не только прийти зрителем, но и сами пройти тестовое собеседование и разбор резюме – а это очень полезный опыт✅ 
Скорее переходите по ссылке и регистрируйтесь, чтобы получить напоминания об эфирах!
Знаете это чувство, когда вы тратите кучу времени на поиски работы, но вас нигде не берут и кажется, что крутая работа в IT доступна только избранным? Эту систему можно хакнуть! Для этого нужно:
С этими задачами помогут наши партнеры — Solvery — сервис по подбору менторов из IT.
На следующей неделе ребята проводят Backend Fest по трудоустройству!
Будут не только технические собеседования, но и моковый скрининг с рекрутером, а также разбор CV и вебинар по поиску работы в 2024 году. Их проведут действующие специалисты из Яндекса, Райффайзен Банка, Wildberries и других компаний.
Расписание феста:
13.05 в 18:30 — Разбор CV
14.05 в 19:00 — Моковое собеседование по С++
15.05 в 19:00 — Моковый скрининг с рекрутером
16.05 в 19:00 — Моковое собеседование по Rust
20.05 в 19:00 — Моковое собеседование по Python
21.05 в 19:00 — Моковое собеседование по Java
22.05 в 19:00 — Как искать работу в 2024 году?
23.05 в 19:00 — Моковое собеседование по С#
Вы можете не только прийти зрителем, но и сами пройти тестовое собеседование и разбор резюме – а это очень полезный опыт
Скорее переходите по ссылке и регистрируйтесь, чтобы получить напоминания об эфирах!
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👀8👍7
  16 мая в 19:00
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥30👍6