Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя

Имеете ли вы картину в голове, которая помогает при решении задач по программированию (Венн диаграммы или что нибудь еще)?

Можете детально отрефлексировать процесс который происходит в голове во время решения задач и описать это словами?
ПрограммированиеМышление
Кайло Фернан
  ·   · 1,7 K
Веб-разработчик, геймер, специалист по этике  · 26 мар 2022
У каждого разработчика ПО интуиция своя, это часть процесса становления профессионалом.
Учтите, что "имеете ли вы картину в голове" и "детально отрефлексировать процесс … решения" это два разных вопроса. Но я, похоже, отвечу сразу на оба.
Классический подход, судя по тому, как я читал об этом у других разработчиков в их книгах и блогах - это абстрагирование и декомпозиция при помощи идеи о "черном ящике". Я пользуюсь таким же интуитивным подходом.
Допустим, перед нами задача классификации. Есть файлы картинок, нужно рассортировать их по папкам: картинки с котиками, картинки с пёсиками, картинки с людьми и все остальные. Допустим.
Значит, представляем всё наше решение в виде чёрного ящика, "чёрного" в смысле "непрозрачного". На ящике кнопка. Когда мы нажимаем на кнопку, задача решается. По условию задачи, мы манипулируем файловой системой компьютера, значит, рядом с ящиком лежит наш жёсткий диск, к которому ящик имеет доступ: соединён проводом.
Теперь ставим перед собой важнейший вопрос: есть ли уже готовый такой ящик? То есть, решил ли кто-то уже такую задачу или нет? Если есть, мы просто идём и берём готовый. Обычно на всю задачу целиком готовых решений нет, поэтому мы открываем ящик и начинаем думать, какая у него должна быть начинка - превращаем ящик в "белый", прозрачный.
Какие самые крупные шаги можно представить в решении нашей задачи? Например, можно разбить задачу на такие шаги:
  1. Прочитать файловую систему и получить список файлов.
  2. Рассортировать список файлов по категориям, получив набор отдельных пачек файлов.
  3. Сохранить полученные отдельные пачки файлов обратно в файловую систему в отдельные папки.
Каждый из этих шагов мы представляем в виде нового "черного ящика" с кнопкой. Эти ящики стоят в ряд и соединены друг с другом. Первый ящик должен выдавать список файлов, который передаётся в центральный ящик, который выдаёт пачки файлов, которые передаются в последний ящик. Это называется "поток данных", data flow. Первый и последний ящики соединены проводами с жёстким диском - взаимодействие со сторонней аппаратурой это побочные эффекты, side effects, выпадающие из потока данных. Для того, чтобы решить задачу, нужно нажать на кнопку на первом ящике, потом на втором, потом на третьем. Это называется "поток управления", control flow.
На этом этапе оказывается, что мы снова смотрим на "черные ящики" и процесс декомпозиции повторяется до тех пор, пока мы не дойдём до ситуации, когда все ящики, оставшиеся для нас чёрными, являются уже готовыми, кем-то для нас написанными. В этот момент задача решена, её осталось только корректно записать на языке программирования. Каждый ящик, неважно, чёрный или белый, оформляется в виде модуля на языке программирования - функцией, классом объектов, собственно модулем или чем-то ещё. В любом языке программирования есть базовый набор функций, доступных всегда - стандартная библиотека - и они и являются самыми маленькими доступными для нас чёрными ящиками. Мы как разработчики не задумываемся больше о том, как они работают, мы просто полагаемся на то, что они работают.
Этот процесс решения задач называется "сверху вниз". Популярной альтернативой ему является процесс решения "снизу вверх". В этом случае мы заранее собираем все "черные ящики", доступные нам, в кучу, и как из конструктора, собираем из них всё более и более крупные шаги решения задачи, пока полученный конструкт не будет решать всю задачу целиком. Сборка из маленьких ящиков ящики крупнее называется абстрагированием.
Преимущества подхода "снизу вверх" в том, что на каждом этапе полунаписанный код можно выполнить, и он что-то будет делать. Так упрощается тестирование. Недостаток подхода "снизу вверх" в том, что мы рискуем переусложнить решение. Полученный конструкт, возможно, будет делать не только то, что нам нужно по условию задачи, а что-то ещё. Не всегда мы можем позволить себе неоптимальное решение.
Преимущества подхода "сверху вниз" в том, что мы гарантированно решим только то, что от нас требуется, а набор самых маленьких чёрных ящиков нам всё равно виден. Получается, что у нас просто больше информации для создания корректной архитектуры. Однако, мы сможем запустить своё решение только когда оно будет полностью собрано.
В реальной разработке ПО при решении задач используется комбинация из абстрагирования и декомпозиции.
Концепция "черного ящика" настолько полезна, что у нас есть целый класс языков программирования под названием Lisp, и парадигма "визуального программирования", например, в Blueprints внутри Unreal Engine. 
На лиспах мы программируем буквально синтаксические деревья разбора, которые в других языках традиционно создаются компилятором автоматически на основании нашего исходного кода. 
Blueprints же буквально выглядит как ящики, соединённые друг с другом потоками данных и контроля:
Я полностью допускаю, что у каждого разработчика ПО своя интуиция и свои абстракции в голове. Более того, я считаю, что не нужно пытаться впихнуть чужие абстракции в свою голову. Однако, насколько я понимаю, вот такое представление о программе является самым распространённым среди профессионалов. Просто не забывайте, что оно не имеет ничего общего с тем, что реально происходит в железе внутри компьютера, на то это и абстракция.
Увлекаюсь математическими проблемами.  · 16 мар 2022
Мои старшие брат и сестра постоянно рисовали в школьные годы всеми красками. Я рос среди их картин и это усилило мое мышление на основе зрительного представления. В само программирование я только начинаю входить, но есть два... Читать далее