Computer Science или что должен знать программист? -3


Программисты бывают разные. Мобильные разработчики на Kotlin и Swift, веб-программисты, использующие PHP, Python, Ruby, хардкорные электронщики на Си и Assembler. Главным их отличием является сфера, в которой они работают и используемый язык. Однако не редки случаи, когда, например, веб-разработчики уходят в mobile, электронщики в gamedev и т.д. А конкретно язык программирования вообще можно переучить за пару месяцев. Пропорции условны, а границы размыты. Языки и технологии меняются, и если всё так подвижно и непостоянно, что же объединяет всех этих людей? А объединяет их умение программировать в целом, не зависимо от языка, платформы и технологии...и знание английского языка, пока не поздно учи английский (вставка из «Криминальное чтиво»)

Умение же программировать складывает из практического навыка написания программ и теоретической базы из различных областей Computer Science. Какие алгоритмы нужно знать программисту, нужно ли ему разбираться в компьютерах, системах счисления, делить в уме столбиком и что вообще должен знать программист в широком смысле этого слова. На эти вопросы вам сегодня постарается ответить Макс - один из автора YouTube-канала PyLounge. Поехали!

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

Алгоритмизация (в целом). Суть в том, что не нужно заучивать реализацию чужих алгоритмов, а стараться развивать своё алгоритмическое мышление, чтобы ты сам мог составлять алгоритмы. Декомпозировать задачу и выявлять нужную последовательность действий. Развить эти навыки можно решая задачи и разбирая готовые алгоритмы, а не заучивая их. Кстати у нас на канале есть ролик «Как решать задачи по программированию». Ознакомьтесь, если интересно.

Оценка сложности алгоритмов. Да, да. Это то самое большое О. Кроме него есть ещё Тета и Омега, но в принципе можно обойтись и просто О-большим.  Действительно важно хотя бы примерно прикидывать временную сложность алгоритма. Нужно понимать какой участок кода тормозит всё твою программу, почему O(n^2) хуже, чем O(n*log(n)), как следует переделать код чтобы добиться этого O(n*log(n)) и почему вот так лучше вообще не делать.

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

Кодировки - UTF-8, Windows-1251, ASCII и т.д. Очень многие программисты мучаются с различными проблемами, связанными с кодировками. Поэтому ориентируясь в этом хотя бы на минимальном базовом уровне, вы знатно облегчите себе жизнь.

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

Техники и приемы программирование. Стоит ознакомиться с понятием рекурсии, мемоизации, динамического, линейного программирования и тому подобного. А также понимать, что, где и когда (вставка Что, Где, Когда) лучше применять. Это поможет сделать твой код гораздо эффективнее и качественнее.

Архитектура компьютера. Хотя бы примерно понимать, что такое память в компьютере, зачем нужна, какая быстрее и т.д. Почему копировать объект 1000 раз не самая лучшая идея, зачем нужно кешировать информацию и т.д. Также неплохо бы разобраться в особенности вычислений процессором, видеокартой. Как грамотно распоряжаться программными ресурсами. Да и вообще полезно знать, как и что там работает в этой коробке под столом.

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

Базы данных. Для backend'деров это отче наш. SQL, запросы, таблицы, связи один ко многим, 1 к 1, многие ко многим, миграции. Что такое реляционные базы, не реляционные. Где лучше какие применять и почему. Это тот раздел, без которого точно не обойтись.

Архитектура программного обеспечения. Ранее я упоминал, что недостаточно чтобы программа просто работала. Она должна работать эффективно. Эффективно не только в плане производительности. Важно уметь писать код качественно, чтобы его было легко сопровождать, расширять. Серьёзное программирование это сложный итеративный процесс, зачастую комодный. Поэтому качественно спроектированная программа сделает вашу жизнь и жизнь других разработчиков лучше. Тут приходится понимание построение архитектуры ПО и грамотное использование паттернов (шаблонов) проектирование (GoF, GRASP, Enterprise). Кроме того, не мешало бы овладеть общепринятыми практиками (SOLID, KISS, DRY и т.д.)

Устройство Сети. Весь мир потихоньку переезжает в онлайн. Поэтому было бы неплохо разбираться в том, как работает Интернет. Опять-таки на базовом уровне. Что такое протоколы, сокеты, DNS, IP-адреса, зачем оно всё нужно и как между собой взаимодействует.

Важная заметка. Математика, в частности логика, комбинаторика, дискретка тоже входит в Computer Science. Поэтому коротко. Математика - круто. Математика точно нужна, но не всем и не всегда. Вообще математика для программиста эта тема довольно обширная и холиварная, заслуживающая отдельного обстоятельного разговора. Поэтому сюда я её включать не стал. Однако держу в курсе.

Best practice. Наверное, Не совсем про Computer Science. Но мне кажется, необходимо ознакомиться как принято писать код именно на вашем языке/стеке. Программирование есть программирование. Но согласитесь, в каждом омуте водятся свои черти. Поэтому будьте добры играть по их правилам или не играть вовсе.

Под конец я очень хочу порекомендовать ознакомиться с книжкой Феррейра Фило "Теоретический минимум по Computer Science". Она коротенькая, но даёт отличное общее понимание всего того, что тебе пригодится (и не отправит начинающего в психушку, как, например, труды Кнута). В том числе в этой книге есть и совсем немного про тот самый матан. Настоятельно призываю ознакомиться. Опытных вряд ли заинтересует, а для новичков самое то.


Как ты понял не нужно идеально всё знать наизусть.  Достаточно разбираться в базовых понятиях, принципах и понимать, что, когда применять. Если ты понимаешь, что тебе нужно, но недостаточно глубоко знаешь это, всегда можно заглянуть в Интернет или справочник, спросить у кого-то. Когда ты выберешь специализацию, то будешь уже разбираться отдельных веща непосредственно на деле, когда коснёшься этого, предметно. Например, если решишь программировать ядро Linux, будешь подтягивать знания ОС и т.д.

Базовое понимание — это твой скелет. На которой в последствии ты будешь наращивать мясо из тонкостей, деталей и специфики.

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

В некотором смысле программирование похоже на рисование. Сначала у вас есть только чистый холст и материалы. Нужно использовать сочетание науки, искусства и ремесла, чтобы определить, что со всем этим делать. (с) Эндрю Хант (Andrew Hunt)

P.S. Есть также видеоверсия данной статьи. Кому интересно, welcome на YouTube.




Комментарии (17):

  1. Hivemaster
    /#24478602 / +5

    Заблуждения о Computer Science начинаются с упорного нежелания её переводить.

    P.S. Интервью у самого себя? Забавно.

  2. CoffinNail
    /#24478610 / -7

    Я как-то думал над объяснением работы компа. Так вот - логическая машина, созданная в этом мире человеками, это механизм работы/обработки цепочек или, что удобнее понять, списков. Программист имеет дело только со списками, основа которых просто линейная память. Код-обработчик - это алгоритм модификации списка данных, с которым он конкретно работает в этом месте. Вообщем-то, это всё объяснение всей глобальной компьютерщины.

    • nx4n
      /#24478898

      Есть конкретная ячейка памяти, что бы до неё добраться сразу не нужно проходить остальные. О чем Вы? Какой список?

      • CoffinNail
        /#24478956 / -3

        Нужно подумать прежде, чем спрашивать очевидное.

      • CoffinNail
        /#24479568

        А кто говорил, что нужно проходить остальные?

        • nx4n
          /#24481838

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

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

          • CoffinNail
            /#24481894 / -2

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

  3. Cheater
    /#24478894

    почему вот так лучше вообще не делать.

    Вызов функции во вложенном цикле это конечно дорого, но в предположении что о "func" ничего не известно и код однопоточный - вряд ли тут можно сделать как-то по-другому. Пример плохой.

    • Kirk1234
      /#24481744

      Можно запихнуть вложенный цикл в func(). К тому же, всегда есть альтернативный путь-путь бездействия

      • Cheater
        /#24484094

        Для этого надо доп. условие, что func() контролируется нами (не библиотечная). =)

        Но да, цикл надо внутрь функции если есть такая возможность

  4. 1Tiger1
    /#24481456

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

  5. webaib1
    /#24482354

    Первый же пример кода имеет О(1) время выполнения, т.б. постоянное и не зависит от длины входа, если конечно функция не стейтфул и ее время выполнения не зависит от количества предыдущих прогонов ;)

  6. Just_Blood
    /#24482974

    Есть глупенький вопрос, но здесь его задать как нельзя кстати.

    Стоит ли на пути к junior python backend developer начинать грузить себя computer science? Очень трепещущий меня вопрос. Лучше пока оставить это до получения работы/оффера или до изучения основных фреймворков, или до прямого столкновения с computer science, или лучше начать заранее (что займет дополнительное время до желаемой цели в виде оффера)? Очень хочется посмотреть, куда гуляют мнения в этом вопросе

    • 1Tiger1
      /#24483914

      Учите то что нравится. Сделайте какой нибудь pet-project, в процессе вы столкнетесь с 50% необходимого и изучите. Ещё 40% изучите если будете периодически интересоваться как сделать то что вы сделали лучше. На собеседовании людей будут интересовать как вы думаете, какой у вас есть опыт (проекты) , что применяли и знаете, а не сложность алгоритмов. Ну кто-то может и погоняет по базам или паттернам, ну помечаете себе что спрашивали, а вы не смогли ответить, и изучаете эти темы.

    • bay73
      /#24484470

      Это зависит от того, какой оффер хочется получить. Можно стремиться к Junior в условном Гугле, а можно пойти в какую-нибудь веб-студию. Я не знаю, где лучше зарплата будет, но требования на приёме будут сильно разными.

  7. CoffinNail
    /#24483076

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

    • 1Tiger1
      /#24483924

      А зачем себя "называть"? Это ведь тоже наклейка.

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