Делать сходу двоичный поиск, без требований - это признак незрелости программиста. Premature optimization.
Оптимизация делается ТОЛЬКО по результатам замеров и профилирования. Иначе алгоритмы усложняются и код становится нечитаемым. А читаемость кода для львиной части кода гораздо важнее скорости.
ВНЕЗАПНО может оказаться, что in-memory join работает на порядки быстрее, чем тот же джоин в базе. Особенно, если этот случай учтён при проектировании.
А вы в данном случае не понимаете разницу между статически типизированными языками и динамически типизированными.
Да, конечно, и там и там "вылетит птичка". Только в динамически типизированном языке вы эту "птичку" получите в рантайме. А в статически типизированном - на этапе компиляции. И на этапе компиляции вам не нужно отлавливать условия возникновения ошибки и изучать стек в попытке узнать, откуда это взялось. Компилятор просто не даст вам сделать такую ошибку.
И не надо называть исключения копеечной проблемой. Это может быть прод на миллионы запросов в час. Это может быть две недели попыток воспроизведения бага. Не надо недооценивать ошибки.
Статическая типизация - это один из инструментов управления сложностью проекта. Точно так же, как и ORM. Та технология, что позволяет сгрузить риск ошибки на неё. В ущерб кривой вхождения, да.
Если для вас внедрение в пайплайн компилятора или ORM делает проекты запутаннее, то у вас недостаточно сложные проекты. Или же вы не умеете ими пользоваться. Или у вас редкий случай, когда это просто невыгодно.
Все свои большие проекты я делал с ORM. Кроме последнего, где ORM не нужен. Вот просто у проекта другая идеология. Но вот придумать условия, где было бы оправданно использовать язык с динамической типизацией для действительно большого проекта я не могу.
Кто-то не очень понимает, что ORM в первую очередь - маппер. Да, и называется он Object-Relational Mapper. Отвечает за взаимосвязь между реляционными данными и объектно-ориентированным миром.
Тот, кто хотя бы раз сталкивался с опечаткой при загрузке поля в объект, уже не задаёт вопросы, оправдан ли ORM. Когда за тебя связку делает кодогенератор с нулевой возможностью ошибки на любой сложности схеме - начинаешь ценить надёжность такого решения.
Что касается SQL. ORM не может в принципе покрыть весь синтаксис SQL. И не должен, это не его задача. Его задача - сделать простым синтаксис 95% случаев, когда дальше джойна и WHERE ничего не надо. ORM не мешает использовать чистый SQL, а чаще всего может его дополнить, переводя результат сложного запроса в набор объектов.
C# действительно немного особняком стоит, благодаря рефлекшену. Рефлекшен позволяет в рантайме распарсить expression tree и понять "чего хотел программист". К примеру:
Нда, и эта извращённая. F-блок прижат к цифрам (часто будешь задевать escape, когда пишешь "ё"), расстояние между четвёрками F сжато, вслепую по F12 не попадёшь.
Ясно-понятно. Мы не умеем в джойн, поэтому сделаем подзапрос. Может сразу CTE прикрутить?
Задача решается элементарным селфджойном, чтобы проверить потомка на нулл. Парент уже есть в полях. Дальше можно и кейсом, можно и ифом выдать нужное значение
Я вот честно, не понимаю. Почему гадство? Люди, которые уехали в Канаду давно имеют канадские симки. Получили уведомление - ну сделайте что-нибудь, ну для начала симку страны, где живёте. Канадцы не обязаны делать роуминг для вашей страны. То, что был роуминг - это результат договорённостей а не нормальная нормальность. Может надо в политике страны кроется ответ, почему нам так часто напоминают, что текущее положение дел это результат интеграции.
Ну конструкция when(health == 0) это огонь. В концепции zero-cost features это можно даже сделать не на подписке, а вставляя компилятором вызов if (health == 0) при каждом декременте health. Очень красивая конструкция
Какая-то неловкая статья о том, как присобачить дженерики туда, куда их не надо присобачивать. Очень наркомански выглядит метод класса, который принимает два параметра типа Т, чтобы склеить их в тот же тип Т.
Ладно, если использовать экстеншены, то да, на вход приходит два аргумента, но первый помечен ключевым словом this, а значит его вызов будет с одним аргументом.
В реальном коде склейки, плюсы, аппенды и прочие конкатинации работают в типе класса и принимают ОДИН аргумент типа класса и выдают свой же тип как результат. Зачем тут дженерик? Чтобы клеить все и вся не учитывая тип? Таких задач в жизни не бывает.
Ближе всего я вижу необходимость помечать классы как способные агреггироваться. Но в данном случае решение унаследоваться от абстрактного класса - это говёное решение. В реальной жизни классу уже есть от чего наследоваться, а для обозначения возможностей классов придумали интерфейсы. В таком случае не надо вот этих всех "мудростей", просто наследуем IPohooy<T> и реализуем метод интерфейса T Pohooy(T second). Всё
Дата последнего изменения это не дата создания. В статье именно речь про дату внесения записи в БД. Такая дата не перезаписывается. И не понимаю, почему Вы против даты изменения. Сохранение даты изменения во всех таблицах ничуть не отменяет истории стейтов или что там у вас... Но добавляет способ выбрать объекты изменённые в определённом промежутке времени и ещё много чего полезного.
int result = a.LastOrDefault(n => n < x);if (result == 0) result = -1;return resultКажется, я уложился в 30 строчек.
Делать сходу двоичный поиск, без требований - это признак незрелости программиста. Premature optimization.
Оптимизация делается ТОЛЬКО по результатам замеров и профилирования. Иначе алгоритмы усложняются и код становится нечитаемым. А читаемость кода для львиной части кода гораздо важнее скорости.
Очень наивная статья без анализа причинно-следственных связей. Мне кажется, что лучше будет смотреться на пикабу, чем на хабре.
ВНЕЗАПНО может оказаться, что in-memory join работает на порядки быстрее, чем тот же джоин в базе. Особенно, если этот случай учтён при проектировании.
Для начала больше не использовать аргумент "не можешь знать, что под капотом происходит".
А вы в данном случае не понимаете разницу между статически типизированными языками и динамически типизированными.
Да, конечно, и там и там "вылетит птичка". Только в динамически типизированном языке вы эту "птичку" получите в рантайме. А в статически типизированном - на этапе компиляции. И на этапе компиляции вам не нужно отлавливать условия возникновения ошибки и изучать стек в попытке узнать, откуда это взялось. Компилятор просто не даст вам сделать такую ошибку.
И не надо называть исключения копеечной проблемой. Это может быть прод на миллионы запросов в час. Это может быть две недели попыток воспроизведения бага. Не надо недооценивать ошибки.
Статическая типизация - это один из инструментов управления сложностью проекта. Точно так же, как и ORM. Та технология, что позволяет сгрузить риск ошибки на неё. В ущерб кривой вхождения, да.
Если для вас внедрение в пайплайн компилятора или ORM делает проекты запутаннее, то у вас недостаточно сложные проекты. Или же вы не умеете ими пользоваться. Или у вас редкий случай, когда это просто невыгодно.
Все свои большие проекты я делал с ORM. Кроме последнего, где ORM не нужен. Вот просто у проекта другая идеология. Но вот придумать условия, где было бы оправданно использовать язык с динамической типизацией для действительно большого проекта я не могу.
Кто-то не очень понимает, что ORM в первую очередь - маппер. Да, и называется он Object-Relational Mapper. Отвечает за взаимосвязь между реляционными данными и объектно-ориентированным миром.
Тот, кто хотя бы раз сталкивался с опечаткой при загрузке поля в объект, уже не задаёт вопросы, оправдан ли ORM. Когда за тебя связку делает кодогенератор с нулевой возможностью ошибки на любой сложности схеме - начинаешь ценить надёжность такого решения.
Что касается SQL. ORM не может в принципе покрыть весь синтаксис SQL. И не должен, это не его задача. Его задача - сделать простым синтаксис 95% случаев, когда дальше джойна и WHERE ничего не надо. ORM не мешает использовать чистый SQL, а чаще всего может его дополнить, переводя результат сложного запроса в набор объектов.
C# действительно немного особняком стоит, благодаря рефлекшену. Рефлекшен позволяет в рантайме распарсить expression tree и понять "чего хотел программист". К примеру:
Orders.Where(o => o.IsCompleted && o.CreatedDate.Year > 2020).OrderBy(o.ID)Превращается в рантайме в SQL:
SELECT * FROM db.Orders a WHERE a.IsCompleted = 1 AND YEAR(a.CreatedDate) > 2020 ORDER BY a.IDА потом результат преобразует в массив типизированных объектов с полями, поведением и состоянием.
А с женщиной в чём проблема? В убежищах нет женщин? В любом fallout есть возможность выбрать пол персонажа.
Негры. Что с ними не так? Это же не ведьмак, они тут могут быть в любом количестве, не только Престон Гарви.
Я бы не стал стилистику F3-F4 называть детской.
Cпособ решения сложных задач путём разбиения их на более простые подзадачи называется декомпозицией.
Да если бы. В Казахстане премиума нет, ютуб просто безальтернативно "предлагает" включить рекламу.
Нда, и эта извращённая. F-блок прижат к цифрам (часто будешь задевать escape, когда пишешь "ё"), расстояние между четвёрками F сжато, вслепую по F12 не попадёшь.
понадобится какой-нибудь там хитрый JOIN, но нетЯсно-понятно. Мы не умеем в джойн, поэтому сделаем подзапрос. Может сразу CTE прикрутить?
Задача решается элементарным селфджойном, чтобы проверить потомка на нулл. Парент уже есть в полях. Дальше можно и кейсом, можно и ифом выдать нужное значение
Я вот честно, не понимаю. Почему гадство? Люди, которые уехали в Канаду давно имеют канадские симки. Получили уведомление - ну сделайте что-нибудь, ну для начала симку страны, где живёте. Канадцы не обязаны делать роуминг для вашей страны. То, что был роуминг - это результат договорённостей а не нормальная нормальность. Может надо в политике страны кроется ответ, почему нам так часто напоминают, что текущее положение дел это результат интеграции.
20 лет работаю в рф на C#. Первый раз слышу, что шарп не котируется.
Ну конструкция when(health == 0) это огонь. В концепции zero-cost features это можно даже сделать не на подписке, а вставляя компилятором вызов if (health == 0) при каждом декременте health. Очень красивая конструкция
Какая-то неловкая статья о том, как присобачить дженерики туда, куда их не надо присобачивать. Очень наркомански выглядит метод класса, который принимает два параметра типа Т, чтобы склеить их в тот же тип Т.
Ладно, если использовать экстеншены, то да, на вход приходит два аргумента, но первый помечен ключевым словом this, а значит его вызов будет с одним аргументом.
В реальном коде склейки, плюсы, аппенды и прочие конкатинации работают в типе класса и принимают ОДИН аргумент типа класса и выдают свой же тип как результат. Зачем тут дженерик? Чтобы клеить все и вся не учитывая тип? Таких задач в жизни не бывает.
Ближе всего я вижу необходимость помечать классы как способные агреггироваться. Но в данном случае решение унаследоваться от абстрактного класса - это говёное решение. В реальной жизни классу уже есть от чего наследоваться, а для обозначения возможностей классов придумали интерфейсы. В таком случае не надо вот этих всех "мудростей", просто наследуем IPohooy<T> и реализуем метод интерфейса T Pohooy(T second). Всё
¯\_(ツ)_/¯
Замена стека jetbrains ноутпадом++ - это, конечно, хорошая шутка.
Термин Reflection переводить не надо. "Отражение" смотрится чужеродно.
А что же случилось?
Код скриншотами IDE - это ужас. Поэтому код я не смотрел.
Вообще меня интересует, какую задачу решал автор и чем это отличается от тасков?
Дата последнего изменения это не дата создания. В статье именно речь про дату внесения записи в БД. Такая дата не перезаписывается. И не понимаю, почему Вы против даты изменения. Сохранение даты изменения во всех таблицах ничуть не отменяет истории стейтов или что там у вас... Но добавляет способ выбрать объекты изменённые в определённом промежутке времени и ещё много чего полезного.