Информация
- В рейтинге
- 2 804-й
- Откуда
- Санкт-Петербург и область, Россия
- Зарегистрирован
- Активность
Специализация
Бэкенд разработчик
Ведущий
C#
Java
Rust
Golang
Многопоточность
C
Системное программирование
Разработка игр
Unity3d
Алгоритмы и структуры данных
Уточню на всякий случай, речь идет о проектах связанных с ML и подобным или вообще о всех существующих типах проектов?
Я правильно понимаю, с Ваших слов,что приложение на python можно написать быстрее чем на Go в 10 раз?
Может ли студент закончивший медицинскую академию сразу идти оперировать людей?
Может ли студент закончивший строительный ВУЗ сразу пойти проектировать дома?
А если курсы специальные пройти?
Думаю ответ очевиден.
А программист конечно же сразу станет мидлом если ему секретные знания расскажут?
Для того чтобы стать условным мидлом, нужно уже быть джуном хотя бы год-полтора. Уже иметь устоявшиеся джуновские знания и опыт, уже набить все необходимые шишки. Чтобы двигаться на новый уровень нужен фундамент старого.
Все рассказы про то что можно сразу перепрыгнуть позицию не более чем реклама курсов.
Не совсем так. Они пробовали сделать поддержку специализированных дженериков но не смогли достичь ощутимых результатов, поэтому остановились на боксинге. На эту тему есть целая статья Одерски как они это делали.
Потому что это решение не выгодно именно "во всех смыслах". У Java и C# разная философия, нет большого смысла из Java делать второй C#.
Java проще на начинающих, в ней сильно сложнее отстрелить себе ноги - это ее основная философия с самого начала. Если бы добавили struct то язык стал бы сильно сложнее, а потом вместе in, out, ref, span и понеслось. Плюс, есть многие вещи в JVM которые принципиально плохо совместимы с этим. На вскидку не скажу но там и на GC завязано и в целом на всю спецификацию.
Но основной посыл что не было смысла делать клон C# с большим количеством детских болезней.
Вопрос исключительно - для чего.
Java/JVM сейчас это на 99% backend приложения и заточена на среднего специалиста, с философией - разработчику доверять нельзя, он может отстрелить себе ноги, поэтому все запретим и из кожи вон будем вылезать компенсируя свои запреты, чтобы закрыть проблемы производительности, памяти и безопасности пассивно. Для backend приложений - это более чем оправдано.
C#/.Net это инструмент практически для любых задач и вообще другая история вида - мы все взрослые люди, мы можем писать и на высоком уровне но у нас в кладовке есть все инструменты для специалистов с прямыми руками и мы не боимся ими пользоваться
Все эти разговоры про:
они от избалованности написанием современных приложений где можно класть на производительность и расход памяти. Как только появляются какие-то требования к производительности никто в здравом уме не будет полагаться на blackbox, что-там на уме у компилятора в этом релизе, на каком тире что-то будет оптимизировано и молиться на то чтобы все само оптимизировалось.
Каждый инструмент под свои задачи.
Ссылочность вообще не причем. Структуры прекрасно передаются по ссылке без всяких аллокаций. Проблема в том что каждая передаваемая переменная должна иметь фиксированный заранее известный размер. Если переменная интерфейсного типа то размер фактически передаваемых данных может быть любым до 0 и далее. Не может быть переменной или параметра, размер которого никто не знает при исполнении. В отличии от ссылки размер которой всегда фиксированный. Боксинг это способ впихнуть невпихуемое.
Когда мы пишем ограничение
where T : struct, IShapeто это совсем другая история, так как это скрывает вызов отдельной предварительно сгенерированной функции для каждого используемого типа. У каждой функции будет свой параметр фиксированного размера.Что значит уже? В C# изначально мономорфизация параметров типов что значит что любой вариант типа с параметром мономорфизируеться в отдельный тип, там нечему бокситься и незачем. Другими словами, не было никакого
List<int>всегда был List_int.Нормальный сеньор дает на простой вопрос - простой ответ. Если я спросил про equals и hashCode а кандидата начинает нести куда то в JPA и Hibernate хотя я даже не спрашивал его про это, значит что он мне зубы заговаривает а это на любом собесе или экзамене признак неуверенности.
Другими словами: "докажите что не нужно". Но ведь Ваше же утверждение можно применить и в обратную сторону - "докажите что нужно".
Многие говорят, что это всё нужно, но ни разу не видел крупный (практически production-ready) проект, написанный таким образом и который бы:
не становился мага тяжелым, сложным и запутанным за счет огромного числа абстракций на всякий случай
не имел протекающие абстракции на каждом шагу
не имел огромного числа костылей, потому что реальная жизнь не натягивается на чистые архитектуры
Более того, в подавляющем числе статей и книг нельзя посмотреть как реализуются на практике советы по сложным архитектурам.
Найти и предоставить хороший простой проект с простой архитектурой не проще чем найти такой же хороший со сложной.
Огромное заблуждение считать что есть какая-то архитектурная чистота и каноничность. Все эти чистые архитектуры и DDD это не более чем завирусившиеся авторские методики отдельных скучающих писателей. Будучи объективным нужно сказать что нет никаких хотя бы околонаучных доказательств что вся эта многослойность, вся эта эмуляция реального мира, вся эта чисто-архитектурность дает пользы больше чем вреда. Да по папочкам разложено, да уложено приложено, все реализации поменять можно, вот только там где в нормальном проекте для доработки хватить пары строк, в книжных архитектурах все будет когнитивно переусложнено, раскидано по десяткам классов и будут уходить часы, дни и недели на обсуждения архитектурной частоты согласно книжке и будет написаны тысячи строк кода которые решают проблемы которая такая архитектура и создала и не имеют никакой практической ценности для практической задачи.
Это я к чему. Наверное не стоит делать такие противопоставления. Делать из перехайпленых книжных подходов какой то эталон. Под задачу выбираем инструменты а не под инструменты подгоняем задачу.
Вообще, это забавно и печально одновременно - как в одно идиотское политическое решение cделать .Net только под Windows, до сих пор не дает, технически куда более зрелому и совершенному .Net(C#) обойти Java(JVM) исключительно по политическим причинам. Один раз упустили, а потом все по привычке будут делать все только на Java.
Второй забавный момент - изначально именно Java/JVM делалась как инструмент под все платформы-задачи а сейчас все наоборот, C#/CLR - хороший инструмент для решения практически любой задачи, в то время как Java/JVM в подавляющей доле это инструмент написания корпоративного backend и практически ничего более.
Хвост начинает вилять собакой
Просто иронизирую на тему компенсации профессиональных качеств красивыми названиями
Кто бы тогда мог подумать что сейчас это будет +1 к цветовой дифференциации штанов
Зачем называть вещи своими именами если можно заменить слово "программист" на "инженер" и все вдруг станет загадочнее, элитарнее, понтовее и круче. И пофиг что чем дальше тем средний программист тупее в техническом плане с каждым годом, главное что теперь он гордо зовется "инженер" и занимается они не никчемным программированием а целой инженерией!
Толку от переноса такой локальной логики - мало. Если проверка подписания - это проверка сущности и проверка в БД то мне ни горячо ни холодно от того что какой то кусок логики лежит в сущности. Мне все-равно нужно искать способы шарить логику связанную с походами в БД. А потом когда я зашарю логику usecase мне нужно дружить с отдельно зашареной логикой из сущности. Вопрос зачем мне все это если я просто могу написать метод который в себе будет содержать вообще все что для этого нужно?
Логика в сущности - это бесполезная полу-мера. Никакого толку от метода is_signed в сущности нет, потому что по итогу она мне не отвечает на вопрос - подписано ли что-то или нет, мне нужно еще искать другую половинку логики. Проще все концентрировать в одном месте где таких ограничений нет.
PS. Потом будет еще веселей, когда захотите реагировать на события. Будете городить городьбу внутри сущности, возвращать из нее события, пришивать эти события к юзкейсам и прочий мрак. Знаем проходили.
Не получаем. Все бизнес-операции сущности живут в сервисе сущности и больше нигде.
Как я уже написал - логика не будет в нескольких сервисах.
В Вашем примере данная логика работает ровно до той поры пока там нет работы ввода вывода. Если логика проверки подписи требует сходить в другую систему, или хотя бы в БД, то метод сущности превращается в тыкву и все нужно переделывать и решать вопрос с перед-использованием. Вариант с управляющим сервисом такой проблемы лишен.
Ну смотрите, давайте от обратного - зачем нам вообще какие-либо бизнес -правила описывать в модели? Вполне разумные преимущества:
1.концентрируем логику в одном месте - из какого бы участка кода мы не вызвали сущность, нельзя привести ее в неправильное состояние
2.вместо изменения отдельных полей мы делаем осмысленные операции с валидацией состояний и прочим
Звучит здорово, но ломается в то что это полумера. Сущность неполноценна. Ну допустим, мы зашили в ней правила касаемо ее полей. А какой в этом толк?
Вот есть операция - подписать. В ней мы меняем поля signature, signer, signed_at, предварительно проверил состояние подписываемого объекта. красиво. А потом в проверку приходиться вставлять запрос и толк от этой схемы стремиться к нулю, потому что из любого места в коде можно сделать подпись и сохранить а внешние проверки застряли в юзкейсе. При этом мы разнесли логику по разным классам, ходи потом бегай и собирай по кускам как делаться подпись. Решительных преимуществ не получили а вот недостатки в полной мере.
Теперь сравните с классической схемой когда все это будет написано в сервисе. В сервисе будет представлена вся логика работы с доменом от и до и без ограничений. Вы нажимаете метод sign и в нем вся бизнес логика, все инварианты и проверки, все походы в БД и во все интеграции. Все сконцентрировано в одном месте. Если сущность будет глупой но Вы просто запретите менять ее поля в любом месте кроме ее сервиса то получите концентрацию логики в одном месте без всех этих проблем и костылей.
Что мы хотим?
Что мы для этого делаем?
2/5 технических встреч, остальные это гуманитарное балабольство на тему ценностей, тердностей, самых сложных задач, философии принятия решений и видимо вопросов в духе - кем Вы себя видите через 5 лет?
Не очень понимаю к чему все эти заявления про инженерное мышление, если описание собеседования - это просто классический пример современного, модного, бессмысленного и беспощадного подхода как у всех.
Немного покритикую что хорошо а что нет.
Раз, и между двумя предложениями рождается противотечение. Это фундаментальная проблема ООП подхода на бэке. Мы не можем оперировать всей доменной логикой без инфраструктуры. Как только появиться необходимость валидировать на существование других данных в БД или что еще хуже, менять их - этот подход сразу превратиться в тыкву.
У нас получилась модель которая не самодостаточна даже для соблюдения своих собственных инвариантов а значит толку от нее ноль, она все равно нормально не работает и намного удобнее сконцентрировать всю доменную логику в одном месте - в сервисе.
Дальше:
Окей. Зачем нам этот класс? Вы по сути написали очень странную и неуклюжую функцию. Просто передайте storage и uow в параметры и выкинете никому не нужный класс.
Во-вторых, у вас в этом классе, как я и писал раньше, торчат инварианты инварианты, которые размазаны между несколькими классами.
В-третих, что будете делать, когда появиться общая логика между usecases? Дублировать? Или выносить в еще одну костыль-абстракцию?
Сервис намного проще как решение. Ну или просто оставить это функциями.
Ну тут вопрос то от обратного - зачем AI вся эта ерунда? Для него нет никакой проблемы разобраться и распутать или вообще переписать и как раз наоборот, лучше отдать предпочтение очень простому коду, который AI может зарефачить там где раньше это была боль. Для человека простой минималистичный код куда проще и для понимания и для валидации AI чем ломать мозг от валидации тонны кода при добавлении одного флага.