Computer Science | что читать/смотреть
Приветствую, давно хотел написать пост об изучения Computer Science, рассмотреть пару тем, рассказать об интересных уч.материалах. К тому же здесь превалируют русскоязычные уч. материалы, что достаточно редкая история(но об английском будет пару слов, без него, к сожалению, никуда).
Этот пост - последний вышедший на моем канале в телеге https://t.me/tobeprog (там об изучении программирования).
Какие варианты roadmap-ов по cs бывают
Кажется крайне позитивной идеей, перед началом любого подобного материала ссылаться на уже существующие roadmap-ы/планы изучения.
Пост о том как найти хороший roadmap/план изучения
Прямо оттуда пара примеров:
https://github.com/jwasham/coding-interview-university (англ.)
https://github.com/jwasham/coding-interview-university/blob/main/translations/README-ru.md (на русском)
John Washam имел достаточно успешную карьеру, но у него была мечта - попасть в гугл. Его отделяло от нее отсутствие образования и знаний в сфере computer science, собственно весь roadmap - это его подготовка к собеседованию и обретение этих знаний с нуля.
https://github.com/ossu/computer-science OSSU(Open Source Society University)
Очень известный проект, опенсорсный университет. Они ориентируются именно на вузовскую программу cs.
1. Ввод в computer science
Учебные материалы, не требующие какой либо предварительной подготовки, можно даже ни одного ЯПа не знать. При этом, их полезно посмотреть всем начинающим программистам, даже если дальнейшее изучения cs не планируется.
1.1. CS50
Легендарный Гарвардский ввод в cs. Лектор обладает каким то запредельным скиллом интересно подавать сложный материал, и сам материал выше всяких похвал. На данный момент, именно этот ввод мне видится лучшим вариантом для старта.
1.2. "Код", Петцольд
Эта книга - ввод в архитектуру, разбирается всё, буквально от подачи тока по проводкам и заканчивая высокоуровневыми языками программирования.
Но куда интересней другая особенность книги - здесь с легкостью ловится эффект, когда ты понял одну часть, но уже забыл прошлую, и надо все заново, и все удерживать в голове и т.д. При этом сама книга написана простым языком, не подразумевает никаких предварительных знаний по теме и досконально разбирает каждый момент. Вы как бы учитесь работать со сложной системой, находясь при этом в комфортных условиях(это буквально необходимый навык для дальнейшего изучения cs, наверно, он даже важнее самой темы книги).
Ко всему прочему CS50 и "Код" Петцольда - идеальное сочетание. CS50 мало про архитектуру, а Код отлично ложится на ввод в computer science. Поэтому рекомендую ознакомится с книгой как можно раньше.
1.3. Missing Semester
Оригинал - https://missing.csail.mit.edu/
[Перевод, на данный момент переведено 2 из 11 частей]Пропущенный семестр курса по компьютерным наукам - https://missing-semester-rus.github.io/
Есть куча инструментов, которые предположительно должен знать студент после изучения Computer Science, обычно это оставляют для самостоятельного изучения, тут же наоборот решили сакцентировать на них внимание(и сэкономить кучу времени студентам).
2. Подготовка к изучению cs
2.1. Про английский
Раз уж, в Missing Semester соприкосновения с иностранным языком не избежать, обсудим эту тему сейчас. Так уж получилось, английский - это необходимость для изучения cs. Хорошая новость в том, что для уч.материалов на английском не нужен уровень Disco Elysium.
Я не лингвист, поэтому рассуждений на тему почему так, выдать не могу. Но точно могу сказать, что для многих становится настоящим открытием то, насколько простой английский используют в тех же лекциях по тех.специальностям. Если получается смотреть какие-нибудь ситкомчики(условных “Друзей”) в оригинале, то и лекции условного MIT по алгоритмам тоже потяните(к тому же, у лекций могут быть конспекты, субтитры, да даже контекст повествования).
Знание языка, даже на каком-нибудь Intermediate, уже огромное преимущество, и если есть возможность каким-то образом подтянуть язык, то это однозначно стоит сделать.
2.2. Выбор языка
Все сводится к 2 вариантам: более классический - си, более простой - питон. Вообще можно выбрать и любой другой, но так уж сложилось, что большинство уч.материалов крутятся вокруг этих двух.
Начнем с питона, основное преимущество - можно быстро писать сложные программы или их рабочие прототипы. В cs очень важно не просто изучать теорию, но и мочь что-то сделать, что называется “покрутить” это, поэкспериментировать, понять принцип работы на практике.
Пост про уч.материалы для изучения основ питона
Не буду расписывать каждый, уже кучу всего про них написал, как и про подбор правильных уч.материалов, все есть в посте.
Поэтому, сразу к Си. Сразу скажу, в моем понимании, изучении Си без ассемблера - крайне странная идея, и из того же gdb изучающий вообще вылезать не должен. Но это достаточно хардкорный подход, в котором для начинающего уж слишком много процесса исследования(что может сильно запутать).
Нет особого смысла расписывать книги по Си, в любой подборке будет фигурировать тот же Прата, мимо основных пройти невозможно, вместо этого расскажу о куда более интересном и малоизвестном материале.
https://stepik.org/course/73618 - один из лучших курсов по Си, найденный мной весьма странным образом. Дело в том, что автор курса написал книгу, с тем самым правильным в моем понимании подходом(сишечка через ассемблер), самой книги нет на русском, но гугл неожиданно привел меня на степик, где курс можно сказать спрятался(не привязан к какой-либо организации, на обложке милейший котик, и всего 2к учащихся, поэтому на самом сайте его приметить затруднительно).
К сожалению, сам курс без ассемблера, но он все же очень хорош. Cложный, глубокий, про современный подход к разработке(это прям редкость). Тут главное не торопиться, и постепенно, вникая во все(это оч. важно), двигаться по курсу.
2.3. А оно точно вам нужно?
Этот вопрос стоит задавать перед изучением любого топика/темы cs. И уж точно, перед комплексным изучением всего предмета. Да, вроде как лишних знаний не бывает, но вот что бывает, так это зря потраченное время(в случае с cs, очень и очень большое).
Почему я вообще поднял этот вопрос? Если кратко, ища разные материалы на тему cs, очень уж часто я видел крайне спорные утверждения из разряда: “каждый программист должен знать”. И если подобное утверждение выходит далеко за пределы основ, то я советую очень и очень осторожно к нему относиться.
Особенно, если изначально не стоит задачи разобраться в той или иной области, а ее изучения связано с получением, например, будущей профессии. Сделайте ресерч, посмотрите действительно ли это необходимое требование(предположу, что в большинстве случаев - нет).
2.4. Изучение от практики
Одна из самых примечательных особенностей изучения cs сейчас, это - возможность изучать некоторые темы от практики. Начинать с небольших “игрушечных” проектов и потихоньку увеличивать сложность, все больше и больше приближаясь к настоящим.
Даже без подборок и прочего, туториалы с ними легко гуглятся. Например, запрос “Lisp interpreter python” и первый же результат:
http://norvig.com/lispy.html (How to Write a (Lisp) Interpreter (in Python)) статья Питера Норвига, где буквально за 90 строк он пишет и объясняет очень простой интерпретатор Lisp
https://habr.com/ru/post/115206/ - перевод этой статьи, также будет на первой странице выдачи
Это отличный вариант для старта. А что потом? Ну например, есть продолжении этой статьи с улучшенной версией интерпретатора:
https://norvig.com/lispy2.html (An ((Even Better) Lisp) Interpreter (in Python)) все также первая страница выдачи, там же будут и другие варианты.
Такой подход, ни в коем случае не отрицает чтения фундаментальной литературы, а наоборот дополняет его, и даже мотивирует все глубже и глубже изучать тему.
2.5. Количество тем
Чтобы этот пост не стал слишком уж большим, я взял самые популярные темы, они входят, если так можно выразиться, в классические топики cs. Получилось 5(Алгоритмы, Математика, Архитектура, Операционные системы, Языки программирования и компиляторы). Не знаю насколько вообще тема поста интересна, если хорошо зайдет, то сделаю еще 5, навскидку: сети, бд, графика и т.д
Computer Science | что читать/смотреть
3. Алгоритмы
3.1. Алгоритмы. Руководство по разработке, Стивен Скиена - считаю лучшим вариантом, замечательная книга. Кроме того, что она великолепно написана, в ней есть куча ссылок на другую отличную литературу, можно очень глубоко погрузиться в тему.
3.2. Грокаем алгоритмы, Адитья Бхаргава - хороший вариант для совсем начинающих.
3.3. Структуры данных и алгоритмы Java, Роберт Лафоре - классика, не смущайтесь ЯПа в названии, вообще хорошая литература по алгоритмам к ЯПам не привязана, они лишь лучше иллюстрируют рассказанное, в случае Лафоре, рассказанное настолько понятно, что Java точно не станет проблемой.
Но если нужно именно на определенном ЯПе, то разумеется есть репозиторий с кучей алгоритмов и реализаций на разных ЯПах - https://github.com/TheAlgorithms/Python/blob/master/DIRECTORY.md
3.4. Алгоритмы. Вводный курс, Томас Кормен - почему то все время забывают про эту книгу, и сразу отсылают к большой работе того же автора ‘Алгоритмы. Построение и анализ’, эта книга, куда легче и возможно, станет ступенькой к основному труду автора.
3.5. https://stepik.org/course/217 - Алгоритмы: теория и практика. Методы
https://stepik.org/course/1547 - Алгоритмы: теория и практика. Структуры данных
Два отличных курса от CSC, оба мультиязычные
3.6. Есть один курс на английском, который я не могу не упомянуть:
Introduction to Algorithms(MIT), он большой(это мягко сказано), но зато очень детальный, и объясняют все достаточно понятно, ко всему прочему этот курс только часть из серии Массачусетских курсов по алгоритмам, сразу за ним идет не менее приятный - Design and Analysis of Algorithms.
Еще к этому можно добавить кучу отличных статей, кучу объяснений сложных моментов простым языком, всякие ресурсы с задачками и т.д. и т.п. В плане поиска уч.материалов - изучение алгоритмов не доставит проблем.
4. Математика
Лучше изучать математику под конкретную цель. Т.е. в тот момент, когда приходит понимание, что для дальнейшего изучения другой темы необходимо ее(математику) подтянуть.
Но, как бы это помягче сказать, может сложиться ситуация, когда и подтягивать то нечего, настолько с математикой дружба не склеилась. В таком случае, наверно стоит почитать что-то популярное, пускай не относящееся к дискретной математике(cs крутится вокруг неё), просто чтобы понять, что это не такая страшная штука.
4.1. Парочка таких книг:
Красота в квадрате, Алекс Беллос
Удовольствие от х, Стивен Строгац
Теория игр, Авинаш Диксит, Барри Нейлбафф
Что такое математика? Рихард Курант, Герберт Роббинс
После/параллельно, стоит посмотреть что-то из разряда “математика для взрослых/минимум для абитуриента тех.вуза”. Главное, чтобы подобные ликбезы не стали в тягость.
Как и говорилось выше, в cs все крутится вокруг дискретной математики
4.2. Дискретная математика для программистов, Род Хаггарти - наверно, сейчас это лучший вариант введения в предмет.
4.3. На степике довольно много курсов по дискретной математике, возможно кому то такой формат будет удобней.
https://stepik.org/course/91 - Ликбез по дискретной математике
https://stepik.org/course/83 - Дискретные структуры
https://stepik.org/course/125 - Основы перечислительной комбинаторики
https://stepik.org/course/126 - Основы теории графов
https://stepik.org/course/5608 - Теория графов
4.4. Перед курсом про алгоритмы(из прошлого раздела) в MIT читают курс, который так и называется Mathematics for Computer Science.
5. Архитектура
5.1. "Код", Петцольд - книга из введения, если по каким то причинам еще не прочитана, то самое время это сделать.
5.2. Архитектура компьютера, Таненбаум - буквально фундамент, очень важная книга. Она куда сложнее Петцольда, но это, можно сказать, другой уровень. По сути, Петцольд в разрезе изучения архитектуры - подготовка к этой книге.
5.3. Архитектура компьютера и проектирование компьютерных систем, Дэвид Паттерсон, Джон Хеннесси - еще одна фундаментальная книга. Вполне может составить конкуренцию Таненбауму.
Честно сказать, не вижу смысла писать о других уч.материалах. Последние 2 книги просто вне всякой конкуренции. И даже близко никакой другой курс/книга не подобрался.
6. Операционные системы
6.1. https://stepik.org/course/1780 - Операционные системы, отличный курс, с него вполне можно начать.
6.2. https://github.com/tuhdo/os01 - Operating Systems: From 0 to 1, книга, отличный ввод в тему, к сожалению, только на английском.
6.3. https://littleosbook.github.io/ - The little book about OS development, великолепная книга, именно по разработке операционок, теорию же авторы рекомендуют брать из того же Таненбаума. Тоже только на английском.
6.4. Собственно, Современные операционные системы, Таненбаум, Бос - книга, разумеется, абсолютный мастрид для желающих разобраться в вопросе, но она очень и очень сложная, поэтому крайне не рекомендую начинать с нее, посмотрите варианты которые выше, попишите всякие мелкие проекты(благо туториалов куча), и только потом стоит приступать.
6.5. Если интересует Linux, точно не стоит проходить мимо Ядро Linux. Описание процесса разработки, Роберт Лав
7. Языки программирования и компиляторы
7.1. Разумеется, есть книга дракона Компиляторы: принципы, технологии и инструменты, Ахо, Лам, Ульман, Сети - здесь та же история, что с операционками Таненбаума, абсолютный мастрид, но к нему следует хорошенько подготовиться.
К тому же, можно очень хорошо разобраться в теме, и например, написать свой первый компилятор, вообще до соприкосновения с драконами. И это мне кажется правильной тактикой изучения.
Начать с того самого “подхода от практики”, потихонечку увеличивать сложность, пока не станет ясно, что необходимо более глубокое понимание теории. Отправная точка у всех разная, благо туториалов разной сложности столько, что без проблем можно найти подходящий.
7.2. https://ruslanspivak.com/lsbasi-part1/ - отличный вариант для старта, Цикл из 19 статей, в котором автор, пишет интерпретатор языка Pascal на Python.
7.3. https://github.com/DoctorWkt/acwj - автор репозитория пишет компилятор, при этом подробнейшим образом объясняя каждый шаг.
Пословицы в BPNM
Когда руководство хочет, чтобы все было описано по правилам
Часть 0.1. Поясняю за структуры данных (часть 1)
Привет, меня зовут Артем и я люблю программировать. Надеюсь, вы прочитали предыдущую, нулевую статью.
Что бы стать хорошим программистом (не веб-разработчиком, а хорошим программистом), вы в первую очередь должны понять, что программирование – это манипуляция данными. И то, насколько вы хорошо умеете обращаться с данными в зависимости от поставленной задачи, определяет, сможете ли вы создавать хорошие программы или нет. В интернете уже есть куча материала на тему структур данных и алгоритмов, но я попробую расписать весь этот материал по-своему. Возможно, это поможет кому-то лучше понять эту тему.
Начнем с определения понятия «сложность алгоритма» — это нам пригодится тут и в следующей статье про алгоритмы.
Если говорить простыми словами – то сложность алгоритма – это то, сколько действий нужно совершить данному алгоритму, чтобы выполнить определенную задачу. Чем больше действий нужно алгоритму, тем он сложнее, и тем он хуже (если существуют альтернативные алгоритмы с меньшей сложностью).
Например, представим ряд чисел – 12345. Нам нужно инвертировать порядок этих чисел (переставить числа так, чтобы вышло 54321). Представим, что алгоритму №1 нужно совершить 5 действий, чтобы переставить числа, а алгоритму №2 – 10. Из этого можем сделать вывод, что в данном случае алгоритм №1 будет предпочтительней для нас.
Но это говоря простыми словами. В реальности на выбор алгоритма также влияет то, сколько памяти он занимает в процессе работы (например, у алгоритма высокая сложность, но он кушает мало памяти, и для устройств с малым количеством оперативной памяти лучше реализовать его), сложность реализации алгоритма (например, мы знаем, что алгоритм «быстрой сортировки» быстрее, чем алгоритм «сортировки пузырьком». Но у вас в компании работают только веб-программисты, которые написать алгоритм быстрой сортировки не смогут. Поэтому вам ничего не остается, кроме реализации алгоритма «сортировки пузырьком») и требования алгоритма к железу (в основном это алгоритмы для нейросетей, которые работают на видеокартах. Например, что бы прогнать картинку 512х512 пикселей через нейросеть типа ESRGAN, вам потребуется видеокарта, у которой не менее 2 ГБ видеопамяти).
Сложность алгоритма обозначается большим О. Например, O(1), O(n), O(n!). И тут все сложна легко. Вспоминаем математику, на которой ты стрелял в друга скомканными шариками из ручки, что значение функции может зависеть (или не зависеть) от определенных параметров этой функции. Например, функция 1 = n (это то же самое, что и O(1)) говорит, что независимо от значения n результат всегда будет 1. Функция y = n! (это O(n!)) означает, что результат (это y) будет равняться значение n факториал (не путать с фракталом). То есть, если у нас 5 чисел, то алгоритм сложностью O(n!) сделает 1 * 2 * 3 * 4 * 5 операций (посчитай сам, сколько это).
Лично мне нравиться эта табличка, которую я нашел в группе /dev/null в ВК
Другой взгляд на О большое:
O(1) = O(уууее)
O(log n) = O(да)
O(n) = O(к)
O(n^2) = O(йблин)
O(2^n) = O(нет)
O(n!) = O(МГ!)
Как это связано со структурами данных? Структуры данных и алгоритмы очень тесно связаны, и у каждой структуры есть свои алгоритмы обхода элементов структуры, их добавление\удаление, поиск в структуре и т.д. И поэтому важно знать сложность алгоритмов, которые дают нам возможность управлять этой структурой, что бы выбрать подходящую для решения нашей задачи.
Со сложностью алгоритмов вроде разобрались. На практике для каждой задачи есть несколько решений, и вы сами, как программист, вольны выбрать то, которое подходит именно под вашу ситуацию.
В следующей статье я попробую рассказать о структурах данных, зачем они нужны и рассмотреть такие структуры, как стек, очередь и связанный список.
После прочтения данного текста можете заглянуть в комментарии - там могут дополнить материал или исправить ошибки в данном материале.
Часть 0. Практическое программирование
Всем привет,
меня зовут Артем и мне нравиться программировать. Я не имею степени в информационных науках, обладаю мизерным опытом работы в данной сфере и не буду делать уроки по конкретному языку или технологии. Я просто хочу начать учится вместе с вами и реализовывать практические проекты, решение которых не очень удачно или вообще никак не описано в сети.
Я не буду привязываться к конкретному языку или технологии, и эти посты нужно расценивать как сборку информации по конкретной теме.
Возможно, это будет полезно начинающим программистам, или людям, которые будут искать информацию по конкретной теме.
Я буду стараться выбирать задачи, которые менее зависимы от возможностей железа (то есть, каких-то программ по нейросетях скорее всего не будет). Также я буду подавать информацию, которая будет собрана с интернета и доступных мне книг, и она может быть как на русском, так и на английском. Также проектов, связанных с веб-разработкой, будет очень мало, ибо я не считаю чистое веб-программирование (я подразумеваю знание HTML\CSS\JS и/или какого-нибудь ASP или Node.js) - программированием и в этой сфере сейчас столько народу, что все возможные аспекты веб — разработки уже были расписаны и разобраны вдоль и поперек.
В первую очередь, я создаю данные посты для себя и не утверждаю, что все, что я тут написал - единственный тру способ программирования.
Чем примерно я хочу заняться:
1) Реализация алгоритмов
2) Реализация проектов, которые полностью или частично представляют собой реальные проекты)
3) Реализация интересных проектов (которые вы возможно никогда не будете реализовать в реальных условиях)
Если вас заинтересовала данная тема - можете подписаться на уведомления.
Как подготовить машину к долгой поездке
Взять с собой побольше вкусняшек, запасное колесо и знак аварийной остановки. А что сделать еще — посмотрите в нашем чек-листе. Бонусом — маршруты для отдыха, которые можно проехать даже в плохую погоду.