Comments 95
Никогда не ставьте кофе так близко от рабочего ноутбука, любая чашка однажды опрокинется. Минимум на расстоянии вытянутой руки. Лучше, на другом столе.
- Двоичная система счисления
- Типы переменных
- Логические операции
- Блок-схемы
- Циклы
- Функции
- Рекурсия
Двоичная система счисления
а можно узнать почему?
не программист, но со всем остальным согласен
а как работает интегральная схема процессора или трансформатор в блоке питания надо знать?
п.с. я не спорю, просто интересно знать более конкретное обоснование
Если же мы возьмём и воспользуемся в алгоритме 128 битными переменными, то в лучшем случае всё ухудшится в 4 раза
То есть сложность не изменится :)
Константа резко поплывёт. Обычно одна инструкция за такт (+\-, иногда могут несколько уместиться), а тут резко все действия становятся медленнее. И нам ещё повезло что современный процессор похож на многоленточную машину тьюринга, во времена одноленточной задавшему вопрос рассмеялись бы в лицо!
Ну, и плюс, моё, личное — я не люблю поверхностную информацию. Она очень часто ведёт к неправильным выводам. Поэтому знание бинарки, как и базового устройства железа считаю обязательными.
в 3-х bool переменных можно хранить 3 единицы информации, а программист должен знать, что это 8 единиц информации.
это конкретно bool, про что уже говорит пункт №2
Так сразу в /dev/null, чего мелочиться :)
Но по факту, все равно один bool занимает 8 бит в памяти.
Не факт. Зависит от компилятора.
Но для ХРАНЕНИЯ данных на внешних носителях экономичней всего хранить логические переменные именно в БИТАХ, но этим как правило брезгуют — лишняя морока ради экономии 128 байт на логических переменных из сотен килобайт сопутствующих данных. Шевелится начинают когда выигрыш более 50% или объём данных находится на грани, чтобы уложится в размер определённого слота и т.д.
И потом, следуя Вашей логике выходит, что и в степень двойку возводить лучше умножением чем сдвигом?
У Вас в профиле указано, что работа связана с МК и ассемблером… но почему-то мне страшно представить код после Вашей оптимизации.
Sorry за оффтопик. Если по теме, то я считаю, что обязательно нужно знать операции с фиксированной точкой.
В любом случае, работать с битами проще всего только в регистрах что и практикуется, но одиночное использование логической переменной очень не оптимально.
К тому же, понимание двоичной системы счисления даёт обьяснение таким странным магическим числам как 1024, 32768, 65535 и многим другим непонятным ограничениям(ограничение размера файла в 4Гб на FAT32, 32Гб на размер винчестера в старых системах...).
Так же, приноси понимание почему математическая операция 10.0/10.0 = 1.0 не имеет смысла и очень часто даёт ложный результат, почему к примеру не всегда получится прибавить 1 к числу вроде 1E+37. Всё это завязано на двоичную систему счисления чуть более чем полностью.
10 вещей, которые нужно знать начинающему программисту:
0. Двоичная система счисления
1. Еще FF всяких полезных вещей
Что прочесть в первую очередь?
системные программисты, которые пишут прикладные программы
Это уж слишком грубое упрощение.
Сразу учитесь структурировать и оформлять свои мысли, а параллельно сразу учитесь писать тесты.
https://android.googlesource.com/platform/art/+/e5f01223ae03b89767dc7881d75dca061121ee36%5E!/
Обход графа был реализован рекурсивным алгоритмом и вызвал то самое переполненение стека.
В функциональных языках многие вычисления естественно выражать в виде рекурсивных функций.
Т.к. транслятор может заменять хвостовую рекурсию на итерацию.
Никто и не говорит, что всегда. Но многие алгоритмы проще выражаются не хвостовой рекурсией, и здесь компилятор уже беспомощен. К примеру, такой "красивый", прямо математичный, факториал:
pure ulong factorial(uint n)
{
return n <= 1 ? 1 : n * factorial(n - 1);
}
Чтобы рекурсию сделать хвостовой, надо уже городить вложенную функцию или нечто иное.
factorial(x, fac) {
if (x == 1)
return fac;
else
return factorial(x-1, x*fac);
}
Вам нужна функция с одним параметром? Нет проблем:
tail_fac(N) -> tail_fac(N,1).
tail_fac(0,Acc) -> Acc;
tail_fac(N,Acc) when N > 0 -> tail_fac(N-1,N*Acc).
Теперь не подойдёт из-за наличия 2-х функций?
Тогда возьмите язык, в котором есть возможность задавать значения по-умолчанию для аргументов функции.
«Чтобы рекурсию сделать хвостовой, надо уже городить вложенную функцию...» — показал, как можно обойтись без вложенной функции
"… факториал по определению функция с одним параметром, а у вас два..." — привел пример с одним параметром и без вложенной функции
И всё равно мимо кассы.
Поэтому и попросил огласить весь список требований, а то создается впечатление(мозгами понимаю, что скорее всего ложное), что требования выдумываются на ходу.
Если один, другой варианты не подходят это означает, что существуют требования из-за которых варианты не подходят. Верно?
> Ваши оба примера как раз подходят под «нечто иное»
Согласен. Оба примера подходят под «нечто иное». Но, если последовать такому подходу, то нерекурсивное решение попадает тоже в категорию «нечто иное».
> Представьте себе, что вам нужна функция sin(x)…
Введите в область видимости функцию-обертку с нужным количеством аргументов.
> Единственный момент, с которым я не могу согласиться — «Тогда возьмите язык, в котором»
Подумайте, зачем придумали такое количество языков? И может ли это быть связано с тем, что некоторые языки не предназначены для решения некоторых задач?))
P.S. кстати, требований по поводу языка никто не предъявлял
> Определение «городить» было дано выше.
Подходят, по причине того, что дополнительные условия появлялись уже после приводимых решений.
Кстати, могли бы Вы процитировать определение «городить» во избежании путаницы?
> «Чтобы рекурсию сделать хвостовой» означает, что нерекурсивное решение не
> подходит вообще. Т.е. задача стояла сделать из общей рекурсии хвостовую.
> Избавление от рекурсии не решает задачу переделки ее в хвостовую. Но решает
> задачу «посчитать факториал». Которая уже была решена.
Простите, позднее время суток и самочувствие не дают понять «кто на ком стоял». Вы уж не серчайте))
> Я всего лишь хотел сказать, что заставлять пользователя давать функции
> непонятные константые аргументы несколько странно.
Замечательно)) Не хотите заставлять — не надо заставлять. Мы ведь совсем не об этом говорим, не так ли?
> А если ваша задача включат в себя множество подзадач, каждая их которых
> решается лучше всего на своем, отдельном языке?
Посмотрите на игрушки, в которых используется не один язык и каждый для своих задач. Без конкретных примеров задач, которые нужно решать говорить можно долго.
> Или даже так, вам дали проект, вы выбрали язык исходя из описания, работаете,
> пишете, и тут вдруг приходит дополнение, и там посчитать факториал нужно, а ваш
> язык даже хвостовую рекурсию не поддерживает (PHP какой-нибудь).
А давайте немного не так? Представим, что надо посчитать не факториал, а что-то «иное», что составляет львиную долю всего проекта. И тут оказывается, что при рекурсии экономятся ресурсы, а язык уже выбран.
> И никто не говорил, что у вас неудачный выбор языка.
Я снова обращаю внимание, что изначально не было требований к языку, но появились потом и уже с учетом новых требований оценивался предложенный мной вариант.
1. Что за двоичная система «счисления»? Если вы про булевую математику, но вроде как используется только в вентильной системе, до которой вас не допустят. И на секунду, процессор оперирует командами вроде как.
2. Может быть типы данных? А еще лучше разобрать разницу между статичной типизацией и динамической?
3. Логические операции… Это вообще что значит? Паттерны?
4. Другими словами UML.
5. Почему циклы? а почему не массивы?)
6. Какие функции? или вы имели ввиду методы? ну тогда это ведь зависит от фреймворка и парадигмы программирования.
Семь вещей, которые нужно знать начинающему программисту:
- Двоичная система счисления
- Типы переменных
- Логические операции
- Блок-схемы
- Циклы
- Функции
- Семь вещей, которые нужно знать начинающему программисту
Не знаю насчет блок-схем, но диаграммы классов и последовательности действий бывают нужны, поскольку они помогают быстро въехать в архитектуру проекта.
Вот смотрите сами: «научитесь писать тесты». Что это за совет вообще? Давайте я попробую давать подобные советы: «научитесь программировать без ошибок», «научитесь решать задачи», «научитесь писать код», «научитесь читать код». Ну вот! Теперь Вы на 100500 шагов впереди тех, кто этих советов не знает…
Научитесь решать задачи
Некоторые разработчики уверены в критической важности умения решать задачи, которое подразумевают написание кода, делающего то, что задумал разработчик. Среди этих людей — Васька Фёдоров, мой сосед, разработчик баз данных в Seventh April Systems. Он пишет: «Думаю, что лучший совет, который я могу дать начинающему разработчику — научиться решать задачи как можно раньше».
1. Написанный код с первого раза запустится с ошибкой.
2. Если он запустился без ошибки, значит он работает не правильно.
Научитесь думать абстрактно.
Учитесь проектировать Системы.
Учитесь управлять зависимостями.
Учитесь декомпозировать.
Учитесь писать читаемый код.
Изучите основные алгоритмы.
Учитесь упрощать все и везде, насколько это возможно.
Учитесь писать гибкий расширяемый код.
Познайте среду исполнения с ее возможностями и ограничениями.
Ну и авторитетная цитата: "Учиться, учиться и еще раз учиться!" В. И. Ленин.
Все это я к чему повествую? А к тому, что не менее важно уметь пользоваться знаниями! Навыки анализа задачи, поиска и сопоставления знаний нужно вывести на уровень условных рефлексов. А без алгоритмического мышления (способности строить алгоритмы) стать программистом (хорошим) очень сложно… Даже имея обширные знания в различных сопутствующих областях…
З.Ы.
Сейчас у меня работает девушка наподобие описанного студента… Зачатки навыка алгоритмизации у нее появились, когда я ей стал давать задачи на GO))) (комплимент этому ЯП)
Семь вещей, которые нужно знать начинающему программисту