Полковник
  • 6 советов о том, как построить взаимодействие внутри команды

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

    Ну вообще-то такой человек называется Senior Software Developer везде, кроме шаражкиных контор. Если еще где-то пишут ТЗ, то очнитесь, уже 21 век на дворе, так не делают больше. Это не масштабируемо.
    Архитекторы конечно тоже разные бывают, но в целом, это тот кто планирует развитие продукта на перспективу и залаживает первый камень в фундамент.
    Есть еще тим лиды где-то посередине.

    Підтримали: Artem Bilyuk, MaxDeffer .
  • Что едят программисты?

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

  • В Amazon розробнику рекомендували працювати по ночах, вважаючи його малоефективним. Як відреагував програміст

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

  • Архитектуры на акторах: вступление

    А модуль ядра или скомпилированное приложение является данными? Что не так?

    Модуль ядра это модуль ядра. Микро-кернел архитектура, plug-in pattern, как угодно.

    Да, полиморфизм. en.wikipedia.org/wiki/Ad_hoc_polymorphism

    И где там об этом написано? Опять же, сказано о типах и о ООП. Про ad hoc только сказано что оно не является фундаментальной чатью системы типов, в том смысле что и без ООП имеет место. Но и о модулях ни слова.

    Имплементация интерфейса не меняет формы — данных. Меняется поведение. Тут та же аналогия с микро-кернел архитектурой.

    Но наверное это уже диалектика :) Каждому свое

    Підтримав: Denys Poltorak
  • Архитектуры на акторах: вступление

    Ну вот в соседнем коммента цитата из LDD как оно реально работает. Собственно, так же, как под капотом в С++, только тут таблицы виртуальных методов написаны руками в явном виде. Вот реальные примеры не из ядра:

    Ну я вижу какие-то сигнатуры и массу методов. Инверсию контроля можно делать уймой способов, от фабрики или template method паттерна до DI. Но DI предполагает наличие DI фреймворка который инжектит зависимости (да, мы не говорим про Pure DI). Т.е. они в одном месте описываются и все, далее только интерфейсы используются везде. Если есть че-то подобное на Си в качестве либ или еще чего то конечно хорошо. Прогресс.

    Это где? Изначально разговор был о том, что нам надо разрезать домен на столько кусков, сколько угодно

    Пускай так. Суть что чем больше тем сложней нарезать: мясо толще и тверже. И нож большой нужен и умение. Простые системы они же пет проекты на коленке там не так об этом думаешь.

    Как раз есть. Не скомпилится, если сигнатура функции отличается.

    Ну сигнатура это да. Вот например выдержка из F# по ф-ям. Там чуток более возможностей:

    F# also supports functional programming constructs such as treating functions as values, using unnamed functions in expressions, composition of functions to form new functions, curried functions, and the implicit definition of functions by way of the partial application of function arguments.

    Как-то так

    И у адаптеров нет внутреннего состояния, вроде пулов коннекшнов или настроек или таймаутов при ошибках? А если у них внутренне состояние (то есть, адаптер уже вдруг оказывается FSM, и результат запроса в адаптер зависит от этого его состояния — например, есть у нас связь с базой, или сокет отвалился) — то какое тогда тут функциональное программирование?

    FSM в F# это просто радость, всегда пользую.
    Вот — fsharpforfunandprofit.com/...​ypes-representing-states
    и вот — www.marccostello.com/...​mple-state-machines-in-f
    и вот — gist.github.com/...​ab10d8b567b89b1b078c02a2f
    У вас какое-то предубеждение что со стейтом в ФП как-то трудно работать. Вот серия статей по дизайну и имплементации калькулятора например (в 4-й части вводится FSM) — fsharpforfunandprofit.com/posts/calculator-design

    Инкапсуляция же, но эта инкапсуляция у нас одновременно затрагивает и данные, и код. ООП)

    Интересный вы собеседник — у вас все ООП получается: и Си и Haskell :)
    Инкапсуляция, модульность и как благодаря вам выяснилось, ad hoc полиморфизм (и параметрический тоже), они были задолго до ООП.

    Підтримали: Roman Pavlyuk, Denys Poltorak
  • Что будет с зарплатами в 2022?

  • Айтішники та зброя

    Ждем далее: «Айтишники и охота», «Айтишники и рыбалка», «Айтишники за рулём», «Айтишники и водка»...

  • Архитектуры на акторах: вступление

    Прям по определению полиморфизма, не?

    Не, это интерфейс (АПИ) и его имплементация которая живет в отдельном модуле и подгружаема. Из выдержи в вики:

    polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types

    Присутствует понятие типа. В CS тип это

    a data type or simply type is an attribute of data which tells the compiler or interpreter how the programmer intends to use the data

    А не просто указатель на функцию который ядро может дёрнуть. Прямая аналогия в ООП будет опрелить интерфейс и имплементировать его 500 разными классами. Это полиморфизм уже или еще не?

    Ну или зайдем с другой стороны, дайте тогда определение тому какой это тип полиморфизма и почему?

  • Архитектуры на акторах: вступление

    Нет, это просто когда мы можем в одну штуку подставить разные аргументы с разным кодом

    Прикольно, не знал что впервые ad hoc полиморфизм появился в ALGOL 68. Но и там же далее в статье все таки отсылка к Simula и наследованию и тому что мы все хорошо знаем по ООП — полиморфизму через function overloading или operator overloading.

    Это как раз настоящий полиморфизм.

    Ну все равно не убедили что это полиморфизм. В модуле функции не переопределяют функции другого модуля а только определяют его границы и функционал. В случае с ядром линукса мы подключили хедер файл (интерфейс) и определили имплементацию по вполне прописанной сигнатуре. Мы ничего не переопределяли. Где тут полиморфизм?

    И даже dependency injection + inversion of control).

    Это как? В Си? Не, ну я могу понять фабрику там, но IoC и DI. Может пример покажете?

    То есть, Вы считаете, что гексагональная архитектура появилась на ровном месте — ведь там почти вся логика на одном сервере лежит? Или что базы данных (тот же MySQL) не нуждаются в проектировании и архитектуре — взял, написал что-то как-нибудь, и оно заработало?

    Ну там же и не 1,3 или даже 5 ответственностей, правда? Изначально разговор был про это.

    В С это указатель на функцию. Не надо никаких структур. Просто адрес скомпилированной функции. С стал функциональным языком?

    Вот именно, просто указатель. Ф-я там не является то что называют first-class citizen. Нет никаких гарантий от системы типов и компилятора. В том же C# или Java нет поддержки partial application и каррирования на уровне конструктов языка. Но там это можно на уровне приложения или библиотеки с небольшими танцами. В ф-х языках есть.

    И вот вдруг обнаруживается, что модуль Email содержит:
    1) кучу настроек коннекшнов, сервера, форматов данных. Хуже того — он использует пул коннекшнов чтобы быстрее работать. То есть — у этого модуля есть энкапсулированное состояние.

    А что здесь не так? Да, инкапсуляция. Это хорошо. А вы это оборачиваете все это и пользуете как нужно. Разве в остальных ЯП не так?

    2) внутренний код, работающий с этим внутренним состоянием. А наружу торчит только АПИ. И это АПИ еще и полиморфно для пайплайна, присылающего данные — то есть, вместо мейла можно подставить другой модуль

    Что-то загнули тут. Подставить другой модуль это хорошо или плохо? :)

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

    Так и наоборот работает же :) Я частенько в C# подключал библиотеки из F#. Есть такая одна известная в мире .NET — FsCheck для property-based testing — чисто F# либа, которая порт с Haskell. И прекрасно работает.
    Это называется уже реюзабилити на уровне компонентов. Какая там внутренняя кухня меня не интересует. А учитывая что все это .NET байт-код и ранится в виртуальной машине то вообще фиолетово.

    Пока сюда не попадает бизнес логика о том, какие именно файлы нам нужны, а какие — нет.
    * Если Вы напишете фильтр файлов прямо в этом куске кода — то код будет запутан
    * Если Вы отделите фильтр в другой модуль — получится, что Вы группируете данные (файлы и директории) с кодом, который их обрабатывает (траверс). А код, задающий логику фильтрования — ничего толком не знает о траверсе. Снова ООП.

    Вам везде мерещится ООП :) Никакого ООП в структурировании и разделении кода и поведения нет. Уже говорил — хексагоналка в ФП она почти по умолчанию без танцев с бубнами. Попробуйте мыслить на каждый ваш запрос — что это ф-я.

    Фильтр файлов? — предикат, т.е. ф-я. Можно параметром принимать

    Підтримав: Roman Pavlyuk
  • 7 советов, как сделать Code Review легким и полезным

    Чувствуется боль в ваших словах :) Понимаю.
    И она исходит от работы в аутсорсе. Это к сожалению там норма. Мне посчастливилось работать в аутсорсе только в начале моей карьеры, потом все время в продуктовых компаниях, где от такого поведения отучал, да и вообще там куда реже такое.

    Но тут прибежал эффективный вахтёр

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

    И вроде как правильно — отдельно рефакторинг, отдельно изменения, притом и протестить это всё тоже отдельно.

    Тут нет единого «правильно». Это как с командой решите. Чисто процессуальное. Регрессионные тесты должны всегда зелеными быть.

    Но тогда рефакторинг нужно выполнить СНАЧАЛА, перед тем как делать фичу — поди докажи менеджменту, что из фичи на неделю ты 5 дней делал рефакторинг и 2 часа фичу

    Лично я предпочитаю continuous refactoring. Всегда. Статью об этом писал: danylomeister.blog/...​1/continuous-refactoring

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

    Кстати, есть конкретные парактики по разруливанию технического долга для больших кодовых баз: www.youtube.com/...​b_channel=GOTOConferences

    Ну и я всегда предпочитаю юникорн-продуктовые стартапы всем остальным вариантам. Там еще ничего не сгнило, толковые люди, мотивация и желание делать все по науке

    Підтримав: Sergey Lysak
  • Архитектуры на акторах: вступление

    Полиморфизм между модулями достигается одинаковым интерфейсом

    Полиморфизм есть суть ООП и только ему присуще. Между модулями может все же сводится к вызову функций по тому же указателю подгруженного модуля если говорить о Си?

    Как в линухе ядро подгружает драйвера, не зная заранее, какой ему драйвер подсунут?
    #include <linux/init.h>
    #include <linux/module.h>
    
    static int my_init(void)
    {
        return  0;
    }
        
    static void my_exit(void)
    {
        return;
    }
        
    module_init(my_init);
    module_exit(my_exit);
    
    Ну и поскольку драйвер может вызывать ф-и определенные в ядре то на этапе linking-а все внешние ссылки и резолвятся. Потом это все либо компилият вместе с ядром (монолит) либо готовят в виде kernel module без рекомпиляции ядра.
    Потом готовят makefile и на выходе имеем определенный object file (*.ko) который подгружаем через make load и вуаля имеем модуль в /proc/modules.

    Извините, може чего упустил, очень давно под линукс не программировал, но суть думаю осталась.

    Но это же не полиморфизм! Всего лишь API и соглашения.

    Почему они должны стираться? У нас же нет цели создать 500 разных акторов.

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

    Пускай получим на выходе 1, 3 или даже 5 акторов. Они будут выполнять свои задачи

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

    А где сами данные?

    Ну вот функцию можно передать в функцию. Это в простонародье называют функции высших порядков. И это уже данные для принимаемой функции (как указатель на структуру в Си например).

    Вот надо картинки из папки в формате JPEG преобразовать в формат BMP и отослать почтой (или наоборот). Картинки же не являются функциями?

    Это вообще чисто практическая задача. Ф-я преобразования и отправки будет выглядеть примерно так:

    getFiles JPEG |> transformTo BMP |> sendTo '[email protected]'

    Каждая из этих функций определена например в модуле IO, Pictures, Email и со своими вспомогательными ф-ми. Здесь уже сборка пайплайна. Вообще функциональщину можно выразить как Pipeline Oriented Programming.

    А вот конкретный и рабочий пример траверсала по папкам и принта всех файлов с разруливанием вложенности:

    open System
    open System.IO
    
    let rec SafeFileHierarchy startDir =
       let TryEnumerateFiles dir = 
          try 
             System.IO.Directory.EnumerateFiles(startDir)
          with _ -> Seq.empty
       
       let TryEnumerateDirs dir = 
          try 
             System.IO.Directory.EnumerateDirectories(startDir)
          with _ -> Seq.empty
    
       seq { 
          yield! TryEnumerateFiles startDir
          for dir in TryEnumerateDirs startDir do
             yield! (SafeFileHierarchy dir)
       }
    

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

    Это какой такой код? На Джаве за последние лет 20 написали больше, чем все, что до этого существовало

    Ну не знаю. Больше ли? Не имею статистики. Все таки 50-60 лет коболов, фортранов и паскалей были.

    джаваскрипт

    Этот зверь вообще в сторонке :) Он и ООП и ФП и процедурный если сильно захочется :)

    Підтримали: Roman Pavlyuk, Sergey Lysak
  • 7 советов, как сделать Code Review легким и полезным

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

  • Архитектуры на акторах: вступление

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

    Уже помнится обсуждали это. Инкапсуляция (модульность) сущевствует вне ООП. Отличия или схожести отношения к делу не имеют. Так можно и статический метод в классе сравнить с ф-й в функциональном ЯП. Наследование и инкапсуляция в ООП всего лишь прелюдия к главному свойству — полиморфизму. Как-то же на Си , Эрланге и Хаскеле умудрялись тонны кода в спагетти не смешать.

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

    Ну проектирование все равно никто не отменял. Разрезать на правильные кусочки это нужно уметь. High cohesion и low coupling в акторах стираются и это непривычно, а это одни из основопологающих принципов архитектуры. Но играться с актороми сплошное удовольствие.

    В ООП одинаково проходят границы модулей у кода и у данных. В ФП и процедурщине, насколько я понимаю, такого правила нет.

    В ООП как и везде границы там где нарисуешь. Но по сути в ООП есть поведение (код), состояние (данные) и это все завернуто в коробочку (объект). Есть конечно сторонники анемичных моделей и rich, но сути сильно не меняет.
    В ФП все просто, функции = данные. Есть еще ADT которые данные. Ну и можно всю программу выразить в виде структуры данных и интерпретировать ее. У того же LINQ оттуда ноги растут.

    Соответсвенно, в каждом месте надо ощущать 2 разных модуля: модуль кода и сдвинутый в домене относительно него модуль данных

    Что такое модуль данных? Вы говорите о статических данных или динамических?

    А практика подтверждает большее удобство ООП тем, что на нем есть большие старые проекты. Много. По сравнению с процедурными и ФП. Значит, этот код можно поддерживать и развивать, даже когда его много, и уже костыли со всех сторон вываливаются.

    А кода на процедурном и структурном больше чем кода на ООП и ФП вместе взятых :) И он поддерживается вполне себе... Даже КОБОЛисты-ветераны еще есть живые и где-то да поддерживают американский бизнес на плаву. Тут больше вопрос к квалификации чем к парадигме

  • Архитектуры на акторах: вступление

    Хорошее интро.

    Было бы хорошо упомянуть что не только дебажить тяжело но еще и тестировать.
    А еще в каких случаях противопоказанно применять акторов.

    По-мелочи, но важно.

    Различимы следующие основные виды сложности

    Есть еще accidential и essential сложность. Любая распределенная система обладает повышенной accidential сложностью, но иногда да, для куда более технических доменов это уже ближе к essential complexity (телеком тот же)

    модульность: код и данные разделяются интерфейсами на компоненты.
    Это — модульность, также известная как ООП.

    Модульность чаще объединяет и код и данные и не тождественна ООП. Модули были еще до ООП. В ООП — инкапсуляция, а та же инкапсуляция в структурном или функцмональном мире это как раз модульность. А бывает и так что код это данные, а данные это код.

    Это — акторы, или (микро-)сервисы.

    Тут тоже одно не равно другому. Все это сервисы, но то что понимают под микросервисами нынче, решает другие задачи. Микросервисы это о том как масштабировать организацию, дать автономию командам, разделить владение и как-нибудь разрулить зависимости между ними. Акторы все же больше о параллелизации вычислений и кодовая база там скорее будет общей как и ЯП/фреймворк. Хотя никто не мешает конечно юзать акторов в микросервисах, тот же Dapr sidecar в .NET на базе MS Orleans яркий тому пример.

    И кстати, это вообще о чем?

    Данные идеально расположены в плоскую структуру, и все правильно работает. Это — мир идей, в простонародье известный как спагетти, функциональное или процедурное программирование.

    Причем тут процедурное или ф-е программрование? Спагетти и равиоли в ООП по определению готовятся бытрей и проще — там столько рецептов что лечге плюнуть и сварить спагетти чем заморачиваться как идеальную лазанью сделать. И это везде и всюду наблюдаю.
    В стурктурных или ФП языках разбить методы по модулям и собрать из меньшего в большее интуитивно и на практике проще, чем спроектировать класс с правильной инкапсуляцией, интерфейсами и ненафакапить где-нибудь в иерархии с наследованием.

  • Ноут від роботодавця

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

  • 7 советов, как сделать Code Review легким и полезным

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

  • 7 советов, как сделать Code Review легким и полезным

    А у вас монорепо?

  • 7 советов, как сделать Code Review легким и полезным

    5 разработчиков, пишем платформу для телекома, вернее ту часть которая смотрит на наших заказчиков: фронт, бекенд, сервисы, апи. Да все как у всех в общем-то. Пришли к такой частоте экспериментальным путем. Для нас работает. Это из серии как меч — продолжение руки самурая, только у нас центральный репозиторий — продоллжение локальных коммитов. Через очень легковесные PR (благодаря установленным конвенциям и тулингу). Так что разряжаем обойму как можно чаще. Как по мне, любой флоу по типу Gitflow и долгоживущие бранчи только маскируют и отодвигают сроки того когда стрельнет и тело всплывет.

  • Как снизить риск невыплаты зарплаты?

    Изучать фондирование, финансовое здоровье, отзывы. Ну и все равно всегда есть риск. Если уверенности нет — попытаться заключать контракт где оплата по отработанным часам в конце итерации, недели, месяца.

  • Как снизить риск невыплаты зарплаты?

    Не работать на шаражкины конторы либо оплата за часы по итогу итерации. И чем меньше итерация тем меньше риск

← Сtrl 123456...8 Ctrl →