Основные заповеди программиста

В последнее время «говно-код» встречается к сожалению очень часто, в этом «топике» я расскажу как уж точно не стоит писать код.

Если же вы спросите что я имею в виду под «говно-кодом» то я отвечу такое:

   value a = 7;
   a -= -1;

Или такое:

     value b = 112;
     b > 100 ? b < 150 ? b == 115 ? print(“equal 115”) : print(“not equal 115”) : print(“high of 150”) : print(“lower of 100”);

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

1) лучше всегда продумать код чем писать его на ходу.

2) не отнимай отрицательное число от другого числа, но есть некоторые случаи исключения.

3) не надо класть тернарный оператор в другой, если тебе надо так сделать, то замени его на конструкцию if else.

4) если тебе многократно надо проверить одно значение на равенство с другими и в твоем языке есть оператор switch, то куда лучше что бы ты использовал его чем конструкцию if else или тем более тернарный оператор.

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

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn

Найкращі коментарі пропустити

Зайшов сюди, бо подумав що тут будуть обговорювати правила переходу на «+500».
А тут — якісь приклади коду із студентських лабораторних.

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

Пафосна назва і відсутність контенту.

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Главное — правильный заголовок, он собрал больше 4К просмотров и более полторы сотни комментариев :)

В последнее время «говно-код» встречается к сожалению очень часто

И когда ж с января 2019 у тебя это последнее время настало?

И когда ж с января 2019 у тебя это последнее время настало?

Это просто чел тренируется в написании топиков, 1-й, блин!
Думаю, в этом опусе 100% фантазии

Суетно слишком. Я не программист, но многие мои знакомые программисты считают, что если ты не постиг текст по ссылке, то программистом пока считаться не можешь:
www.linux.org.ru/forum/talks/287211

Прикольно :)
Это ж не поленился кто-то... (я не дочитал до конца)

хренасе, чувак вашол вайти и узнал про тернарный оператор!

А целое на ноль делить мона? ну хоч трошки... для себе?

Саттер и Александреску, как на меня, отлично переписали принцип KISS применительно к коду: «KISS (Keep It Simple Software): Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.» И не забывайте что код пишется в т.ч. и для того, чтобы следующий погрузившийся в него гений восхитился его ясностью, либо же нашел там дерьмо на свой вкус: «Programs must be written for people to read, and only incidentally for machines to execute» (Co. Hal Abelson) . Все остальное — это «а мне так хоцца!».

JavaScript считает что любое число прекрасно делится на ноль (с результатом деления infinity), c++ считает так же.

не знаю, в JS есть всего вроде 5 основных типов данных — char, string (массив символов), object, int, float.

JS настолько плох, что не соответсвутет своей спеификации, даже в таких вопросах как основные типы данных?
Слава тебе Платан, что ты отказался от вакансии, предполагающей работу с этим варварством...

Поганий з тебе експерт:

1. undefined
2. Boolean
3. Number (In JavaScript, Number is a numeric data type in the double-precision 64-bit floating point format (IEEE 754).)
4. String
5. BigInt (в кінці числа треба n підставляти щоб стало бігінтом)
6. Symbol (якесь жабаскриптове ноухау. Схоже на чар, але не чар)

Боже, і цю всю *уйню треба вивчати. Може пронесе мене? Десь би глибоко на бек залягти до кращих часів.

Ой немного ошибся особенно жалко что про boolean забыл сам не знаю как, Js активно только 3 месяца изучаю.

вообще так вбил в поисковике, вот что выдало:

1) Число «number»
2) Число «bigint»
3) Строка «string»
4) Булевый (логический) тип «boolean»
5) Специальное значение «null»
6) Специальное значение «undefined»
7) Символы «symbol»
8) Объекты «object»

Сколько СЕКУНД это заняло? Какой СМЫСЛ тестировать знания, на получение которых нужно несколько секунд?

Я отвечу: умные спрашивают то, что может или могло понадобиться, и даже уверены что 50% ответов есть норма, в иных областях и 10% хороший результат, и 5% неплохой. Но вот ответ «не знаю» гораздо ценнее, чем самоуверенность в неправильном. Потому что если не знаешь — то найдёшь или спросишь, а вот ежели самодур...

Дурачьё же спрашивает то, что проще спросить. Где проще сравнить правильные ответы. При том что эти ответы никому не нужны в работе, а значит чем более опытный работник, тем меньше шансов что он знает хоть один.

Пример: чем равен предел Unsigned Int в JavaScript? Попробуйте ответить не подглядывая. А уже потом подсмотрите :)

У меня ответ неверный: ≈2 млрд, и если я имею шансы переступить эту границу, мне стоит внимательно подойти к строгой типизации данных на каждой обработке.

Десь би глибоко на бек залягти до кращих часів

Видел сегодня на апворке вакансию, где искали фуллстека с React, React Native и Golang. И таких вакансий больше чем чисто фронт/бек, так что залечь на бек может быть непросто.

Насправді пофіг чого більше чи менше. Треба шукати своє, а не керуватися абсолютними числами.

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

Так. Тому фронт базово треба вчити. Щоб якщо не знайдеться без нього, можна було на місці довчити і виконувати обов’язки fool stack-ера.

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

Мобільний девелопмент явно перебір. Якість тих апів буде відповідна. Я вважаю що одна людина може, але вірогідність знайти такого девелопера, особливо з таким стьоком де є го, і щоб знання були глибокі — дуже мала. Замовник явно хоче зекономити там, де зекономити не можна.

При цьому йому зааплаять. Але хто — ті кому байдуже що, байдуже як, аби роботу дали. Нічого, життя навчить.

особливо з таким стьоком де є го

Вот с этого я офигел больше всего. Это как должна жизнь помотать человека чтобы стать специалистом (там жиж только экспертов все хотят нанять) и в реакте, и в го

там жиж только экспертов все хотят нанять

Ринок лимонів. Експерти знаходяться! Хто менше париться на рахунок моралі, той першим експертом серед аплаєрів стає. І в результаті виходить, що замовник хотів зекономити найнявши одного дева, який вміє все, а по факту замовник найняв дева, який вміє лише половину, а другу половину він вивчить з увімкненим трекером, за гроші замовника, і зробить як попало. Клевер!

А целое на ноль делить мона? ну хоч трошки... для себе?

А зачем?
Это ж ни себе, ни людям, все нулю под хвост :)

Помню, видел такой код на одном рабочем проекте:

#define TRUE  '/' / '/'
#define FALSE '-' - '-'

Естественно. Только вот не каждый прочтёт сразу.

Ещё веселее будет когда код подменят на похожий по начертанию символ, и это дерьмо проваляется на проекте долгие годы, пока «случайно» по беспределу не уволят автора без зарплаты (в Україні то національна традиція), и последний не заэксплойтит багу.

Будет как с сертификатом Рябошапки, когда оказалось что Украина вообще не проверяет подлинность сертификатов.

Помню, видел такой код на одном рабочем проекте:

#define TRUE ’/’ / ’/’
#define FALSE ’-’ - ’-’

Так получше будет:
#define true (rand() <= RAND_MAX * 0.97) #define if(x) if ((x) && (rand() <= RAND_MAX * 0.97))

Demo

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

Ну да, синдром Даннинга-Крюгера. Если знаешь обходной путь — расскажи, нам всем интересно.

Разве это говнокод, если и так понятно что там делается.В современном говнокоде за лесом деревьев не видно.

1) Спасибо КЭП
2) Если так проще для понимания логики кода то не только можно, но нужно.
3) Спасибо КЭП
4) Спасибо КЭП
5) Спасибо КЭП

value a = 7;
value b = 112;
b > 100 ? b < 150 ? b == 115

6) No «magic» numbers!!! Хотя и здесь бывают исключения.

PS Предлагаю составить более общие заповеди. Например:
1. Порограмист не должен выполнять работу за цену существенно ниже рыночной и тем-более работать бесплатно. Нарушение этой заповеди является актом штрейхбрейхерства, нарушитель подлежит пожизненному изгнанию из цеха. Любое общение с изгнанным воспрещается :)

Изгнание в менеджері или заключение в концлагеря SCRUM-мастера?

Изгнание подразумевает что-то плохое )

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

Ну...
Это...
Может когда-то можно амнистировать? Лет через 10?

Еще больший грех не описывать сериализацию объектов, что запихиваются в переменные сессии на ASP.NET, из-за чего хрен вывести сессии вне процессов и врубить веб-сад или настроить веб-ферму без отпадания сессий, когда перегружаешь сервера.

Пафосна назва і відсутність контенту.

Також повівся на цей клікбейт.

Так кажеш, ніби очікував глибокої філософії під пафозною назвою.

Очікував рекомендації по зміні роботи, росту зарплати чи юридичні моменти цього всього.
Хоча б на якомусь рівні.
А тут якісь шматочки студентського коду.

Та бо автор і є студент, як виявилось.

Зайшов сюди, бо подумав що тут будуть обговорювати правила переходу на «+500».
А тут — якісь приклади коду із студентських лабораторних.

а есть правила для перехода на +500? Я всегда приходил и говорил , что хочу +500, всегда давали, а у вас? Хотя опыт java пока 2года зп 2100, магистратуру заканчиваю

Якщо може і є якісь заповіді щодо цього, то тут їх не побачите.

так мне не нужны, у меня своя рабочая философия, пока каждые полгода по +500 в одной галере и так до 5к дойду, потом надо что-то менять, чтоб 7-8 брать

а есть правила для перехода на +500? Я всегда приходил и говорил , что хочу +500, всегда давали

Ну вот — у тебя есть это правило.
Спасибо, что поделился!
Возьму себе :)

a -= −1;

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

Не вижу смысла рассматривать банальные примеры. Все уже много раз разжевано в умных книгах, а современные код-анализаторы даже обучают ИИ что бы он подсказывал вайтишникам как «свернуть» 10 вложенных if — else.
Сейчас работаю с кодом, написанным в одной из топ 10 ИТ компаний. Соответственно отношение к коду очень серьезное: куча разных анализаторов, покрытие тестами, код-ревью... Очень редко можно встретить явно тупой код.
НО вместе с тем код практически не читабельный! Т.е. глядя в код невероятно сложно понять что именно он делает. У меня такое впечатление что это как-то связанно с иным подходом к восприятию мира в Индии. Такая себе «восточная философия».
Код НЕ тупой, но даже самая простейшая бизнес-логика никогда не пишется просто. Похоже у каждого индуса есть свой любимый стиль, своя «философия».
Например один любить функциональный подход и лямбда-выражения. Его код выглядит как безумно длинная «колбаса» из вызовов. Как-то так: данные.избазы(х=>преобразовать).соединить(х=>данные.издругойбазы(x=>аггрегировать(сложить))).переслать(создатьсервис()).применитьшаблон(шаблон.взятьизфайла()).генеритьразметку(html).переслатьклиенту().
Отдебажить такое невозможно даже если бы IDE умело нормально дебажить лямбда-выражения (сейчас не умеет).
Второй подход: максимальная косвенность. Например что бы вычислить дискриминант по формуле b^2-4*a*c будут созданы 3 интерфейса и 3 реализации для операций возведения в квадрат, вычитания и умножения. И 3 структуры данных для переменных a, b и с. Потом будет класс Дискриминант, в который через IOC контейнер вставляются нужные операции и внутри еще будет пайплайн, который вызывает их в нужном порядке.
Вот такой-вот индуский оверинжиниринг: бессмысленный и беспощадный! Каждый чужой класс индус обернет в свой Адаптер, добавит своих интерфейсов — а только потом вызовет! Может им и правда за число строк кода платят?
Но обратная сторона этого еще хуже: американские менеджеры, которые познали Аджайл (а точнее «ковбой-кодинг»)! И они свято верят что код должен быть само документирующимся, что написание документации и работа над требованиями — это потеря темпа разработки! Мы решаем бизнес-ниды клиента и делаем это оперативно. А потом через год уже никто не помнит что там клиенты просили навернуть и как это должно работать! Кого не спроси — все отвечают «смотри код» ;)

Нечитабельные части должны быть тщательно вынесены в отдельный загон и огорожены.

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

«Розділяй і виноси» — Гей Юля Девелопер.

Так же не раз работал с индусятиной, хот заказчик как всегда мего-сириоусли блэт...
Насчет логики согласен полностью — усложняют просто ппц как, просто таллант —
— напихать стэйт переменных, чем выще видимость тем круче,
— невероятное количество if else, в том числе и вложенных
— предикаты в несколько строк,
-копипаста, тьма прайвет хэлперов болтаются внизу кода для Entity и будут написаны с нуля, но чуточку иначе для Person, надо реально випидорашивать дебагером днями + тестами если хочешь вынести хэлперы в бейз.
— никакого наследования и иерархии — у тебя 100500 хранимок? — получай 100500 классов где все будет весь флоу — вытаскиванние данных их риквеста, валидация, открытие\закрытие конекшена, Dispose метод, маппинг ...все три уровня(front, business logic, data sccess layer)будут смешаны и пустят корни в каждом классе.
Конечно же это все будет перекопипщено из одного другого + небольшие правочки (смотри пункт первый) которые порой выглдят как просто обфускация чтобы аналайзер не смог заподозрить копипасту...

Все это делается по двум причинам
1 — платят\хвалят за количество строк — чем больше строк тем больше работал\заработал.
2 — после такой индусской обфускации, очень мало у кого хватает сил\нервов\денег приводить в божеский вид, кастомер садится на иглу — после того как индусятина поразила кодовую базу, с ней может работать ток другая индусятина.

Честно говоря глядя на код часто задумывался что он писался ТАК именно для «job security» — что бы никто другой не понял и не мог заменить автора.
Если это и так — то сработало с точностью наоборот! Американских менеджеров задолбало что команда индусов любое изменение делает по неделе, а другие (белые) девелоперы потом даже не могут понять почему это не работает.
В итоге индусов послали и отдали это говно украинцам ;) Потому что наш код белые господа могут прочитать.

Для этого кастмоер должен созреть, а главное понять, что рефакторинг этого равносилен напсанию проекта с нуля, нужны бизнес аналитики, тестировщики, прорабатывать требования по новому, крыть все тестами, CI\CD, нормальный отдел для тестирования, а не просто ручника потыкать формы...все это вливается не только в копеечку на прогеров, готовых ворошить мумии фараонов, но и на аналитикво, тестировщиков, девопсов, sql девелоперов + лиды и архитекты.

Когда кастомер на такое созрел это золотая жила для галеры! Ведь кроме все указанных еще напихают всяких манагеров и срам мастеров :-)
Поэтому так часто на галерах такие проекты, они как наживка для кастомера.
Должен согласиться, что галеры могут очень даже вполне, причесать аппку до вменяемого вида, и даже оно будет работать.

а современные код-анализаторы даже обучают ИИ что бы он подсказывал вайтишникам как «свернуть» 10 вложенных if — else

кстати да, современные ИДЕ умеют и тернарники в ифы преобразовывать, и наоборот, и подсказывают как лучше

данные.избазы(х=>преобразовать).соединить(х=>данные.издругойбазы(x=>аггрегировать(сложить))).переслать(создатьсервис())

При нормальном форматировании читать такое не слишком сложно, но можно иногда уменьшить количество кода и количество промежуточных переменных

При нормальному форматуванні і процедурний код легко читається.

При том что ты НЕ ВИДИШЬ, что за данные, что на самом деле делает преобразование, какой реально соединитель применяется, к какому типу...

И это всего лишь 1 строчка кода, представь себе [не]читабельность всего проекта, написанного в этом «сахарном» стиле.

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

«Нечитабельный» проект — это когда к изменениям полей объектов привязаны «ивенты», меняющие другие объекты. Когда смотришь на ендпоинт, меняющий состояние объекта A и не можешь понять каким образом при этом меняется состояние объекта B. Хотя и такой код можно прочитать — достаточно глянуть в код класса A чтобы понять принцип действия. Но это могут не только лишь все.

А в цепочке вызовов всё как на ладони, ничего там сложного. Вот например вполне читаемый код

"При том что ты НЕ ВИДИШЬ, что за данные, что на самом деле делает преобразование"
  .split("")
  .reduce((acc, letter, idx, arr) => { 
    acc[letter] = (acc[letter] || 0) + 1; 
    return idx < arr.length - 1 ? acc : Object.entries(acc); 
  }, {})
  .sort(([letterA, counterA], [letterB, counterB]) => counterB - counterA)
  .map(([letter, counter]) => ({letter, counter}))

А если вынести в функцию, то ещё читабельнее

const countLetters = (str, ignoreWhitespace = true) => 
  str
    .split("")
    .reduce((acc, letter, idx, arr) => { 
      acc[letter] = (acc[letter] || 0) + 1; 
      return idx < arr.length - 1 ? acc : Object.entries(acc); 
    }, {})
    .sort(([letterA, counterA], [letterB, counterB]) => counterB - counterA)
    .map(([letter, counter]) => ({letter, counter}))
    .filter(({letter}) => !ignoreWhitespace || letter !== " ");

И подумай, сколько бы ненужных переменных потребовалось завести если писать «по нормальному»

Да? Что тут делается, я могу догадаться только по имени countLetters. И если у тебя там ошибка, то найдут её очень нескоро. Если же ты неправильно назвал функцию — считай свой код обфускацией.

Начнём с простого: видимость переменных. Она неочевидна при разборе. Это для компьютера все зависимости прописаны и правила вывода известны, для памяти читателя это адский процесс.

Дальше, ты всерьёз полагаешь что у тебя есть сверхспособность правильно именовать переменные? Так что читатель по их имени с ходу и 100% догадается, что они такое, зачем нужны, что ты собираешься с ними делать, и каковы их допустимые границы?

Есть вообще много чего «ненужного» в коде джунов. Правда потом оказывается что дешевле было бы переписать с нуля... если бы была спецификация. Но писать её дали «техническому писателю», который написал много бла-бла-бла, с ошибками в терминологии и потерей сущности того что описывает.

В твоём случае я вообще не понимаю этого адского дерева вызова функций для предположительно крайне часто используемого кода, который НУЖНО оптимизировать до инлайн-функции. Хорошая штука была в C, как же в той же Java этого не хватает. Когда вместо функции в коде получается небольшой набор прямых команд, без этих мегатонн операций со стеками, блокировками, деревьями наследования, приведениями типов, которые писакам, увы, не видны.

Да? Что тут делается, я могу догадаться только по имени countLetters. И если у тебя там ошибка, то найдут её очень нескоро.

Это потому что ты не знаешь JavaScript. Кроме того, обычно когда человек работает на проекте, то он более-менее знает что исследуемая часть кода должна делать

Дальше, ты всерьёз полагаешь что у тебя есть сверхспособность правильно именовать переменные?

Так использование цепочки вызовов как раз помогает избежать лишних переменных и проблемы их именования. Давай я перепишу эту функцию «по-нормальному», с минимумом «синтаксического сахара»:

const countLetters = (str, ignoreWhitespace = true) => {
  const lettersArray = str.split("");
  const lettersCount = {};
  for (let i = 0; i < lettersArray.length; i++) {
    const letter = lettersArray[i];
    if (lettersCount[letter] === undefined) {
      lettersCount[letter] = 0;
    }
    lettersCount[letter]++;
  }
  const lettersCountArray = Object.entries(lettersCount);
  lettersCountArray.sort(([letterA, counterA], [letterB, counterB]) => counterB - counterA);
  const ret = [];
  for (let i = 0; i < lettersCountArray.length; i++) {
    const letterCounterArray = lettersCountArray[i];
    if (ignoreWhitespace && letterCounterArray[0] === " ") {
      continue;
    }
    ret.push({
      letter: letterCounterArray[0],
      counter: letterCounterArray[1]
    });
  }
  return ret;
};

Такую простыню сильно легче читать? Именования переменных помогают?

Во-первых, теперь понятно, что ничего не понятно. Так что мля делает функция? Она тупо считает, сколько каждого символа? Тогда почему это не map на выходе?

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

Именования переменных дают понять ЧТО ИМЕННО ты хотел. Ещё лучше, если это не очевидно (а здесь не очевидно), оставлять комментарии. Вот как думаешь, человеку со стороны сильно понятно, что у тебя в letterCounterArray, а что в lettersCountArray? Главное, слово Array ты вписать в имя не постеснялся, хотя как раз это очевидно на любом этапе кода. А вот объявить структуры данных как следует — а зачем?

Разумеется, если речь идёт о highload подобный код ещё оптимизировать и оптимизировать. Вопрос исключительно в частоте пользования, речь идёт о 1k вызовах в сутки, или 1M вызовах в секунду.

Тогда почему это не map на выходе?

Потому что отсортировано по убыванию. Ну и пример вымышленый, специально чтобы цепочка вызовов (в предыдущем комментарии) получилась длиннее.

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

Так если покороче, то первый for заменяется на reduce, второй на map и получается та же цепочка вызовов что и в предыдущем комментарии, но разбитая по промежуточным переменным. И зачем эти все переменные, если человеки, пишущие на джаваскрипте, вполне знают что возвращает каждый метод?

Вот как думаешь, человеку со стороны сильно понятно, что у тебя в letterCounterArray, а что в lettersCountArray?

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

А вот объявить структуры данных как следует — а зачем?

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

Разумеется, если речь идёт о highload подобный код ещё оптимизировать и оптимизировать.

Хайлод может кстати и не сочетаться с читаемым кодом

Даже говнокод может не сочетаться с читаемым кодом :)

Неочевидный момент: львиная доля информации из текста кода компилятором выбрасывается. Это нужно людям. Сам код существенно короче.

Как работают классические функторы как раз читаемо. Если это не часто используемый код, заморачиваться эффективностью не особо-то и хотелось.

Неочевидной и крайне проблемной обычно является структура данных. Львиная доля говнокодеров пишут так, будто читая ОДНУ строчку кода, ВСЕ ОСТАЛЬНЫЕ ты должен помнить. Самое тупое, что они и документацию так пишут.

Хороший читаемый код написан избыточно. Я не спорю, ТРЕБОВАТЬ этой избыточности на уровне компилятора — глупость. Но вот писать так, чтобы не требовалось перестраивать мозг ради прочтения одного кусочка кода, потому что кто-то там багу потерял (а может и не там) — вот что делают хорошие программисты. И кстати, хорошие писатели обычных текстов, да и любого контента.

А по поводу циклов for — для меня они по сей день непонятны, почему во многих языках нет достойной эффективной замены этим итераторам. Ну вот ты знаешь про оптимизацию циклов С++ компиляторами... и вылезающие потом баги. Почему нельзя СРАЗУ попросить компилятор это сделать, и переписать код таким, каким он будет?

Почему в той же Java нет оптимизации обработки массивов? В конце концов, за столько лет, когда там уже будут честные типы, не наследованные от Object, а являющиеся «сырыми» данными для самой Java — в которых разбирается только код, да и то не всегда, но которые не нуждаются в обслуживании их иначе как просто выделение места и уничтожение?

Есть много когда-то хороших правил, которые сейчас тупо заменены бюрократией, и в результате всё что они делают — УСЛОЖНЯЮТ РАЗРАБОТКУ. Не менее чем в 100 раз, более адекватная оценка — 800 раз, учитывая затраты на тестирование.

не совсем вас понимаю зачем в цикле постоянно создавать новую константу чем изначально создать переменную и присваевать ей новое значение? Может просто я тупой, не знаю...

Потому что она вне цикла никому не нужна и не должна быть доступна.

данные.избазы(х=>преобразовать).соединить(х=>данные.издругойбазы(x=>аггрегировать(сложить))).переслать(создатьсервис()).применитьшаблон(шаблон.взятьизфайла()).генеритьразметку(html).переслатьклиенту().

не шаришь в фп.

c будут созданы 3 интерфейса и 3 реализации для операций возведения в квадрат, вычитания и умножения.

не шпришь в ООД.

Кого не спроси — все отвечают «смотри код»

зато аджайл и скрам!

1) лучше всегда продумать код чем писать его на ходу.

Херня, обычно пишу на ходу в 95% случаях, код почти сразу выходить отличным, в остальных 5% надо дополнительно порефакторить

подумать код, это когда у тебя одна таска на 2 дня, а когда ты на 2 проектах рубишь лавеху и отчитаться нужно за 16 часов, проработав макс 8, то раздумывать над кодом сильно некогда — рабочий, понятный -> в прод

Да даже если на таску 5 дней но она большая, то также делаю и все норм

а чем это плохо? кому-то за 1000$ красивые if-ы писать, а кому-то нужно быстро и успевать несколько проектов делать и бабосик косить , чтоб семью кормить и отдохнуть успеть

согласен, часто может получиться не самый лучший продукт, НО в украинском ИТ на галерах, хапонуть проектов и далать лишь бы платили — это стандарт де-факто, так, что мне как программеру остается играть по тем же правилам, набрать проектов и рубить бабло, ну если нужно качественно , у нас могут и качественно, но не за 20-25$ в час, тогда за рейт 50-70 будет качественно и по всем стандартам, хотя я сомневаюсь, что это лучше

ну разложить на а=а+1 для понимания или а++ это не 15 вложеных if else с циклами for и условиями для break / continue внутри)

все равно не понял, что это за алгоритм такой, что знак решает его сложность понимания, у меня было бы реально много вопросов увидев а -= −1, вместо а++ просто не надо давайть код тупым читать)))

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

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

Швидше за все, у сучасних реаліях, до того коду повернуться років через 5-ть.
До того часу програміст вже змінить три роботи.
Перейде на черговий проект, що рефракторять після індусів.
І навіть забуде назву цього проекту.

value b = 112;
b > 100 ? b < 150 ? b == 115 ? print("equal 115″) : print("not equal 115″) : print("high of 150″) : print("lower of 100″);

Что за язык? Почему компилятор позволяет игнорировать результат выполнения тернарного оператора? Или там сахар, который игнорирует void, который возвращается print’ами?
Или это какой-то динамически типизированный и интерпретируемый язык?
Как бы то ни было, использовать тернарный оператор с выражениями, которые возвращают void в принципе некорректно, независимо от вложенности.

кто сказал, что print() возвращает void

А что ещё он может возвращать? Ну даже если какой-нибудь флажок типа int или bool. Суть моего вопроса не меняется.

printf возвращает количество выведенных байт.

Этот пример не выглядит как C++.
По прежнему остаётся открытым вопрос по поводу снисходительного компилятора/интерпретатора, который разрешает игнорировать возвращаемое из тернарного оператора значение. Как минимум, должен прилетать хотя бы warning от какого-никакого статического анализатора.
Мой пойнт в том, что пример с принтами в тернарном операторе либо притянут за уши, либо это какой-то Ruby или JavaScript.

Чем говорить попробуйте прокомпилировать на плюсах следующую строку:

true ? printf ("A") : printf ("B");
Мой компилятор выдал только ворнинг, что последняя часть никогда не будет выполнена.
Мой компилятор выдал только ворнинг, что последняя часть никогда не будет выполнена.

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

Вот каноническая форма тернарного оператора:
result = condition ? expressionTrue : expressionFalse

Понимаете, в плюсах функция может быть вызвана, но результат её выполнения может быть не присвоен никакой переменной. Например, всем известная функция int puts( const char * str ), выдающая строку на стандартное устройство вывода, возвращает int. Тем не менее возвращаемое значение очень часто не проверяется, и в коде можно увидеть, например:

puts("Hello, world!");
Это же касается любых других синтаксически корректных инструкций. Например, если мы где-то в коде поместим строку
5 + 3;
то компилятор не выдаст сообщение об ошибке. То же касается и тернарного оператора, предоставленного нам в качестве примера: замените в нем print на printf или puts, определите b и эта строка будет скомпилирована. Таким образом, не соответствует действительности, что
что пример с принтами в тернарном операторе либо притянут за уши

Этот пример корректен в C++. Иное дело, что так писать не стоит, но об этом автором и так уже сказано.

Немножко непонятны такие претензии от человека, у которого в профиле написано «iOS Engineer». Если что, и Xcode, и AppCode в коде, написанном на Swift, вполне позволяют конструкции вида condition ? print("A") : print("B"). И если этот condition не был определен вот прямо тут же сверху, а действительно изменяемый — даже предупреждения никакого обе IDE не показывают.

Если что, и Xcode, и AppCode в коде, написанном на Swift, вполне позволяют конструкции вида condition ? print("A") : print("B")

Только потому что print возвращает Void. Для других типов будет предупреждение (которое можно конвертировать в ошибку линтером). Причём, даже @discardableResult не уберёт предупреждение. Для отлова Void результатов в тернарном операторе можно и нужно настраивать линтер, потому что это code smell.

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

Тернарный оператор может использоваться ради сайд-эффектов, а не результата. Если нужен ворнинг или ошибка компиляции, то это можно включить соответствующими флагами. А если не нужен, то не включить :)

я не использовал какой то один язык, что бы более широкому кругу людей объяснить я использовал вкачестве переменных всем понятный value (значение), использовал функцию print() вместо менее известных console.log() или std::cout << "". Вывод если бы я писал на каком то одном языке не кто б не понял, можно было конечно еще использовать Python.

Вывод если бы я писал на каком то одном языке не кто б не понял, можно было конечно еще использовать Python.

Так. Не тільки лише всі можуть зрозуміти:

console.log()

Основные заповеди программиста давно написали в толстых книжках «Чистый код» и «Совершенный код», чтобы не переизобретать заповеди рекомендуется ознакомиться

Большинство не читало даже обложку.

И прально делали. Это же дядюшка боб. Там куча субъективного бреда и капитанства.

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

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

Ну дай человеку самоутвердиться. Весна ж.

весь топик можно свести к рекомендации читать книги

читайте книги, они рулез (ц) DZ (если склероз не изменяет)

А по поводу тернарных операторов — ты загнул. Это одни из самых понятных конструкций. Разумеется, если применяются по назначению, а не для обфускации. Грубо говоря, когда тебе не нужно ветвить алгоритм, а присвоить 1 из 2 значений, уже готовых или понятных на уровне арифметики.

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

boolean worktime = hour >= 8 && hour < 17 && (dayOfWeek==1 || dayOfWeek==2 || dayOfWeek==3 || dayOfWeek==4 || dayOfWeek==5);

Всё, этот код становится нечитабельным, когда ты просматриваешь его по диагонали, ты понимаешь чего от него ждать, и ты легко разберёшься, чем он ограничен. Если туда нужно вносить изменения, ты разумеется развернёшь его. Но не чаще. С мат.ожиданием раз в никогда.

Такой код достаточно легко тестировать: ты видишь начальные значения, ты видишь возвращаемые значения, ты прячешь реализацию. Да, маленькими кусочками, в 1-3 строки, но это РАДИКАЛЬНО повышает удобство написания и проведения тестов. Мёд отдельно, пчёлы отдельно.

Недостаток: тебе приходится полагаться на имена переменных. И вот тут мы приходим к самой сложной задаче программирования — как правильно назвать.

PS. Булева алгебра вообще плохо переносит вложения в плане удобочитаемости, и соответственно вероятности допустить ошибку. Тестировать её откровенно сложно, особенно когда какие-то комбинации редки и под них не прописан код, они нужны под исключения, которые авось никогда не вылезут. И если это только не HighLoad, булеву алгебру лучше не оптимизировать. Потрать лишних пару-тройку операций, но будь уверен, что код работает как надо. И чтобы с первого прочтения понималось, КАК надо, КАК задумывалось. И нет большего гемора, чем разгребать булевы выражения с ошибкой, когда ты не знаешь, что собственно планировалось получить.

Не читаю цей меседж Пєніє, бо вже знаю що там буде Дартаньянство і «неочевидно, но факт». Дістав цей стиль аки розкривають істину. Став лайк якщо погоджуєшся.

Є тільки одна категорія людей, рефлексуючих що вони не дартаньяни. То ж або рясу накинь, або трусєля червоні зніми

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

Невже така банальність комусь неочевидна?

Такой код достаточно легко тестировать

«удобно» «тестировать» — как только тебе надо применить к подобной тернарной колбасе — boundary values & equivalence classes — все, пиши пропало. Без разворачивания в выражения с одиночными условиями — справиться можно только с дорогими code coverage тулами которые меряют самые разные метрики (например mc/dc)

6) обрабатывайте негативные сценарии, должен быть нормальный индикатор , что что-то прошло не так.
Вот так не надо:

print(error)
Но судя по проектам, индикатор никому ничего не должен.

Но именно это тебя спросят на каждом первом собесе!

Да-да, дадут распутать хитросплетение из тернарных операторов.
А потом, не дослушав ответ, скажут «понятно, переходим к следующему вопросу», поставив минус напротив пункта.

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

Так говоришь, будто те кто спрашивает — вообще знают, что пишут на проекте.

Особенно весело, что 50% этих ответов у них самих неправильные. Им даже про это говорили, но всё как-то некогда исправить...

Вдвойне весело, когда всё это должно получиться как надо только на Internet Explorer 6.0, при условии что сейчас январь или год високосный.

Одни такие мне отказали ещё в конце января. Где-то что-то не так: и через день ответ, что вы — всего лишь strong middle, не берём
На Доу до сих пор вакансия висит, наверное, ищут шалаву-девственницу.

Возможно тебя хотели продать как CTO :)

Почти со всем согласен, кроме
4) switch сейчас очень сильно продвинулся в плане шаблонов сравнения. Тот же pattern matching в ФП языках выглядит выразительней, чем if/else
5) зависит. Если речь идёт об уменьшении аллокаций, то мутабельные значения спасают от бешеного траффика памяти

4) откровенно похер. И то читаемо, и то читаемо.
5) тоже похер. У человека в памяти вообще нет констант, так что это вопрос правильного именования и не более. В остальном же константы — защита от дуркака. Как правило, именно дураки ими и не пользуются. А кто пользуется — жертвы синдрома Даннинга-Крюгера.

Это как Foreign Key в реляционных базах данных. Формально, служит поддержанию их целостности. На деле — всё куда быстрее работает без них, и что характерно, без каких-либо проблем. Если надо регулярно проверять целостность данных, это повод написать кронтаб на ночь, а совсем не тянуть лишние гигабайты индексов в оперативку.

Я так понял, что у тебя не было задач, которые бы привели бы к моему комментарию к 5 пункту

Так я ещё и на грабли ни разу не наступал. У меня граблеплясофобия :)

Это серьезно, по поводу foreign key? А что делать, если эта задача обнаружит нарушение целостности? К примеру у нас уже операция завершилась, деньги ушли, но запись в базе ссылается непонятно на что, потому что разработчик решил, что foreign key не нужны...
Вы уж скажите, с какими продуктами работаете, чтобы знать, чего опасаться :)

Начнём с того, что «деньги» — отдельная субстанция, с которой особое обращение. И там пишутся свои триггеры транзакций, и это очень плохая практика, писать их на уровне базы данных. Задача базы — хранить данные. Поддерживать целостность гораздо легче, правильнее, и что важно, распределяемей — на уровне приложений. Базы попросту лишены адекватных возможностей программирования, не говоря уж об их интеграции с другими комплексами по их правилам.

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

По поводу ссылок непонятно на что — вот бери и пиши триггер на апдейт и на делит для тех полей, по которым надо проверить, не наплодили ли от них потомков. Но в абсолютном большинстве случаев эти поля, по которым идёт логическая зависимость, запрещено апдейтить, а эти записи не подлежат удалению. И это очень даже ясно прописано РОЛЯМИ пользователя в базе данных. А ежели уже админ лезет править — то он знает, что делает, и никакие foreign key его не остановят.

Правильнее сказать, это защита от дурака. Оставшаяся от тех времён, когда запросы писали лапками, в том числе не программисты. Когда миллион записей считался чем-то на грани фантастики. Но время доказало, защита от дурака работает против умных, а против дураков, внезапно, нет.

Целиком согласен, зачем использовать встроенные проверки, если можно писать триггеры для тех же проверок на уровне сервера приложений... подумаешь, ну придется писать гораздо больше кода, придумывать синхронизацию, если серверов больше одного, мы же не ищем легких путей, и платят нам за количество строк кода, а не за функционал :)
А Ваша фраза, что «Базы попросту лишены адекватных возможностей программирования» говорит о том, что с базами данных Вы не слишком часто сталкивались :) - да, сейчас принято выносить всю логику на сервер приложений, потому как это как минимум проще масштабировать, но утверждать, что в них нет адекватных возможностей программирования... А потом, после таких вот советов, народ тащит эти миллионы записей на сервер приложений, чтобы отфильтровать их там и получить на выходе пару десятков записей.

Ключевой вопрос ЕСЛИ.

Ну отпинает сервер базы запрос — а дальше-то что делать? Ура, ура! Мы снова пишем код с разбором исключения и анализом его в применении к конкретной базе. И пишем уже в аврале, и не потому что заказчик накосячил, а потому что выставил нам предъяву — и доказывай, что не верблюд. Особо весело, когда проблему спрятали под ковёр на месяц-другой, а всплыла она при сверке с контрагентами, оформлении квартальных очётов...

Я не говорю, что базы лишены программиорования. Лишь утверждаю, что это либо через жопу делается, в сравнении с честными языками и фреймворками на них, либо требуется написание плагинов к базе — что несравнимо по затратам, а по результату идёт лишение переносимости и усложнение инсталляции.

Я не спорю, есть сиутации, когда дефолтные решения по защите «от дурака» — работают. Я лишь говорю, что на современных задачах таких ситуаций меньшинство, и теория разошлась с практикой уже потому, что теория работает в идеальных условиях, предполагая что всё что выходит за рамки — решается где-то кем-то в другом месте. Современные ситуации по качеству данных такие, что этого выходящего за рамки — авгиевы конюшни, и вот их-то и стоит разгребать на бэкенде, базе давая уже кристально чистую инфу, согласующуюся с моделью.

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

Если кратко: оптимизируют ВРЕМЯ и ДЕНЬГИ. Всё остальное — от лукавого.

Нет, мы честно пишем исключение в лог/шлем сообщение куда-то и все. Дальше условный менеджер заводит в условной jira таску, исходя из которой условный программист разбирается, почему в данном случае что-то не сработало. Примерно в половине случаев окажется, что пользователь ввел что-то неправильно, но этот ввод пропустила проверка на входе в приложение. С моей точки зрения это лучше, чем потом разбираться, почему следующей ночью крон по контролю целостности базы скажет, что что-то у вас с базой не так, деньги ушли не туда, в сеть подали не 220, а 300 вольт, больному вкололи 20 кубиков аминазина и т.п.

> Я не говорю, что базы лишены программиорования. Лишь утверждаю, что это либо через жопу делается, в сравнении с честными языками и фреймворками на них
Исходя из этого считаем, что C, Perl, Python, Tcl — языки заведомо нечестные (на всех них можно писать триггеры и остальную логику например на PostgreSQL). А можно тогда список честных языков и фреймворков, а то вдруг я не тем занимаюсь? :)

> И вот в этом случае, коих, повторюсь, большинство нынче — и стоит исключить лишнюю работу из базы...
И вместо использования встренного функционала базы писать свой код по контролю целостности... как-то это расходится с призывом оптимизировать ВРЕМЯ и ДЕНЬГИ.

например на PostgreSQL

и мы уже ограничились PostgreSQL, во веки веков
Извини, разве ты можешь передать код на С прямо из приложения в базу, и он будет выполнен, без перенастройки базы, без переписывания переменных? Вот уж сомневаюсь.
А хранимую процедуру можно на C написать?? С доступом к нативным блокировкам?

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

и мы уже ограничились PostgreSQL, во веки веков

Как бы Вам сказать... есть такая вещь, как пример, это когда применяют частный случай для объяснения общего :) Не нравится Postgre, тогда есть еще MSSQL — там процедуры можно писать на любом языке, поддерживаемом CLR...

А хранимую процедуру можно на C написать??

Понимаете, Вы упорно демонстрируете свое же утверждение по поводу образования — если бы Вы хотя бы немного были знакомы с тем же Postgre (а человек, который утверждает, что знаком с базами данных, должен иметь представление хотя бы о первой пятерке БД), то не задавали бы таких вопросов. Один из разделов его документации начинается фразой: «User-defined functions can be written in C»

Я не спрашивал о разделе, я спрашивал о переносимости. Если это действительно так, хорошо. Каюсь, действительно с Postgre не имел дела в плане переносимости процедур на C. Сильно раньше это было геморно.

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

Переносимости куда? Если с одной базы на другую, то... не то, чтобы геморно, но учитывая, что сам Postgre компиляцией не занимается, для процедур на C ему нужен бинарник, то да, запихнуть код процедуры во что-то типа Flyway не получится... но мы же говорили о принципиальной возможности, а не о том, как переносить.

По поводу проверок на уровне сервера приложений — тут как раз не согласен... т.е. да, проверки нужны, но... Проблема в том, что сейчас как раз большинство приложений делаются в виде сервер/кластер серверов -> одна база. Соответственно есть два варианта:
1. свести проверки, которые могут быть сделаны в базе — на уровень базы, т.е. минимизировать траффик и выборки, соответственно выиграть те самые время и деньги
2. делать все проверки на сервере приложений — и тут начинаются изобретения типа SAGA, EDD и т.п. в тех местах, где оно совсем не нужно, т.е. теряем время на разработку и отладку вещей, без которых все и так будет работать, т.е. те же деньги
Да, есть highload или olap приложения, где нужны уже другие подходы... но сколько у нас тех приложений?
По-моему где-то тут была статья с примерно таким диалогом:
— у нас распределенная система, 7 серверов...
— а какое у вас максимальное количество записей в таблице?
— 70000
Другая статья, «у нас highload система, 20кк транзакций в месяц, 100 серверов»... а 20кк транзакций в месяц это, если я правильно посчитал — 7 транзакций в секунду, для правильно написанного приложения хватит одного сервера и еще ресурсов на вырост останется

При том, что для того же highload обычно нужны точечные решения — в паре таблиц немного поменяли подход, вынесли их отдельно куда-то в nosql, остальное работает по общим правилам

Контроль целостности на уровне базы используется не как единственное средство само по себе, а вместе с контролем на уровне приложения. Так повышается надежность — если где-то баг допустили программисты, foreign key помешает испортить данные.

Я о том же. Надёжность можно повышать бесконечно. Вопрос, а нужно ли — не велика ли цена конкретно за это повышение, и насколько ценно само повышение?

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

По поводу цены — сравним решения:
1. есть foreign key, проверки делаются постоянно при вставке/обновлении, но осуществляются внутренними механизмами базы
2. foreign key нет, но есть проверки на каждую вставку/обновление: нужно сделать запрос на клиенте, сериализовать его, распарсить на сервере, построить план (если его еще нет), достать данные (те самые внутренние механизмы), сериализовать их, передать клиенту, там десериализовать...
3. вообще не делать проверок

Понятно, что вариант 3 самый быстрый... но допустим мы все-таки проверки делаем :) - Вы считаете, что вариант 2 быстрее, чем 1?

Я повторюсь, ЕСЛИ БЫ foreign key был достаточным, это прекрасный механизм. Но увы, проверок нужно гораздо больше. И поскольку они так или иначе делаются, foreign key стал во многих случаях атавизмом.

Есть и другая сторона медали: когда данных много. В этом случае приложение хранит в оперативе их структуру целиком или частично, именно по тем связям, по которым данные прилетают чаще всего. То есть данных много, метаданных — мало. Но их мало, когда они отфильтрованы, только те что нужны. А в базе их куда больше.

Так что вопрос не в скорости. Вопрос в избыточности и БЕСПОЛЕЗНОСТИ. Ошибки базы данных крайне сложно обрабатывать, для этого нужно писать много кода. Плохо понятного кода. То же самое в приложении куда дешевле в обслуживании: Структура данных описана куда лучше, данные в этот момент ещё связаны с источником, и есть средства грамотно инвалидировать инфу. В случае же с ошибкой базы нередки случаи просто выкидывания в лог (привет, индусы Майкрософта) — потому что НЕТ ВРЕМЕНИ программировать разбор полётов.

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

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

На самом деле мы занимаемся демагогией — я говорю: вот есть приложения типа А, в них желательно делать так, а есть B, в них можно немного по другому. Ваши возражения — это все неправильно, потому что в приложениях типа C нужно совсем по другому.
Например: в каких приложениях нужна сложная обработка ошибок БД? В 95% приложений достаточно сказать: «ой, что-то не получилось, зайдите позже», а админам в это время система мониторинга скажет, что с базой что-то не то. В оставшихся 5% возможно что-то и нужно... но ведь в 5%, а не 100%.

Я правильно понимаю, у вас обычно серверы приложений на многоядерных Xeon с минимум 1TB памяти, а серверы БД на Raspbery или Arduino с соответствующими ресурсами? :) Иначе я себе слабо представляю тягу отключить использование индексов на primary key (а foreign key их в основном и использует), а также кеширования в БД.

С точностью до наоборот — поскольку качество данных сильно спаскудилось (неизбежное следствие роста количества), проверки на бэкенде стали нормой, а проверка на базе — атавизмом, потому что на отработку её РЕЗУЛЬТАТОВ нужно написать немало кода для перевода в логику предметной базы. А на бэкенде всё уже находится в нужной абстрактной модели.

Касательно праймари — я бы не был так уверен, у многих таблиц праймари чистая синтетика.

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

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

Ага, я уже такое проходил — помнится я как-то смотрел один проект, в котором первой базой был выбран HSQLDB, с целью перехода в дальнейшем на что-то более серьезное. В общем повезло, что собственно содержимое базы оказалось никому не нужно, потому что при перевести на другую базу перелитием данных было нельзя. В этой HSQL foreign key как бы были, но не контролировались. В итоге ссылки в никуда, записи, на которые никто не ссылается. Я так понимаю, что Вы рекомендуете именно это? На вопрос: «а почему они не написали контроль в беке», ответ — «а кто будет платить за написание дополнительного кода, который дублирует существующий функционал базы?» Да, код конечно был не очень, но при включенных проверках в базе проблем бы ни у кого не было

Ага, а в БД значит тонкой настройки кеша нет? :)

Все-таки я вам бы советовал во-первых, немного почитать о БД, а во вторых, интересоваться современным железом :) - Сейчас большая часть производителей хранилищ данных как раз и продвигает хранилища на SSD... больше того, они уже и хранилища на NVME предлагают (Huawei например). А по поводу ненадежности SSD — во-первых, промышленные SSD и домашние это таки немного разные вещи, а во-вторых — в таких случаях обычно всегда есть RAID10, особо жадные ставят базы на RAID6, а особо параноидальные вообще делают что-то типа RAID60 :)

Нет, понимание базой устройства логики — это отдельная сказка. И попытка её туда засунуть по сути и есть перенос сервера приложений в базу. Узнай у ораклистов, насколько это дорого.

А то что у тебя какие-то косяки с переносом или выбором базы — так кто ж тебе доктор? Если ты не осилил какую-то базу, это не значит что всё плохо, только то что ты не осилил. Либо учишь мат.часть, либо просишь помощи того кто знает, в том числе за денежку.

Ну вот допустим был бы на тот момент у HSQLDB foreign key — что бы это поменяло по сути? Те же данные, те же ссылки, никакой новой избыточности. Foreign key по сути триггер на вставку, модификацию, удаление. Притом я даже не уверен, что он чётко отрабатывает на удаление, никогда не пробовал это сделать.

RAID на SSD — тот ещё идиотизм, по сути внесения ещё одного звена риска. Проблема SSD не в потере части данных, а в том, что нет достаточной защиты метаданных, без которых получить доступ к остальным данных — долго и дорого.
И вот по поводу промышленных SSD как раз и встаёт проблема, что статистически их меньше, и потому проблемы детектируются куда дольше. И только раскрытие прошивок в исходных кодах решило бы большинство проблем, вплоть до опенсорсных сторонних прошивок (и увы, подделки устройств). Но вопросы подделки вполне даже имеют другие решения.

Тобто, косяки бізнес логіки звалюємо на обмеження бази. Невже так важко зрозуміти, що видалення то досить складна частина системи, і на неї витрачається тричі більше часу — саме для того, щоб не вигрібати потім наслідки.

То в кращому випадку нагенерили висячих записів. Гірше було б, якби отримали дублювання поля зв′язку — і ті всі записи дісталися у спадок скажімо іншому клієнту.

Тому так, я кажу що обмеження бази зайві САМЕ ТАМ, де серйозно підійшли до розробки бізнес-логіки та витратили набагато більше часу на перевірки всього, що тільки можна перевірити.

Притом я даже не уверен, что он чётко отрабатывает на удаление, никогда не пробовал это сделать.

А я пробовал. Отлично работает и позволяет не писать лишний код для удаления всех связанных объектов. Удалил пост — удалились комментарии без какого-либо лишнего кода для их удаления.

Триггером по базе? А кто инвалидацию кешей будет делать?

Кешей чего? Вот ты сейчас додумал уже что есть какие-то кеши, которые foreign key как-то мешает инвалидировать.

Мне не нужно спрашивать у ораклистов, я сам в Оракле неплохо разбираюсь :) ... и кстати, писал логику на PL/SQL там, где это нужно было, при этом не могу сказать, что это вызывает проблемы.

А вообще, насколько я понимаю, этот разговор не имеет смысла — Вы не только плохо разбираетесь в базах данных (по крайней мере как минимум в Oracle, Postgre, MSSQL), но и в железе у вас явно знания не на уровне промышленных серверов. Более того, у Вас и со чтением проблемы :) - по крайней мере для того, чтобы понять фразу «я как-то смотрел один проект» как то, что я этот проект делал... нужно обладать плохим вниманием и хорошей фантазией :)

Ото ж бо! Бо то дорого їх розбирати. Набагато дешевше перенести самі обмеження на дані в бізнес-логіку, а вже в базу давати нормалізовані дані.

В общем случае, да, образование и опыт нужны чтобы НАРУШАТЬ правила. Чтобы снимать ограничения. И чтобы эти правила создавать, когда они полезны.

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

PS. Я не только foreign key не уважаю, я ещё и избыточность данных творить люблю, положив моржовый на третью нормальную форму (не говоря уже о более высших степенях маразма). Моя б воля, я бы и на вторую с пробором поклал, но это требует детерминирования порядка следования записей, что разумеется запрещает распределённое хранение. В абсолютном большинстве случаев работы с данными оно не требуется. Одним из примеров такого хранения является обычная запись в файл. К слову сказать, индексы лишены нормализации, и если уж начистоту, они для этого предназначены. То есть бюрократы по сути спрятали под ковёр проблемы, свойственные привычным способам работы с данными, и вынесли это в движки баз данных. И я посмотрю, как вы сможете работать с базами без индексов.

С одной стороны согласен, с другой — лучще переформулировать и сместить акценты: образование и опыт нужны чтобы знать когда МОЖНО нарушать правила и когда этого делать НЕЛЬЗЯ. Потому как из Вашей фразы следует: «у меня высшее образование, поэтому я выше правил, которые придуманы для всяких лохов» :)
Не совсем понял высказывание про индексы и про то, что они лишены нормализации — какое отношение индексы имеют к хранению данных? Это всего навсего дополнительная функциональность для ускорения работы с данными, соответственно требовать от них нормализации примерно то же самое, что требовать от ложки быть съедобной — мы же едим с ее помощью, значит она имеет отношение к еде. И работать с базами без индексов никто не запрещал — full scan еще никто не отменял... более того, если Вы работаете с базами, то должны помнить, что на маленьких таблицах индексы наоборот противопоказаны, потому что замедляют работу

Нет, не так. ЛИБО вы получаете образование до конца, и соприкасаетесь с реальной природой ограничений, ЛИБО не имитируйте что оно у вас есть, выполняйте предписанные правила, и НЕ СУЙТЕСЬ обучать других.

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

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

А до конца это как? Вот я например как-то получил таки высшее образование, поработал, потом, через какое-то время, защитился и получил PhD — должен ли я считать людей без PhD необразованными? О, кстати, Вы подали хорошую идею — предлагаю в начале каждого обсуждения писать свое образование, автоматически в споре побеждает тот, у кого его больше :)

> Фраза что индексы лишены нормализации означает, что они обслуживают данные за границами их вылизанной фундаментальной теории
Еще раз — индексы не являются участником общей концепции хранения данных, это вспомогательный механизм в конкретной реализации БД, его отсутствие на саму концепцию никак не влияет. Покажите мне хотя бы одно упоминание индексов в описании нормальных форм (на всякий случай: ключ — не индекс).

По поводу хранения неструктурированных данных — ну так есть оно уже: в куче баз есть возможность хранить строки, который потом представлять как XML, JSON и т.п., после чего проводить операции с отдельными полями... и все это на уровне SQL — вроде именно то, что Вы и хотели. Данные с архивацией — тут уже не помню, может у кого-то и есть... если нет, то да, придется писать плагин к базе. Ну или брать честный фреймфорк, который вытянет все 10ТБ данных, разархивирует каждую запись, отфильтрует, и на выходе отдаст 1КБ данных :)

Речь не о PhD, речь о готовности узнать мат.часть по конкретному одному вопросу, где правила вы хотите нарушить. Не больше.

Именно это я и сказал про индексы — они за рамками концепции. И этот «маленький» факт, будучи не заявленным явно, заставляет под синдромом Даннинга-Крюгера многих оставаться на пике уверенности, что они строго следуют правилам, что так нужно, и что все остальные делают то же самое. Они не знают, что вышли за рамки теории, едва написав CREATE INDEX или просто определив поле как PRIMARY KEY.

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

Однако есть один на первый взгляд парадокс, наглядно продемонстрированный в игре 2048: сколько нужно иметь клеток минимально, чтобы сложить 2048? Неправильный ответ — две, чтобы сложить 1024+1024. Правильный ответ — 1024+512+256+128+64+32+16+8+4+2+1, притом +1 не точно, может выпасть сразу 2. Но в любом случае вам нужно иметь ВСЕ ЗВЕНЬЯ лестницы, чтобы получить одно единственное конечное слагаемое.

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

По поводу строк — вы правы частично. Полноценное хранение — это 1 байт хранимой инфы на 1 байт информационной нагрузки, ну с очень небольшими издержками. Пока что это даёт только файловая система (которая, как ни крути, тоже является базой данных). Проблема в их разрыве: база данных не имеет механизмов удобной трансляции файловой системы. Я более чем уверен, что такие базы существуют, просто у них уже сильно другие протоколы, и разумеется они дико проприетарны.
Недостаток полноценности, разумеется, в способе защиты информации. Мы знаем, что надёжность хранения не 100%, как и в принципе есть задача бэкапа, и никуда от неё не деться. Вот собственно эта задача на сегодня общедоступных средств не имеет — компактного хранения и бэкапа, как у файловых систем, и умения работать с базой данных, совмещая как малые, так и большие данные — разумеется, с учётом затрат времени на это совмещение и соответствующих механизмов [раз]блокировки данных.

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

основная заповедь — не дай менеджерью себя развести и не продешеви

Это неправильная заповедь. Не всё меряется деньгами, иногда стоит сходить за лычками, если проект хороший. А если плохой — так туда и за деньги не стоит, один хрен когда всё посыпется, хрен заплатят. Особенно весело если тебя за границей забудут.

Підписатись на коментарі