Программирование

Я пишу код уже больше 20 лет и, хотя в последнее время больше занимаюсь руководством, на пике формы был способен писать по 500+ строк хорошо работающего кода в день. Вот принципы, которые мне в этом помогали:

  1. Не переобобщайте. Если не получается малой кровью создать универсальное решение, то и неважно, решите конкретную текущую задачу и двигайтесь дальше. Обобщение, даже хорошее, в 70% случаев так и остается нигде больше не использованным.

  2. Не оптимизируйте код заранее. Идея усложнить код ради его ускорения почти всегда ошибочна. Исключение возможно только в том случае, когда именно этот участок код "тормозит" так, что это уже заметно на уровне продукта или бизнеса. "Пессимизировать" код тоже, конечно, не нужно, из двух версий, одинаковых по сложности и по объему кода, выбирайте более быструю. Из этого есть важное следствие: нельзя дублировать данные и нельзя кешировать результаты вычислений там, где этого не требует во весь голос производительность. Больше половины структурных багов возникает из-за того, что "разъехались" кэш и реальные данные, причем еще и отлаживать такое обычно адски сложно, потому что в момент собственно "разъезжания" никакого бага еще не видно, он проявится потом, когда ставить breakpoint-ы и проходить исполнение по шагам уже поздно.

  3. Называйте и группируйте всё происходящее правильно. Код, в котором нет алгоритмических или технологических сложностей, должен читаться как текст, написанный по-английски. Хорошо, когда код, в котором ниндзя куда-то крадётся, выглядит как-то вроде ninja.sneak(...), а не pDst2.trySetCoord(...) и ещё десять строчек после этой, ни одну из которых нельзя забыть. Если функция что-то меняет в состоянии объекта, она не может называться isSomething -- если так сделать, следующий же код с её участием обречён на интересный дебаг. Если функция что-то трудно вычисляет, она не может называться getSomething -- кто-нибудь наверняка начнёт вызывать её в цикле и удивляться, почему всё тормозит. Класс, который хранит состояние документа, может называться DocumentState или Document, но никак не SDManager. Кстати, про Manager-ов. Если единственное название, которое вы можете выбрать для класса или метода, получается очень расплывчатым, это верный признак того, что вы делаете что-то неправильно. Классы BaseObject и World или функции databaseOps и initService быстро приведут к самым разным проблемам и багам, связанным с нарушениями этого и предыдущего пунктов.

  4. Не смешивайте алгоритмы и другие технологически сложные участки кода с бизнес-логикой. Выразительности современных языков программирования вполне достаточно для того, чтобы, скажем, графический движок компьютерной игры ничего не знал о ниндзя и вертолётах, функции работы с БД в CRM-системе не знали слов "счёт" и "клиент", и т.д. и т.п. Для бизнес-логики типичны постоянные изменения, нечеткость и путаница. Как только сущности с разных уровней абстракции начинают упоминаться в соседних строчках кода, , всё это тут же начинает проникать и в технологически сложный код, и всё взрывается.

  5. Не используйте никакие advanced фичи никакого языка. В С++, например, не стоит пользоваться темплейтной магией, переопределением операторов, множественным наследованием и т.д. и т.п. Экзотические языки программирования (Haskell, диалекты Лиспа, хитрые декларативные язычки, работающие поверх JVM) вообще стоит использовать только как хобби, источник вдохновения. Не напрямую в той работе, за которую вам деньги платят. Эта точка зрения часто вызывает споры. К сожалению, обстоятельно аргументировать её в формате ответа на Знатоках не получится. Поэтому просто сошлюсь на свой почти 20-летний опыт индустриального программирования. Во всех областях и организациях, в которых я успел поработать, что в Яндексе, что в разработке игр, что в науке идея использовать в качестве рабочего инструмента "красивый полёт свободной мысли, недоступный простым умам" оказывалась разрушительной. Часто и для всего проекта, но всегда, без исключений, для автора идеи.

  6. Стоит выкинуть из головы все ООП. Единственное полезное, что в императивные языки пришло из этой идеологии - модификаторы private. Иерархии классов это зло, наследовать реализации нужно себе запретить. Наследовать можно интерфейсы, и то не слишком много уровней. Агрегация почти всегда лучше наследования. Большая часть классических "шаблонов проектирования" уже либо устарела, либо нашла поддержку на уровне языка.

  7. Используйте как можно больше assert'ов, логов и прочих способов поймать незапланированное состояние системы как можно раньше. Очень часто в момент, когда неверное поведение системы становится заметно пользователю, дебажить её уже сложно. Если же вы смогли поймать систему именно в тот момент, когда её внутреннее состояние впервые становится неконсистентным или она начинает вести себя не так, как вы задумывали, чаще всего разобраться в том, почему, становится тривиально.

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

  9. Граничные случаи стоит проверять "в голове" прямо по ходу написания кода. Например: я пишу list.back(), а почему этот список не пуст? Как я "доказал" к этому моменту, что этого не может произойти? Что сделает эта функция, работающая со строчкой, если она пуста?

  10. Любой баг, если он все-таки вам встретился, старайтесь возводить до первопричины и до общего правила. Что я написал в коде такого, что этот баг вообще оказался возможен? Как я могу поменять свои практики так, чтобы больше никогда не допускать таких же? Например, баг состоял в том, что я написал такую-то строчку в функции save и забыл добавить симметричную в функции load. Может быть, пора, наконец, заменить эту пару на одну функцию serialize? Обложить их тестами? Или хотя бы поклясться вслух самому себе, что никогда не будете трогать их по одиночке? Или, например, причина бага была в том, что в указателе pNeighbor содержится null, а программа этого не ожидает и падает. Можно просто воткнуть if (pNeighbor != null) и закрыть баг как исправленный. А где ещё в коде разыменовывается pNeighbor? Везде ли есть такая же проверка? Насколько вообще эта ситуация легальна, может быть, настоящая ошибка там, где pNeighbor впервые оказался нулевым? Если значение pNeighbor это результат отображения NULL из БД на объектную модель, то как этот NULL попал в БД, кто его туда положил и не стоит ли воткнуть там constraint? И т.д и т.п. Никогда не считайте, что ваш код уже идеален! Наблюдайте за собой, совершенствуйтесь, старайтесь работать вместе с людьми, у которых есть, чему поучиться.

Тема эта неисчерпаема, приёмов и приёмчиков можно вспомнить ещё много, но я, пожалуй, остановлюсь на этой десятке. Всем хорошего кода!

JS — своеобразный язык, в нём есть одна общеизвестная логическая ошибка (если будете изучать — узнаете), которую специально не исправляют для совместимости с предыдущими разработками на js. Сам js — создан для фронтенда и его код обрабатывается непосредственно браузером, но из-за повсеместной популярности, из него сделали и бекенд—версию. Плюс, для js создано большое количество всевозможных фреймворков, заточенных под разные задачи и облегчающие процесс кодинга

Очень субъективное мнение: хороший программист умеет решать задачи "от и до", учитывать все возможные ограничения своего решения, последствия для разрабатываемой системы. О точно знает, что и почему он сделал. В первую очередь это зависит от широты специальных знаний.

Привет, стоит отметить, что в последнее время всё большую популярность для создания игр набирает среда Unity, которая лучше всего взаимодействует с C#.

Python в геймдеве он тоже пригодится. 2D и 3D-игры, простые квесты и RPG — это далеко не все, что можно написать на «змеином языке». Скрипты Python хорошо взаимодействуют со многими движками, что позволяет использовать их для более эффективного и простого кода, даже если игра написана на другом языке.

Не теряет популярности Java, и достижения технического прогресса играют ему на руку. Кроссплатформенность этого языка позволяет легко адаптировать игры под любую операционную систему. Java пригодится не только в игрострое. С его помощью создают Android и веб-приложения, серверные проекты в сфере финансовых услуг, встраиваемые системы и инструменты для обработки Big Data.

Классика для создания игр — C++. При всей сложности в изучении этот язык крайне востребован. Он гибкий и компилируемый.

Думаю, всё просто. Существует не так много общеизвестных перечислений: арабские цифр, латинские и греческие буквы. Ещё в 1950х годах компания IBM использовала греческие буквы для описания стадий тестирования, затем эта практика распространилась в индустрии. Теперь буквой α обозначают стадию разработки, на которой хромой и спотыкающийся продукт уже хоть как-то но можно тестировать, а буквой β - стадию тестирования перед непосредственным выпуском продукта или сервиса.

Нет. Схожесть названий не должна вас обманывать, C# и C++ совсем разные языки. С# довольно простой язык, по своему устройству и философии гораздо больше похожий на Java, чем на C++. Насколько мне известно, C# применяют в основном для программирования десктопных приложений под Windows, а в прочих областях он по распространенности сильно отстаёт от языков-"конкурентов". С++ язык гораздо более сложный и многогранный, и применяется он в огромном количестве самых разных областей, от разработки игр до серверного кода Facebook/Google/Яндекс. Если вы уже изучаете C++, изучение C# в параллель вас только запутает и мало что даст в понимании программирования. Если хотите что-то изучать дополнительно к С++, посмотрите лучше на python, Javascript или Go. Они очень сильно отличаются от С++ по синтаксису (так что не запутаетесь), очень широко применяются, и в каждом из них заложены интересные "философские" идеи, концепции и конструкции, понять которые, изучая только С++, практически невозможно. Будет в этом и совершенно практический смысл: ситуация, когда часть кода написана на С++, а часть на одном из этих языков, широко распространена в ведущих IT-компаниях мира.

К сожалению, без контекста ответить на этот вопрос достаточно трудно, ведь базы данных бывают очень разные: темпоральные, распределённые, реляционные и т.п. Однако на самом высоком уровне их все объединяет задача. Базы данных нужны, чтобы хранить информацию и предоставлять к ней удобный доступ (для чтения, записи и изменения). А значит, в базе данных обязательно должны существовать коллекции данных (таблицы или отношения в терминах реляционных баз данных, коллекции в терминах MongoDB) и способ строить запросы к этим данным (в реляционных базах это скорее всего будет диалект языка SQL, в документ-ориентированных это может быть javascript, в XML-хранилищах - язык xpath или xQuery, а некоторые языки программирования могут транслировать код в такие запросы, как например технология Linq в C#).
Итак, во всех известных мне базах данных есть коллекции объектов (таблицы) и способ к ним обращаться (язык запросов).

Зачем нам вообще вектора слов и предложений?
Представьте, вам сказали решить задачу классификации отзывов на положительные и отрицательные и дали примеры таких отзывов. Вам нужно построить алгоритм, который по тексту будет предсказывать вероятность того, что отзыв положительный. Для этого нужно перевести текст - слова или предложения в вектор- набор цифр. Можно использовать информацию только из обучающей выборки - из нашего набора отзывов, но кажется, что люди, когда определяют положительный ли отзыв, используют свои знания, собранные из всех прочитанных текстов - понимают, какие слова похожи, их контекст.
Немного про предка doc2vec - word2vec
Итак, если мы хотим построить полезные вектора для слов или предложений, нам нужно от них 2 вещи:
1) Мы хотим, чтобы похожие по смыслу слова или предложения лежали рядом.
2) Мы хотим уметь получать их без обучающей выборки - по неразмеченным текстам.
Тут на приходит на помощь модель word2vec - мы учим неглубокую сетку предсказывать слова, по тому, какие слова обычно встречаются в их контексте.
Ответ на вопрос
Doc2vec предсказывает слово не только по контексту слов, но и по предложению, в котором встретилось слово. Это предложение и кодируется с помощью параметра paragraph_id, а веса, полученные при обработке paragraph_id становятся векторным преставлением предложения.
Ссылка с подробностями и картинками -
https://medium.com/@amarbudhiraja/understanding-document-embeddings-of-doc2vec-bfe7237a26da

Архитектор ПО является следующей ступенькой после должности Senior разработчика. Эта должность также предполагает решение технических задач, но уже связана с принятие ключевых решений, определяющих весь ход разработки программного продукта. Должность архитектора ПО предполагает не только наличие глубоких знаний и опыта в области IT-технологий, но также и определенных личностных качеств и навыков, без которых взаимодействие с командой разработчиков а также с представителями бизнеса, являющимися, собственно, заказчиками проекта, будет проблематично. К таким качествам можно отнести системное мышление, коммуникативные способности, склонность к анализу, умение донести свое видение проекта до широкого круга лиц, принимающих участие в разработке, склонность к постоянному получению новых знаний.

Можно понять лишь пробуя.

К сожалению спрос на дизайнеров гораздо меньше и зп меньше тоже, но тем не менее я выбрал профессию дизайнера и люблю то, что делаю. Все относительно. То, что вы любите и есть "лучше" :)