Разбираю и объясняю пример хорошего и плохого кода

  Рет қаралды 49,504

S0ER

S0ER

Күн бұрын

#soer #itubeteam
Основной канал для общения и публикации новых видео - Телегарм - t.me/softwaree...
Спонсорство - donate.s0er.ru
Сайт платным контентом - soer.pro
Зеркало для видео Дзен Видео - zen.yandex.ru/...
GitHub - github.com/soe...
Чат для программистов - / discord
Группа ВК - codeart...

Пікірлер: 263
@ВикторСмольяков-щ4в
@ВикторСмольяков-щ4в 3 жыл бұрын
Никогда не рассматривал такие примеры с факториалом с такой стороны... Вроде пример банальный, а тонкостей оказывается очень много. Спасибо!
@qwertymangames1800
@qwertymangames1800 13 күн бұрын
Хвостовые рекурсии наши друзья А исключения переполнения стека - признаки плохого программиста
@fess932
@fess932 3 жыл бұрын
вывод - языки без строгой типизации позволяют ломать себе ногу передавая обьект туда куда надо передавать uint
@PostoiParovoz
@PostoiParovoz 3 жыл бұрын
В таких языках надо делать проверку и типизацию (валидацию) внутри функции.
@anotherone3641
@anotherone3641 3 жыл бұрын
а что скажешь насчет ассемблера?
@fess932
@fess932 3 жыл бұрын
@@anotherone3641 ассемблер это лучший способ сломать себе все что возможно))
@blacktrub
@blacktrub 3 жыл бұрын
если достаточно долго писать на javascript то вообще перестаёшь доверять людям и начинаешь обрабатывать всё подряд, будто каждый хочет тебе подсунуть undefined
@muratx10
@muratx10 3 жыл бұрын
😂😂
@fellainthewagon7166
@fellainthewagon7166 3 жыл бұрын
Вот это контент. Вот это можно пощупать. Больше бы таких практических наглядных ситуаций, больше разборов!
@dasauser
@dasauser 3 жыл бұрын
Жаль, что в жс не придумали тайп хинтинг. Хорошо, что для жс придумали тайпскрипт.
@arhitutorials
@arhitutorials 3 жыл бұрын
Название видео не соответствует содержанию. Надо было назвать "Страдания JS разработчиков")
@protiv_bio
@protiv_bio 3 жыл бұрын
Истинно
@drapasYT
@drapasYT 3 жыл бұрын
Благодарность. На редкость много полезного, на одну квадратную минуту видео.
@qwertymangames1800
@qwertymangames1800 13 күн бұрын
Никто не пишет рекурсии вызывающие переполнение стека. Это ужасный код. Юзаем хвостовые рекурсии вместо этого
@mikhailkh8560
@mikhailkh8560 3 жыл бұрын
Обожаю такие выпуски! Всегда есть о чем погуглить и чему поучится после!
@lexxkrt
@lexxkrt 3 жыл бұрын
а в языках с нормальной типизацией такого не произойдет, стоял бы тип uint во входных данных, и сразу отлетели бы некорректные данные на входе
@yaroslav8609
@yaroslav8609 3 жыл бұрын
TS в помощь
@qwertymangames1800
@qwertymangames1800 13 күн бұрын
@@yaroslav8609 ts всё равно транслирует код в js и выполняться код будет в js. Максимум чем ts может помочь - это дать подсказки до запуска кода.
@xdef42
@xdef42 3 жыл бұрын
Предлагаю сделать видео, где Соер просто 15 минут будет быстро говорить умные слова, за Макконнела, белые/черные списки и стратегии "мусор на входе - мусор на выходе" и т.д. больше спасибо
@aMR5AvDeG
@aMR5AvDeG 3 жыл бұрын
"мусор на входе - мусор на выходе" мое кредо
@peregrint
@peregrint 3 жыл бұрын
Отличный ролик! Я ещё больше полюбил TypeScript)
@olezhonnv3215
@olezhonnv3215 2 жыл бұрын
Ну, в левой функции можно ексепшн обработать и отдавать тоже NaN. Например, сделать влежнную функцию реального рассчета факториала, которую вызывать с трай кетчем, где в кетч блоке результат делать NaN. Ну и тип параметра проверять, чтобы было подходящее число.
@aronin4392
@aronin4392 3 жыл бұрын
Блин, я не программист, но автор канала так четко и понятно рассказывает, что даже мне абсолютно все понятно. Респект!
@kalobyte
@kalobyte 3 жыл бұрын
скоро тебя осенит, что ты оказывается и программировать можеш бросиш свою унылую работу, возьмеш нотыбук и поедеш в тайланд фрилансить под пальмами
@АзимАзимов-ч1й
@АзимАзимов-ч1й 3 жыл бұрын
Было очень полезно. Больше таких обучающих роликов. Спасибо🙃
@Игорь-ч6ф3и
@Игорь-ч6ф3и 3 жыл бұрын
Если идти по пути проверок, я б эту функцию завернул в ещё одну функцию, где бы и разместил проверки. Чтоб ещё и рекурсивно их не повторять.
@MrAnetto
@MrAnetto 2 жыл бұрын
Классическое GIGO - garbage in, garbage out. Наглядно
@Algok17
@Algok17 3 жыл бұрын
А что на счёт языков со статической типизацией?
@dasauser
@dasauser 3 жыл бұрын
А что насчёт них? Они молодцы. Они делают то, что соер предлагает прописывать руками, а именно ограничивать функцию от данных, с которыми она не работает, добавляя полотна проверок. Так что с ними все ок. Т.е. если параметр функции был условно integer n, то при мусоре на входе было бы исключение. И все норм. 3 состояния результата работы функции: число, бесконечность (это вроде как тоже число в жсе, я хз), и экзепшен.
@ForwardMyMonkey
@ForwardMyMonkey 3 жыл бұрын
@@dasauser uint
@Algok17
@Algok17 3 жыл бұрын
@@dasauser а что на счёт проверки x
@0imax
@0imax 3 жыл бұрын
@@Algok17 unsigned int - и число всегда будет неотрицательным.
@Algok17
@Algok17 3 жыл бұрын
@@0imax ну это для данного примера подходит, а что если в агрументы передаётся класс, части которого могут быть некорректными и из-за этого не отработает дальнейшая логика?
@antonpankrat4594
@antonpankrat4594 3 жыл бұрын
может так еще лучше function factorial(n) { return fact(n); } function fact(n) { if (n === 0) return 1; return n * fact(n-1)); } таким образом мы уберем из рекурсии проверку (многократную) хоть белого хоть черного списка
@enkryp
@enkryp 3 жыл бұрын
Такой подход требует, чтобы во время рекурсивных вызовов входные данные оставались корректными, гарантии чего наш код не даёт. Например, при проверке "входное значение должно быть числом большим или равным единице" указанный код крашнется при n=1.2
@eugeneponomarov7429
@eugeneponomarov7429 3 жыл бұрын
Да, но у нас вместо одной функции теперь две, что не очень красиво
@antonpankrat4594
@antonpankrat4594 3 жыл бұрын
@@enkryp
@fess724
@fess724 3 жыл бұрын
Чтобы не создавать 2 глобальные функции лучше поступить так: function factorial(n) { if (!Number.isInteger(n)) { throw new TypeError('Variable n must be and integer type.'); } if (n < 0) { throw new RangeError('Variable n must be positive integer.'); } return (subf = (i) => { if (i === 0) return 1; return i * subf(i - 1); })(n); }
@qwertymangames1800
@qwertymangames1800 13 күн бұрын
По хорошему факториал вычислять лучше через reduce в функциональном стиле. А если делать нечего и хочешь использовать рекурсий то пожалуйста, используй хвостовую рекурсию, чтобы не вызвать исключение переполнения стека.
@dmitrygurinovich58
@dmitrygurinovich58 3 жыл бұрын
Насколько я понял основная идея этого видео в том, что поведение функции должно быть детерминированным. И я с этим полностью согласен. Но примеры на JS лично для меня только добавляют путаницы. Я, признаюсь, плохо знаю JS. Видимо поэтому у меня осталось только больше вопросов, чем ясности: - я правильно понимаю, что в правой функции выбрасываются одинаковые ексепшены для разных инпутов? - Если ексепшены разные - то это мало отличается от левой функции, так как надо их все обработать. - Если они все одинаковые и сообщают о переполнении буфера - то, вроде бы лучше, но не совсем понятно, как это поможет вызывающему коду понять, что он передал неправильный аргумент? - И вообще, если, я увижу, что при передаче неверного аргумента в функцию она выбросила ексепшен, который говорит о том, что она пыталась выполнить свою логику с этим заведомо неверным типом аргумента, мне будет не по себе. Просто представьте, что функция не считает факториал, а обновляет состояние в базе данных, например.
@solitarysubscriber6575
@solitarysubscriber6575 3 жыл бұрын
правая функция вместо моментального выхода при отрицательном целом будет крутиться до переполнения стека. это что угодно, но не хороший код. можно было бы проверить тип, но динамикодебилы не догадаются. поэтому весь фронтенд в такой жопе, ждём переполнения стека
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
На чем основывается утверждение? Переполнение стека в JS в данном случае произойдет для тебя так же моментально как и выход. Страх ради страха?
@solitarysubscriber6575
@solitarysubscriber6575 3 жыл бұрын
@@S0ERDEVS А на медленном компьютере? А если это происходит тысячу раз подряд? Тоже будет "так же моментально"? Что это вообще за больная логика: "компьютер быстрый, давайте делать лишние (!) действия, не писать же нам более аккуратный код в конце концов"? Поверить не могу, что приходится это объяснять серьёзному специалисту. Но, как я уже сказал, это объясняет, почему веб-страницы долго грузятся и медленно работают, а браузеру потреблять 2гб ОЗУ для отображения картинок и текста (!!) считается нормой. Печально, очень печально.
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
@Solitary Subscriber Поверить не могу, что для тебя нормальная ситуация - тысяча исключений подряд, в моей практике вероятность исключительной ситуации в 0.01% - это уже очень много, но даже в таком случае, если посчитать вероятность того что такие события произойдут 1000 раз подряд, то окажется, что это практически нереально (очень уж маленькая вероятность такой ситуации). Т.е. у тебя получается, что ради того чтобы сэкономить процессорное время 1 раз на миллиард вызовов (на самом деле даже больше, но считать точно не хочу), ты в каждом из этих вызовов готов делать доп проверку (которая не бесплатно выполняется). Вот поэтому и получаются медленные приложения, что пихаете в каждую функцию проверки, которых можно избежать, если перестать руководствоваться интуицией, а подучить тервер и посчитать реально насколько вероятно наступление события, ради которого вы вносите неопределенность и сложность в программу, убивая производительность в нормальном потоке выполнения. Еще раз подумай - речь идет не о нормальном потоке исполнения, а о исключительной ситуации, т.е. в нормальном потоке вообще не будут использоваться доп. ресурсы. В твоем же случае ты хочешь экономить ради редкого исключения, повышая нагрузку на нормальный поток.
@niklkelbon3662
@niklkelbon3662 3 жыл бұрын
@@S0ERDEVS просто язык гавно вот и всё
@trell_7842
@trell_7842 3 жыл бұрын
я 1 кто пытался поймать кадр на 07:12 и очень сильно разочаровался ???((((
@КириллЧе-я5ы
@КириллЧе-я5ы 3 жыл бұрын
А если не использовать рекурсию в данном примере, а применить цикл, как быстро произойдёт переполнение?..
@azamatk4302
@azamatk4302 3 жыл бұрын
TypeScript поможет избежать мусора на входе. Типизация + аннотация параметра функции.
@robertdowneyjr8494
@robertdowneyjr8494 3 жыл бұрын
Не поможет, если сам разработчик дундук и поставил условный any как тип. Тут надо понимать что и зачем, язык лишь даёт (или не даёт) инструменты для этого.
@azamatk4302
@azamatk4302 3 жыл бұрын
@@robertdowneyjr8494 В таком случае поможет проверка в аннотации. Чтоб обойти, дундуку придется лезь в аннотацию и там ломать проверки.
@robertdowneyjr8494
@robertdowneyjr8494 3 жыл бұрын
@@azamatk4302 Вы не верите в могущество идиотизма? :)
@vetalmontolio8075
@vetalmontolio8075 3 жыл бұрын
Не во всех случаях, от микса эксепшенов, НаН и обычних чисел не защитит даже при правильной типизации.
@KopoLPedov
@KopoLPedov 3 жыл бұрын
особенно смешно этот комент выглядит, если вчитаться в повторение "избежать" )))
@агатакристи-г3ы
@агатакристи-г3ы 3 жыл бұрын
Жень, ударение такое "Сти́вен Макко́ннелл "
@takiekakmi7532
@takiekakmi7532 3 жыл бұрын
Хм, хоть я и питонист, тем не менее - интересная концепция, особенно при переполнении стека (хотя это будет сделать проблематично - скорее комп положишь...) Ну и отсюда понимание, что питонячий обработчик исключений - просто топчик
@viktor_borodin
@viktor_borodin 3 жыл бұрын
Не знаю, на си и c++ - изи, причём если не сталкивался с таким, то можно по первому разу сильно удивиться, когда делаешь какой-то итеративный расчёт.
@mormorrowind403
@mormorrowind403 3 жыл бұрын
Спасибо, за разбор. Очень познавательно
@PostoiParovoz
@PostoiParovoz 3 жыл бұрын
Оба примера - плохой код. Должна быть валидация входящих данный и должно выбрасывать ошибку, либо в крайнем случае 1 (в зависимости от задачи). Также должно быть преобразование типов - это же JS *!!! Левый код более правильный. Валидация слабая, но она есть! Надо просто сделать это лучше. Потому что потом , когда во время разработки будет пойман результат Exception, хотя по факту будет ожидаться выполнение, а не переполнение, потому что якобы должно поступать небольшое число на вход - вот тогда разработчик "хорошего кода" будет рвать последние волосы на мягкой точке, ища что же не так. Так для примера на 8:00 идёт рассуждение "либо результат, либо Exception". А на каком результате он будет наступать? На 20000, на 10486? А если комп и движок JS из будущего и потянет и даже 100 000 на расчёт? * данная функция из-за особенностей JS автоматически будет приводить всё в числа. Но "0" ноль, она не переварит! Что выдаст factorial("0")? А если математическая функция использует сложение?
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
Очень наивный подход, на практике так не делается, уже в следующем видео на примере redux показал, что боятся исключений не стоит, и умение проектировать как раз в том и заключается - не делать лишних проверок, пытаясь подстелить соломинку.
@PostoiParovoz
@PostoiParovoz 3 жыл бұрын
@@S0ERDEVS ага, а потом разгребать багрепорты от пользователей. Вот так джуны почитают вас, ещё и формы проверять не будут, потому что наивный подход на практике. У вас вероятно свой опыт умения проектирования, а на практике - чем больше вариантов учтёшь, чем больше проверок и тестов предусмотришь, тем проще будет поддерживать. Не придётся искать ошибки. И хорошо, если эта функция не жизненноважные. А то может со счёта уйти пару миллиончиков долларов и будешь всю жизнь отрабатывать.
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
@PostoiParovoz причем тут мой опыт? Открой любую публичную популярную библиотеку и посмотри как они написаны. Было бы желание, а информации на счет проектирования более чем достаточно. Если в коде куча проверок и явных приведений - это первый признак, что никто его не проектировал, а код написан по интуиции.
@ДобрыйЧеловек-я6о
@ДобрыйЧеловек-я6о 3 жыл бұрын
Код хороший. Код плохой. Код злой.
@Кочевник-й3г
@Кочевник-й3г 3 жыл бұрын
Образца 1966 года.
@vlatterran
@vlatterran 3 жыл бұрын
Из этого всего мы делаем вывод - js плох, ибо у него есть ничего, и другое ничего
@qwertymangames1800
@qwertymangames1800 13 күн бұрын
NaN есть во многих языках. Это результат вычисления к примеру 0/0 Это число, но не число при этом. Inf/-Inf тоже в любом языке есть, это число в типах с плавающей точкой. undefined фишка js. По сути аналог null, но не null так как у null есть своё отдельное значение в js. А исключение Exeption тоже есть во многих языках, к примеру Java, C# Откуда взялся NaN? Сначала функция вернула просто return; -> undefined. Потом undefined попытались математически умножить с числом и получили число "нечисло", то есть NaN.
@stanislavsh6582
@stanislavsh6582 3 жыл бұрын
На самом деле все довольно сложно. Если более комплексный кейс рассмотреть, допустим с парсингом Http - все будет не так уж и очевидно. А люди из команды еще тебе и скажут, что им лень обрабатывать исключения и потому твой код не должен их бросать. Ну и в итоге - все придет к тому, что у тебя все публичные функции будут выглядеть как-то так: IResult, а в контексте веба - всегда 200 и пусть тот кто получает результат - смотрит, все ли нормально.
@liravesnovaya242
@liravesnovaya242 3 жыл бұрын
По поводу лени обработки: пускай тогда просто делают пустой catch раз уж так лень. По мне, подход: "появилась проблема, выдай исключение и умри" в разы лучше мусора на выходе, потому что мусор может потом уйти очень далеко от источника, и источник уже можно и не найти.
@stanislavsh6582
@stanislavsh6582 3 жыл бұрын
​@@liravesnovaya242 Да я сам так же считаю(относительно принципа fail-fast), но что поделать, я же не один в команде. Потому и сказал что в конечном итоге все сведется к IResult. Как по мне - тупое решение, потому что не дает до конца понять - что не так, но что поделать.
@niceandquickly
@niceandquickly 3 жыл бұрын
Почему не рассмотрено исправление левого кода с учетом белого списка и выброса исключения? Или это тоже плохой вариант, почему?
@ArtyomShakurov
@ArtyomShakurov 3 жыл бұрын
Не успел поставить лайк после завершения, но вернулся и поставил! Спасибо за разбор!
@keksinjo
@keksinjo 3 жыл бұрын
чтобы избежать переполнения стека: function sum(n, s = 0) { return (n) ? () => sum(n - 1, s + n) : s } function trampoline(fn) { return function (...args) { let res = fn.apply(null, args) while (typeof res === 'function') { res = res() } return res } } const num = 1000000 const trampSum = trampoline(sum) const res = trampSum(num) console.log(res)
@kotxiiith776
@kotxiiith776 3 жыл бұрын
Когда пытаешься написать хороший код на плохом языке...
@spappinventor2850
@spappinventor2850 3 жыл бұрын
А почему в правой функции не перехватить Exception и вернуть Nan ? И вообще если надо вернуть хорошо или плохо, то надо функции немногие варианты плохо и превратить в одно возвращаемое плохо!
@nurk9928
@nurk9928 3 жыл бұрын
Тут ещё нужно смотреть на ЯП. В golang, на котором в основном я пишу код, левый вариант лучше. При < 0 возвращается ошибка, которую необходимо обработать. При невалидных входных данных (< 0) функция уйдёт в бесконечную рекурсию.
@nurk9928
@nurk9928 3 жыл бұрын
Я снова не досмотрел видео и написал комментарий. Прошу прощения.
@protiv_bio
@protiv_bio 3 жыл бұрын
Хм, здесь что-то очень специфичное относительно языка, что требует объяснения. Я не понял, как проверка на отрицательное число в итоге приводит к разным результатам в еще двух случаях?
@VorobyevAlexander
@VorobyevAlexander 2 жыл бұрын
Мне кажется, если уж дорабатывать левый код, то правильнее было бы бросить исключение в случае не валидных входных данных. это так же позволит разделять исключения "общие" и относящиеся к бизнес логике задачи.
@Uni-Coder
@Uni-Coder 3 жыл бұрын
Услышав про мусор, ожидал услышать что-нибудь про контракты. Хотя не знаю, есть ли какое-то подобие контрактов в JS.
@АндрійБілецький-о2ж
@АндрійБілецький-о2ж 3 жыл бұрын
Отличное видео, побольше бы таких.
@TheKwadriga
@TheKwadriga 3 жыл бұрын
Мне кажется, что вторая функция тоже плохая. Да, работать она будет предсказуемо, но каждый раз, когда на вход попадает что-то кроме целочисленного значения >= 0 ждать, когда переполнится стек - это так себе идея. С точки зрения производительности это очень плохо. И я не уверен, что она будет работать одинаково на разных ОС и разных архитектурах железа (я, как программист, вообще не должен об этом думать - лучше просто написать функцию так, чтобы: 1) никакого переполнения стека не происходило вообще никогда, 2) было не важно, на какой платформе это будет запускаться. Чтобы этого добиться, пред условием выхода из рекурсии (n === 0), нужно добавить проверку корректности входящих значений. Не уверен, что это корректный код на js, но будем считать, что это некий псевдокод: if (typeof n !== integer || n < 0) { throw new Exception('Invalid parameter'); } if (n
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
Стек на js это условности. Не надо путать со стеком на си. Переполнение стека в js безопасно в силу гарантий самого языка. Что касается производительности то преждевременная оптимизация - зло. В данном случае переполнение стека очень недорогое поведение. И не надо забывать что это исключительная ситуация, если в программе высокие шансы получить вместо данных мусор, то надо разбираться с дизайном системы в целом.
@TheKwadriga
@TheKwadriga 3 жыл бұрын
@@S0ERDEVS Ага, т. е., в данном случае можно считать, что сам язык делает эту проверку входящих значений. Ну да, тогда никакого смысла нет проверять самостоятельно и вторая функция вполне удовлетворительна.
@ANTGPRO
@ANTGPRO 3 жыл бұрын
@@S0ERDEVS Причем здесь JS к проверке стэка вызовов? не позорься))
@AlexM-gn7bp
@AlexM-gn7bp 3 жыл бұрын
Отличное видео. Побольше бы именно такого контента
@avecoder
@avecoder 3 жыл бұрын
Почему ты не продаешь курсы по JS? Разбогател бы, уехал жить на остров, может даже и на свой :)
@kirillriman3611
@kirillriman3611 3 жыл бұрын
Мудро и познавательно
@СергейНовожилов-я6я
@СергейНовожилов-я6я 3 жыл бұрын
Расскажи, пожалуйста, как бы ты построил SPA веб приложение, в котором много связей между отдельными компонентами (например чекбокс на одной странице должен менять состояние элементов на другой). Некоторые данные используются сразу несколькими компонентами. Или хотя бы подскажи, где можно почитать про решение конкретных архитектурных проблем.
@enkryp
@enkryp 3 жыл бұрын
Посмотрите в сторону архитектуры Flux и хранилищ типа NgXs/Redux
@redeyes256
@redeyes256 3 жыл бұрын
Если некоторые данные используются разными компонентыми, то их можно хранить в виде стейта в общем компоненте прородителе, это если без всяких state management. По хорошему конечно же завести глобальное хранилище состояния приложения, например вышеупомянутый редакс, и из него получать конкретные курски стейта в разных компонентах. "например чекбокс на одной странице должен менять состояние элементов на другой". Это штуку тоже можно редаксом решить, просто изменения состояния чекбокса должно запускать определенный actionCreator, который будет менять глобальное состояние, от которого и будет зависеть тот самый компонент, который вы хотите менять чек боксом, и не важно в каком месте, потому что как только тот кусок состояния в редаксе, от которого он зависит, изменится, он автоматически перерисуется. Так же черед редаксовские actionCreator's можно отправлять ассинхронные запросы на сервер, если подключить redux-thunk, что тоже добавляет удобства. Чтобы понять что к чему в редаксе потребуется определенное время и пытливость ума, но если есть время и желание, то это решение должно вам помочь.
@surenkirakosyan5244
@surenkirakosyan5244 3 жыл бұрын
А почему просто не выбрасить исключения вместо оператора return? Очевидно же, что программист хотел избежать ненужных операций, которые приводили бы к ошибке "Maximum call stack size exceeded", но выбрал неудобный путь.
@NarkotikAsd
@NarkotikAsd 3 жыл бұрын
Спасибо!"!!!!!!!!!!!!!!
@111KriegeR111
@111KriegeR111 3 жыл бұрын
Посмотрел ролик и вспомнил, почему у меня горит от языков с динамической типизацией. Спасибо за видео.
@ВіталійКостак-ю9в
@ВіталійКостак-ю9в 3 жыл бұрын
Круто... Подписался
@ovanse
@ovanse 3 жыл бұрын
Джун: ничерта не понятно, но очень интересно 😂
@covid-2284
@covid-2284 3 жыл бұрын
Не думаю что я - джун. Я никто вообще... Но что, зачем, как и почему - мне понятно. Думаю тут в принципе ничего такого нет. Ну разве что гуманитарий запутается...
@computercomputer3293
@computercomputer3293 3 жыл бұрын
@@covid-2284 гуманитарий. Не запутался :)
@AlexRuban...
@AlexRuban... 2 жыл бұрын
в java действительно нужно === поставить?)))
@sovrinfo
@sovrinfo 3 жыл бұрын
Спасибо за ролик!
@ХаимМохави
@ХаимМохави 3 жыл бұрын
А ещё будет?
@ac130kz
@ac130kz 3 жыл бұрын
не смотря дальше первой части видео, могу сказать, что правильным будет второй код, НО с добавленным типом
@ianpaddington3187
@ianpaddington3187 3 жыл бұрын
а че бы не проверить тип параметра? явное лучше, чем неявное. в правой функции отсутствие побочных эффектов достигается за счёт того, что нет условия ‘n < 1’. всем программистам в команде нужно знать и держать в голове, что доп проверка приводит к сайд-эффектам.
@johnstrayk5208
@johnstrayk5208 3 жыл бұрын
Спасибо, расширили сознание.
@МаксимХвостов-м1й
@МаксимХвостов-м1й 3 жыл бұрын
Еще один интересный метод реализации - через построение бесконечного списка - обращение к нему производится только по индексу поэтому получается "мусор на входе - исключение на выходе". Пример на Haskell: factorial = scanl (*) 1 [1..] :t factorial -- Тип списка: factorial :: [Integer] factorial !! (-1) -- Обращение к списку: *** Exception: Prelude.!!: negative index factorial !! 3 -- 6 factorial !! 300 -- Большое число не буду сюда копировать. factorial !! 30000 -- Очень большое число.
@anotherone3641
@anotherone3641 3 жыл бұрын
расскажи лучше как реализовать стратегию мусор на входе - оффер на выходе. да всем (кроме интервьюеров на техническом собесе) похер какую стратегию реализует кусок говнокода на жабаскрипте. потому что уже при разработке самого интерпретатора жабаскрипта изрядно наговнокодили. С нетерпением жду следующего выпуска: как писать расово правильный код на встроенном в микрософ офис висуал барсике.
@romanradchenko3569
@romanradchenko3569 3 жыл бұрын
Стратегия 2 интересна, но также не до конца понятно какое должно быть поведение в месте где вызывается функция, тогда в таком месте должен быть try/catch.
@ANTGPRO
@ANTGPRO 3 жыл бұрын
Конечно. Обе функции бездарные, с точки зрения JS. Но этот приколист еще убрал проверку на отрицательный аргумент в надежде на exception. Трэш.
@Iskandarko
@Iskandarko 3 жыл бұрын
«Мусор на входе, мусор на выходе» - полицейский участок
@ДмитрийРоманенков
@ДмитрийРоманенков 3 жыл бұрын
А я правильно понимаю, что правый вариант функции от -1 будет крутить рекурсию пока не кончится стек? Это тоже как то не слишком здорово выглядит.
@TwilightSun32
@TwilightSun32 3 жыл бұрын
он очень быстро кончается в жабаскрипте. можно в браузере проверить, падает почти мгновенно. там просто ограничение на глубину вызова стоит, оно не ждёт фактического окончания памяти
@enkryp
@enkryp 3 жыл бұрын
В этом и есть главная идея видео - для стандартного разработчика код справа выглядит некорректным, хотя в определённой перспективе он лучше левого.
@ДмитрийРоманенков
@ДмитрийРоманенков 3 жыл бұрын
@@enkryp Ну да, в этом смысле понятно, что правый вариант лучше. Просто они оба плохие)
@Poloskun4ik
@Poloskun4ik 3 жыл бұрын
А для чего вообще подобный кусок кода используется?
@kalobyte
@kalobyte 3 жыл бұрын
вычиляет факториал - бесполезный абстгактный пример из мудематики, когда хотят показать программирование
@Poloskun4ik
@Poloskun4ik 3 жыл бұрын
@@kalobyte да судя по комментам я тут один не понимаю всего праздника жизни)))
@kalobyte
@kalobyte 3 жыл бұрын
​@@Poloskun4ik ну это классика же, когда начинают рассказывать про программирование в быдловузе и вместо конкретных кусков кода показывают непонятный факториал если быть точнее, то факториал это классика примера рекурсии типа показать, что функция может вызвать сама себя но за столько десятилетий никто не додумался придумать боле менее наглядный пример рекурсии нежели вычисление бесполезного ряда чисел а я таки один раз использовал рекурсию, что упросило и сократило мой код аж в 3 раза по визуальному объему я аж сам с себя нереально проперся
@ANTGPRO
@ANTGPRO 3 жыл бұрын
@@kalobyte ахахах, молодец
@roma3880
@roma3880 3 жыл бұрын
Смотрю , очень проявляется «синдром Одина» , это - хорошо )))
@yuriik.6711
@yuriik.6711 3 жыл бұрын
услышал про рекурсию - закрыл видео
@GenaTolstij
@GenaTolstij 3 жыл бұрын
О. Хорошо однако, элементарнейшие вещи но хорошо
@skiu9578
@skiu9578 3 жыл бұрын
Это особенность джаваскрипта, который может вернуть что угодно, а для ошибки у него аж четыре значения, включая null, которые могли бы быть чем-то одним, если бы было различие между значением переменной и состоянием программы. Null и Error можно понять зачем. Но NaN? Немогу сделть, и у меня для этого есть специальное слово. Переменной не присвоено значение, и для этого вот еще одно слово. Null это значение переменной, нет никакой ошибки. Лол.
@АртП-м7ж
@АртП-м7ж 3 жыл бұрын
Меня бы начальник убил бы нахер, если бы я сидел и перебирал все возможные некорректные значения подобных функций. Инвестор деньги немножечко не для этого выделяет всё же.
@АлексейКомский
@АлексейКомский 3 жыл бұрын
Спасибо!
@user-dz3bi7qt6i
@user-dz3bi7qt6i 3 жыл бұрын
Отличное видео!
@ПавелИванов-м5ю
@ПавелИванов-м5ю 2 жыл бұрын
А потом я должен без обработки warning ни протестировать толком, ни ошибку найти , ни флага не увидеть что ситуация уже вышла где-то за край контроля , потому что никакой генерации warning incorrect incoming data в логах чтобы сразу понять где мина -- не будет в принципе . Считаю обе функции незаконченными в аспекте логики и рациональности именно применения как функции .
@dmitriysheyko1035
@dmitriysheyko1035 3 жыл бұрын
спасибо
@alexabees682
@alexabees682 3 жыл бұрын
А ещё стратегию мусор на входе и мусор на выходе используют на футбольных стадионах
@СергейПанов-з3ц
@СергейПанов-з3ц 3 жыл бұрын
Java программистам не понять проблем Javaскриптизёров...
@АртП-м7ж
@АртП-м7ж 3 жыл бұрын
javascript на входе - мусор на выходе!
@romartynromashka
@romartynromashka 3 жыл бұрын
10461 -> максимальное число, с которым получаем Infinity, а не ловим исключение
@I_am_Alan
@I_am_Alan 3 жыл бұрын
Респект!
@sevsxes
@sevsxes 3 жыл бұрын
Сразу видно, автор видел много мусора на входе и на выходе. : )
@arctan-k
@arctan-k 3 жыл бұрын
if (n < 0) throw new IllegalArgumentException();
@_bogie_
@_bogie_ 3 жыл бұрын
Главная ошибка что код написан на js
@javavlogger9409
@javavlogger9409 3 жыл бұрын
Название видео не соответствует его содержимому. Хороший код - это про правильные имена переменных, форматирование, грамотную архитектуру, принципы SOLID и т. д. А тут просто разбор ошибок в функции.
@enkryp
@enkryp 3 жыл бұрын
Судя по всему, вы пропустили (промотали) видео на 1:23-2:00
@andreysakharov6210
@andreysakharov6210 3 жыл бұрын
Да
@Олександр-ы4э
@Олександр-ы4э 3 жыл бұрын
Оба варианта ужасны .
@Nikrogan
@Nikrogan 3 жыл бұрын
Сяп чисто коммент для продвижения Ы
@AJIagguH
@AJIagguH 3 жыл бұрын
7:12
@Провиденс-х1е
@Провиденс-х1е 3 жыл бұрын
На самом деле все просто: Хороший код - "_" в названии приватного поля Плохой код - без "_" Не путай!
@alexanderskusnov5119
@alexanderskusnov5119 3 жыл бұрын
плохая демонстрация - на чёрном фоне.
@qwertymangames1800
@qwertymangames1800 13 күн бұрын
Максимально глупый пример. Кто будет делать в рекурсии две ветки if? Ещё и не использовать хвостовую рекурсию позволяя получать исключения переполнения стека. Просто зачем? Ведь все знают про хвостовые рекурсии, это уже стандарт.
@yaroslavishchuk
@yaroslavishchuk 3 жыл бұрын
+
@alekseyshibayev5243
@alekseyshibayev5243 3 жыл бұрын
Если использовать нормальный язык программирования, например java, то этой ерунды не будет, из-за типизации. Разве что выше надо будет проверить что там не отрицательный int или null, если большой integer. А так вам приходится самим компилятором быть.
@jeromewicks3896
@jeromewicks3896 3 жыл бұрын
а если использовать еще более нормальный язык, чем java, а именно kotlin, то и проверок на null не будет)
@KnowingCat
@KnowingCat 3 жыл бұрын
обе ф-ции говно, т.к. не прописан тип входящего параметра и тип выходящих данных
@ANTGPRO
@ANTGPRO 3 жыл бұрын
Красава. Это правильный ответ.
@ANTGPRO
@ANTGPRO 3 жыл бұрын
Либо сделать Number.parseInt / Number.parseFloat.
@WGDev
@WGDev 3 жыл бұрын
А тесты где?! Где тесты, Билли?!
@ANTGPRO
@ANTGPRO 3 жыл бұрын
Мдааааааа
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
С удовольствием посмотрю твои видосы про технологию разработки, когда ты наконец-то поставишь WSL и VSCode, и закончишь пересказывать документацию на язык.
@S0ERDEVS
@S0ERDEVS 3 жыл бұрын
Блин, так ты инфоцыган kzbin.info/www/bejne/onPRnGCwZZmsjc0
@ANTGPRO
@ANTGPRO 3 жыл бұрын
@@S0ERDEVS ахаха, чел, зайди на канал и посмотри про wsl, ты опять выдал что-то неадекватное. Мои ученики давно его поставили и забыли. У тебя не получилось? :D
@ANTGPRO
@ANTGPRO 3 жыл бұрын
@@S0ERDEVS я продаю свои знания за деньги, а ты так и не понял как написать рекурсию) такой трэш нес про функции, про JS, про стэк, ахаха разберись с базой, чел.
@ANTGPRO
@ANTGPRO 3 жыл бұрын
@@S0ERDEVS можешь у меня купить курс, будешь шарить за стэк и рекурсию :D
@MaksimK-l4k
@MaksimK-l4k 3 жыл бұрын
Очень длинное видео.
@sixaxisization
@sixaxisization 3 жыл бұрын
Рыдая, с болью в душе, Я задаю всего лишь один вопрос - И ЧТО ТЕПЕРЬ ВСЁ ПЕРЕПИСЫВАТЬ? аааа!!! зачем Я Вас увидел? :) Спасибо!
@leshiq4214
@leshiq4214 3 жыл бұрын
Обязательно посмотрю это видео, когда мне понадобится знание факториалов. К сожалению, их не было в моей школьной программе (закончил в 2004), и во вступительных тоже, и даже на выш мате первых двух лет института по экономической специальности. И я ни разу не слышал об их практическом применении и не сталкивался с ними вообще. Я даже не знаю, что это такое - факториал.
@chelbes9509
@chelbes9509 3 жыл бұрын
Факториал часто встречается в комбинаторике
@vetalmontolio8075
@vetalmontolio8075 3 жыл бұрын
Видео не о факториале
@ДмитрийУшаков-л6ж
@ДмитрийУшаков-л6ж 3 жыл бұрын
Факториал - произведение ряда натуральных чисел от 1 до n. Это не сложная штука и еë часто используют для, например, демонстрации разницы между рекурсивными функциями и циклических алгоритмов.
@leshiq4214
@leshiq4214 3 жыл бұрын
@@ДмитрийУшаков-л6ж, спасибо, конечно. Но смысл моего комментарий был в том, что мне это знание не требуется для решения задач бизнеса, за которые мне платят(разработка серверной части мобильных приложений).
@leshiq4214
@leshiq4214 3 жыл бұрын
​@@vetalmontolio8075, согласен. Но тяжело воспринимать информацию, когда в примере используется что-то, о чем ты не знаешь. Это примерно также, как учить слова иностранного языка, используя не их перевод, а их значения на другом иностранном языке.
@norzqq
@norzqq 3 жыл бұрын
Из этого ролика я узнал в каком стиле я проектирую и пишу все свои функции - мусор на входе, мусор на выходе :peepo_cry:
@nazarii.lazarchuk
@nazarii.lazarchuk 3 жыл бұрын
да и сам код тоже мусор XD
@zakzemsky4199
@zakzemsky4199 3 жыл бұрын
@@nazarii.lazarchuk мусор внутри 😉
@alexmanspb-2125
@alexmanspb-2125 Жыл бұрын
😂
@dirtyhandz
@dirtyhandz 3 жыл бұрын
Спасибо!
@VladykaVladykov
@VladykaVladykov 3 жыл бұрын
Интересная стратегия: мусор на входе, мусор на выходе. Хмм, надо подумать о внедрении
@mamkinproger
@mamkinproger 3 жыл бұрын
Я уже пакеты с мусором поставил как делает автор) А если серьезно - очень полезное видео) Заставляет задуматься и понять, что мой код - го*но...
@КириллЧе-я5ы
@КириллЧе-я5ы 3 жыл бұрын
Паттерн стратегия - поменяйте алгоритм в процессе работы на мусорный...
@arkadysm
@arkadysm 3 жыл бұрын
Вообще-то мусор на входе, ошибка на выходе, хотя я тебя понял)
@Alexander-lp2qy
@Alexander-lp2qy 3 жыл бұрын
Мусор ломится в квартиру
@drVatman
@drVatman 3 жыл бұрын
Мне кажется, тут уже недостаток джаваскрипта. Слева более понятная с точки зрения алгоритма функция (без специфики языка), но её поведение получается более сложным из-за отсутствия строгих типов. Наверное, хорошим тут был бы третий вариант, с проверкой типа, если мы берем общий случай, а не конкретно джаваскрипт.
отомстил?
00:56
История одного вокалиста
Рет қаралды 7 МЛН
小天使和小丑太会演了!#小丑#天使#家庭#搞笑
00:25
家庭搞笑日记
Рет қаралды 11 МЛН
Программист, ты должен писать плохой код
21:51
SOLIDный чистый код на простых примерах
46:58
Александр Бармин
Рет қаралды 8 М.
Как писать чистый код
25:56
Vlad Mishustin
Рет қаралды 24 М.
КОД КАК У СЕНЬОРА. РЕФАКТОРИНГ
22:59
ITentika Online
Рет қаралды 66 М.
Плохой vs. хороший код / wtf is clean code
11:50
отомстил?
00:56
История одного вокалиста
Рет қаралды 7 МЛН