Pull to refresh

Comments 97

Правило, которое выучил я (навеяло заглавной картинкой):
Никогда не ставьте кофе так близко от рабочего ноутбука, любая чашка однажды опрокинется. Минимум на расстоянии вытянутой руки. Лучше, на другом столе.
И желательно, чтобы он был без сахара — когда вы его таки разольёте — будет проще отмывать.
Ваш совет реально полезнее всего, что написано в посте.
Вы когда-нибудь пили кофе по 20 000 рублей за чашку? И я пил. Ваш совет крайне полезен.
Буквально пару дней назад как менял клавиатуру на ноутбуке по этой причине.
Это был худший розыгрыш себя самого на первое апреля.
И перед собой тоже не стоит ставить — очень легко задеть рукой. Когда-то я у меня была такая привычка, но после нескольких инцидентов я научился ставить чашку далеко в стороне :)
Если уж очень хочется кофе или чая, то можно взять большую чашку с широким основанием. Я использую чашку объемом 800 миллилитров. Даже при поперечном ударе в верхнюю кромку она не переворачивется, в отличие от обычных чашек.
Семь вещей, которые нужно знать начинающему программисту:

  1. Двоичная система счисления
  2. Типы переменных
  3. Логические операции
  4. Блок-схемы
  5. Циклы
  6. Функции
  7. Рекурсия
Двоичная система счисления

а можно узнать почему?

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

п.с. я не спорю, просто интересно знать более конкретное обоснование
Ещё есть поля с флагами и операции над ними (установка, проверка, снятие)
А ещё знание двоичной системы нужно, чтобы понимать, почему 0.1 * 10 не равно единице.
Я про тот low level, который доходит до самого верха. Предположим что у нас есть алгоритм сортировки. Хороший алгоритм, все знают что у него логарифмическая сложность. Но есть один нюанс — эта сложность будет только если у нас переменная меньше либо равна разрядности процессора. Если же мы возьмём и воспользуемся в алгоритме 128 битными переменными, то в лучшем случае всё ухудшится в 4 раза, а скорее всего выползет квадрат. А теперь вопрос — как программист без знаний низкого уровня будет оптимизировать приложение когда упрётся в боттлнэк? Он может поставить больше серверов, но там вылезают эта же двоичная система, но приминительно к сетям. Ровно в тот момент когда для программиста заканчивается вся магия низкого уровня — приходит понимание. Что оптимизации, что хайлоада. Я бы не сказал что это ненужные знания, я соглашусь что они могут не пригождаться очень долго, возможно даже — никогда, но вот ровно до того момента пока есть запас производительности.
Если же мы возьмём и воспользуемся в алгоритме 128 битными переменными, то в лучшем случае всё ухудшится в 4 раза

То есть сложность не изменится :)
Так «в лучшем» же :)
Константа резко поплывёт. Обычно одна инструкция за такт (+\-, иногда могут несколько уместиться), а тут резко все действия становятся медленнее. И нам ещё повезло что современный процессор похож на многоленточную машину тьюринга, во времена одноленточной задавшему вопрос рассмеялись бы в лицо!
Новое слово в компьютерной науке!
Это азы работы компютера и, как по мне, их стоит знать как и историю своей страны (не из-за пользы). Так же, знание бинарки сильно позволяет экономить ресурсы. Ибо обычный человек думает, что в 3-х bool переменных можно хранить 3 единицы информации, а программист должен знать, что это 8 единиц информации.

Ну, и плюс, моё, личное — я не люблю поверхностную информацию. Она очень часто ведёт к неправильным выводам. Поэтому знание бинарки, как и базового устройства железа считаю обязательными.
в 3-х bool переменных можно хранить 3 единицы информации, а программист должен знать, что это 8 единиц информации.

это конкретно bool, про что уже говорит пункт №2
Пункт №2 заставит понимать, что это за тип. А не концепцию хранения и сортировки массивов из него.

Также мне кажется что нельзя до конца понять логические операции не зная бинарки… Поэтому и написал на первом месте — она мать всего (утрирую)
UFO landed and left these words here
Извиняюсь. Разумеется это ошибка в используемых мной названиях.
Архиватор сделать не проблема, проблема сделать разархиватор.
>> А то ведь можно было бы сделать прикольный архиватор, который сжимает любые данные до 1-го бита

Так сразу в /dev/null, чего мелочиться :)
А то ведь можно было бы сделать прикольный архиватор, который сжимает любые данные до 1-го бита. ;)

Так ведь уже три года назад.

Но по факту, все равно один bool занимает 8 бит в памяти. И три bool можно уместить в 8 бит минимум, и то через битовые маски. Так что в некотором роде комментатор прав.
Но по факту, все равно один bool занимает 8 бит в памяти.

Не факт. Зависит от компилятора.
Фиг там, в современных языках логическая переменная занимает одно машинное слово — используется тип INTEGER. С чем это связано? А банально с производительностью… современному процессору сложнее оперировать байтами — для этого ему нужно из кеша/памяти извлечь слово и отсечь всё лишнее — а это дополнительные операции и соответственно замедление работы. Ещё хуже — использовать для этого отдельные биты.
Но для ХРАНЕНИЯ данных на внешних носителях экономичней всего хранить логические переменные именно в БИТАХ, но этим как правило брезгуют — лишняя морока ради экономии 128 байт на логических переменных из сотен килобайт сопутствующих данных. Шевелится начинают когда выигрыш более 50% или объём данных находится на грани, чтобы уложится в размер определённого слота и т.д.
UFO landed and left these words here
Несколько не так, переменная типа BOOL это на самом деле INTEGER, который равен машинному слову используемой системы. т.е. нынче это 32/64 бита. Мало кто работает с BOOL как с отдельными битами т.к. из-за этого сильно страдает производительность и имеет смысл только для долговременного хранения состояния и в случае массовой обработки бинарных состояний(маски прозрачности изображений?). В целом, работать с битами процессору очень накладно, он умеет эффективно работать только группами бит по 32-64 за раз. А некоторые системы работают большими порциями — например по 1024 бита за раз(привет видеокартам и аналогичным числовым ускорителям) и им крайне накладно работать с одиночными битами.
Как-то я вас не понимаю. Операция по установке бита занимает от силы 3-4 такта процессора, для снятия 4-5. Слишком накладно для процессора это с fload/double работать, вместо fractional
И потом, следуя Вашей логике выходит, что и в степень двойку возводить лучше умножением чем сдвигом?
У Вас в профиле указано, что работа связана с МК и ассемблером… но почему-то мне страшно представить код после Вашей оптимизации.

Sorry за оффтопик. Если по теме, то я считаю, что обязательно нужно знать операции с фиксированной точкой.
Вы не учитываете что при этом если переменная не находится в кеше L1 нужно подтянуть её из оперативки, а это может занять уже до сотни тактов и очень неочевидно. И при этом процессор хоть из кеша хоть из оперативки вынужден читать словами, т.е. если надо где-то изменить один бит он читает 64/128 бит меняет их и ложит обратно. При этом операции с кешем могут затрагивать блоки гораздо большего размера — например страницу кеша в 64 байта… т.к. процессор/чипсет не умеет извлекать одиночные байты/слова и вынужден при операциях с данными оперировать объёмами кратными размеру страницы кэша, что в итоге выливается в очень много тактов простоя из-за таких простых операций, зато в отличие от бит он УЖЕ способен работать с числами с плавающей запятой гораздо быстрее — результат вычисления над числами с плавающей запятой появляется уже через 2..10 тактов. А в некоторых системах умножение матриц чисел 8x8 занимает 2..3 такта. По сравнению с этим, операции с битами выглядят крайне неэффективными.
В любом случае, работать с битами проще всего только в регистрах что и практикуется, но одиночное использование логической переменной очень не оптимально.
Основная форма представления данных в самых распространенных, на сегодняшний день, ВС. Сильно поможет «заглянуть под капот».
Она тесно связана с элементарными логическими операциями.
К тому же, понимание двоичной системы счисления даёт обьяснение таким странным магическим числам как 1024, 32768, 65535 и многим другим непонятным ограничениям(ограничение размера файла в 4Гб на FAT32, 32Гб на размер винчестера в старых системах...).
Так же, приноси понимание почему математическая операция 10.0/10.0 = 1.0 не имеет смысла и очень часто даёт ложный результат, почему к примеру не всегда получится прибавить 1 к числу вроде 1E+37. Всё это завязано на двоичную систему счисления чуть более чем полностью.
Правильно так:

10 вещей, которые нужно знать начинающему программисту:

0. Двоичная система счисления
1. Еще FF всяких полезных вещей
>>> 0bFF
  File "<stdin>", line 1
    0bFF
     ^
SyntaxError: invalid token
Можешь посоветовать книгу начинающему?
Что прочесть в первую очередь?
Вам для начала стоит определиться каким программированием вы хотите заняться. На вскидку могу определить три области, железячники, которые начинают с ардуино и продолжают на микроконтроллерах, системные программисты, которые пишут прикладные программы и веб разработчики, которые строят сайт. Это все очень грубые упрощения.
Вы описали очень интересные области. Если судить так, то вот вопрос: Что можете посоветовать для начинающего в области программирования, ну т.е. написание системных программ?
Начинающий в области программирования не будет писать системных программ.
Могу порекомендовать классику: Брайан Керниган, Деннис Ритчи. Язык программирования C.
Особенно полезно будет, если программировать под *nix.
системные программисты, которые пишут прикладные программы

Это уж слишком грубое упрощение.
Системы программисты пишут, как ни странно, системные программы, а прикладные программы, включая веб, пишут прикладные программисты.
Я не знаю в какой сфере вы хотите писать (может вы и сам еще не определились), но вкупе с литературой вашего направления рекомендую Стива Макконнелла — Совершенный код.
Сразу учитесь структурировать и оформлять свои мысли, а параллельно сразу учитесь писать тесты.
Для начала советуют изучить PHP. Но как я понял не мало важны и знания аппаратного обеспечения. Я хочу стать хорошим специалистом. Буду читать книги. Большое спасибо.
Ч.Петцольд — Код. Тайный язык информатики. Идеально для начинающего. Проверил лично.
Причем рекурсию надо знать, что бы потом бежать от нее подальше. Она хороша при обучении, алгоритмы с рекурсией красивы и как правило занимают немного строк кода. Но когда выясняется, что например алгоритм обхода графа падает при обходе реального графа с десятками тысяч параметров, приходит понимание, что алгоритмы из учебника в реальном мире спотыкаются о такие ограничения операционной системы, как размер стека.
К сожалению, об этом часто не задумываются даже очень опытные программисты. Как пример — недавняя проблема в компиляторе андроид, использовавшемся в миллионах телефонов по всему миру:

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);
}
Прошу прощение за форматирование
UFO landed and left these words here
«Огласите весь список, пжлста»(ц)
Вам нужна функция с одним параметром? Нет проблем:

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-х функций?

Тогда возьмите язык, в котором есть возможность задавать значения по-умолчанию для аргументов функции.
UFO landed and left these words here
Мы с Вами едины в непонимании))
«Чтобы рекурсию сделать хвостовой, надо уже городить вложенную функцию...» — показал, как можно обойтись без вложенной функции
"… факториал по определению функция с одним параметром, а у вас два..." — привел пример с одним параметром и без вложенной функции
И всё равно мимо кассы.
Поэтому и попросил огласить весь список требований, а то создается впечатление(мозгами понимаю, что скорее всего ложное), что требования выдумываются на ходу.
UFO landed and left these words here
> Не совсем понял, где тут были требования.
Если один, другой варианты не подходят это означает, что существуют требования из-за которых варианты не подходят. Верно?

> Ваши оба примера как раз подходят под «нечто иное»
Согласен. Оба примера подходят под «нечто иное». Но, если последовать такому подходу, то нерекурсивное решение попадает тоже в категорию «нечто иное».

> Представьте себе, что вам нужна функция sin(x)…
Введите в область видимости функцию-обертку с нужным количеством аргументов.

> Единственный момент, с которым я не могу согласиться — «Тогда возьмите язык, в котором»
Подумайте, зачем придумали такое количество языков? И может ли это быть связано с тем, что некоторые языки не предназначены для решения некоторых задач?))

P.S. кстати, требований по поводу языка никто не предъявлял
UFO landed and left these words here
> Верно. Они не подходят под ваше утверждение «А если ничего не городить».
> Определение «городить» было дано выше.

Подходят, по причине того, что дополнительные условия появлялись уже после приводимых решений.
Кстати, могли бы Вы процитировать определение «городить» во избежании путаницы?

> «Чтобы рекурсию сделать хвостовой» означает, что нерекурсивное решение не
> подходит вообще. Т.е. задача стояла сделать из общей рекурсии хвостовую.
> Избавление от рекурсии не решает задачу переделки ее в хвостовую. Но решает
> задачу «посчитать факториал». Которая уже была решена.

Простите, позднее время суток и самочувствие не дают понять «кто на ком стоял». Вы уж не серчайте))

> Я всего лишь хотел сказать, что заставлять пользователя давать функции
> непонятные константые аргументы несколько странно.

Замечательно)) Не хотите заставлять — не надо заставлять. Мы ведь совсем не об этом говорим, не так ли?

> А если ваша задача включат в себя множество подзадач, каждая их которых
> решается лучше всего на своем, отдельном языке?

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

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

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

> И никто не говорил, что у вас неудачный выбор языка.

Я снова обращаю внимание, что изначально не было требований к языку, но появились потом и уже с учетом новых требований оценивался предложенный мной вариант.
UFO landed and left these words here
Такая штука, как TCO поможет не упасть рекурсивному алгоритму.
Я дико извиняюсь, но:
1. Что за двоичная система «счисления»? Если вы про булевую математику, но вроде как используется только в вентильной системе, до которой вас не допустят. И на секунду, процессор оперирует командами вроде как.
2. Может быть типы данных? А еще лучше разобрать разницу между статичной типизацией и динамической?
3. Логические операции… Это вообще что значит? Паттерны?
4. Другими словами UML.
5. Почему циклы? а почему не массивы?)
6. Какие функции? или вы имели ввиду методы? ну тогда это ведь зависит от фреймворка и парадигмы программирования.
А вы программист?
Чисто для интереса — а вы на чем пишете?

Это язык, в котором нет двоичной системы счисления, нет "if" и нет функций. Зато есть паттерны, методы и фреймворки.

Ассемблер для машины Сетунь что ли?

Там много фреймворков, да

Вот тут я не уверен X) Вероятно, название не совсем подходит, но остальное — нет двоичной системы, нет функций или if, наверняка есть какие-то шаблоны-паттерны…

Семь вещей, которые нужно знать начинающему программисту:


  1. Двоичная система счисления
  2. Типы переменных
  3. Логические операции
  4. Блок-схемы
  5. Циклы
  6. Функции
  7. Семь вещей, которые нужно знать начинающему программисту
блок-схемы не нужны, для этого используется мозг
Только в очень простых случаях. Из-за эффекта «дверного проёма» есть огромные шансы упустить важные детали и по этой причине очень быстро закопаться в многочисленных недоработках, недодумках и банальной забывчивости.

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

UFO landed and left these words here
Честно говоря, я очень плохо отношусь к статьям подобного рода: «21 способ похудеть, лёжа на диване» или «35 мест, где должен побывать турист». То же касается программирования. Тут один совет: у человека должна быть голова на отведённом ею эволюцией месте, а конкретный способ организации своей деятельности он сам определит, исходя из конкретных условий работы и задач, которые нужно решать.

Вот смотрите сами: «научитесь писать тесты». Что это за совет вообще? Давайте я попробую давать подобные советы: «научитесь программировать без ошибок», «научитесь решать задачи», «научитесь писать код», «научитесь читать код». Ну вот! Теперь Вы на 100500 шагов впереди тех, кто этих советов не знает…
Я всё-таки попробую улучшить статью. Восьмой совет.

Научитесь решать задачи

Некоторые разработчики уверены в критической важности умения решать задачи, которое подразумевают написание кода, делающего то, что задумал разработчик. Среди этих людей — Васька Фёдоров, мой сосед, разработчик баз данных в Seventh April Systems. Он пишет: «Думаю, что лучший совет, который я могу дать начинающему разработчику — научиться решать задачи как можно раньше».
UFO landed and left these words here
Нужна статья — 45 вещей о которых не нужно писать)
Как-то преподаватель в университете озвучил мне 2 закона.
1. Написанный код с первого раза запустится с ошибкой.
2. Если он запустился без ошибки, значит он работает не правильно.
Пережитки времен императивщины и слабой типизации :)

Научитесь думать абстрактно.
Учитесь проектировать Системы.
Учитесь управлять зависимостями.
Учитесь декомпозировать.
Учитесь писать читаемый код.
Изучите основные алгоритмы.
Учитесь упрощать все и везде, насколько это возможно.
Учитесь писать гибкий расширяемый код.
Познайте среду исполнения с ее возможностями и ограничениями.
Ну и авторитетная цитата: "Учиться, учиться и еще раз учиться!" В. И. Ленин.

Вот с этим, пожалуй, соглашусь полностью.
У вас последний абзац переведен неправильно. Там смысл такой — что пишИте хороший код, который можно отдать другим на поддержку. И люди к вам потянутся. И работа будет. А если держаться за свое место и подминать под себя неподдерживаемый другими код — то перестанешь расти как профессионал.
Как-то уже давно, лет 8-10 назад, ко мне на работу устроился студент-отличник (в зачетке все пятерки). Он успорял, что много знает и что умеет программировать. На первый же вопрос, который я обычно задаю всем новичкам, он ответил (со знаком «минус»). Вопрос был таков: «Как наиболее просто узнать значение заданного бита в 16-разрядном слове?» Он написал функцию на ассемблере в >100 строчек кода, применив, наверное, весь знакомый математический аппарат — и это только для выделения заданного бита. На слово мне он не хотел верить, что я все это могу уместить в «одну строчку» кода на том же ассемблере)))))))))) Пришлось доказать))))) Работал он не долго — сами догадаетесь почему))) Потом он устроился в банк, в кредитный отдел… вскорости банк «лопнул» (и тут я закончил линию логических умозаключений))))))

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

З.Ы.
Сейчас у меня работает девушка наподобие описанного студента… Зачатки навыка алгоритмизации у нее появились, когда я ей стал давать задачи на GO))) (комплимент этому ЯП)
Нет) и криповалюты своей у меня нет) и Кати… и слава Богу)
UFO landed and left these words here
Only those users with full accounts are able to leave comments. Log in, please.