8 ознак поганого програміста
Які якості та професійні недоробки віддаляють від роботи мрії? Розберемося докладніше, як представники IT-компаній та рекрутери розпізнають поганого програміста.
Невміння писати код на аркуші паперу
Ігор Зінов'єв, технічний директор компанії «Дисципліна»:
«Будь-який розробник зобов'язаний вміти писати код на аркуші паперу. Цей критерій не допоможе вам знайти хорошого розробника, але чудово покаже поганого. зв'язуватися».
«Всі винні, крім мене»
Олександр Нінбург, генеральний директор сервісу "Німбл":
«Поганий програміст — той, який за час роботи не довів жоден із попередніх проектів до кінця. не програміст. Такі люди багато говорять не у справі — відповідаючи на запитання, вони далеко уникають теми, навіть якщо відповідь була коректною».
Нецікава розповідь про роботу, небажання самостійно шукати відповіді та неструктурне мислення
Євген Карюк, виконавчий директор компанії "Біплан":
«Коли фахівець не фанатіє від своєї справи або без ентузіазму ділиться всіма деталями, це одразу помітно і говорить багато про що.
Коли фахівець ставить багато запитань, замість самостійного пошуку відповідей, нічого хорошого чекати не варто.Структурне мислення — характерна риса для справжніх професіоналів своєї справи, яка одразу впадає у вічі неосвіченій людині».
Відсутність самодисципліни
Антон Захаров, технічний директор професійного хостинг-провайдера.
«Ключовим у роботі програміста є самодисципліна. Регулярність і старанність у роботі розкривають творчий потенціал програміста, а його роботу над будь-яким проектом роблять передбачуваною. практичні рішення поставлених завдань.
Для того щоб розпізнати поганого програміста, можна звернути увагу на кілька базових речей, які є наслідком браку дисципліни: відсутність будь-яких базових навичок у побудові алгоритмів, а як наслідок – відсутність розуміння, як зробити код для інших розробників, що читається. для того, щоб підтримувати код проекту на необхідному рівні актуальності та чистоти, оскільки це також впливає на швидкість внесення нового функціоналу».
Впадання в крайнощі
Микола Степанов, директор департаменту розробки ПЗ «Лестер ІТ»:
Крім простих формальних критеріїв, які дозволяють обчислити поганого програміста (незнання і нерозуміння базових алгоритмів, надмірність при написанні коду і просто відсутність здібностей), є пара властивостей особистості, крайні ступеня прояви яких змушують віднести програміста в розряд поганих навіть за наявності хороших знань і досвіду :
Впевненість у собі та своїх діях. Коли її занадто багато, людина легко затирає чужий неправильний код, навіть не розібравшись у тому, що власне він робив і де помилка. намагатиметься всіляко скинути з себе провину. навіть маючи повний карт-бланш на ухвалення рішення, всіма силами повертає відповідальність назад керівнику за допомогою нескінченних узгоджень. і в результаті з боку вже й не зрозуміло, де старий код, а де коментарі до нового.
Ставлення до нового. Кохання в крайньому ступені — це нескінченні нові технології, бібліотеки, інші фічі та впевненість піфії, що вони в секунду вирішать усі завдання. ситуація - програміст пише тисячі рядків коду, використовуючи тільки ті методи, які він знає сто років, не бажаючи озирнутися навколо, вивчити новинки, навіть якщо вони йому доступні без накладних витрат».
«Не люблю Ruby, на ньому пишуть лише дурні»
Катерина Гаврилова, генеральний директор IT рекрутингової агенції DigitalHR:
«Іноді поганого розробника можна дізнатися з напівслова. Наприклад, коли він пояснює, чому не хоче з технологією якоїсь роботи.
— не люблю рубай, бо на ньому пишуть дурні — погано;
— не люблю рубай, бо (і каже щось про синтаксис та інше) — добре».
Висновок
Вміння писати код на аркуші паперу, здатність визнавати свої помилки, захопленість роботою, самостійність у прийнятті рішень поставлять вас вище серед інших претендентів на вакансію. Не варто впадати в крайнощі, виявляючи надмірну впевненість чи невпевненість у собі. Потрібно розвивати структурне мислення, самодисципліну, вчитися аргументовано та зрозуміло відстоювати свою точку зору — адже у будь-якому разі доведеться контактувати з людьми.
Будьте добрими програмістами: професія «Веб-розробник».
Ознаки поганого програміста
"Міркувати про код" означає розуміти порядок виконання інструкцій ("виконувати програму в голові"), знаючи, яке призначення коду.
Симптоми
- Наявність «чарівного», «вуду» коду або коду, який не має жодного відношення до цілей програми, але все одно ретельно підтримується (наприклад, ініціалізація змінних, які ніколи не використовуються, виклик функцій, що не мають відношення до мети, створення вихідних даних, які не використовуються і т.д.).
- Багаторазові виклики ідемпотентних функцій (наприклад, виклик save() по кілька разів, «щоб точно»).
- Виправлення помилок написанням надлишкового коду, який замінює дані, отримані під час виконання несправного коду.
- "Йо-йо код", який конвертує значення в різні уявлення, а потім конвертує їх назад рівно в те ж уявлення, з якого починали (наприклад, перетворення десяткового числа в рядок, а потім назад в десяткове число, або padding рядки з наступним trim Том).
- "Бульдозерний код", який створює враження рефакторингу за допомогою розбиття шматків коду на процедури, які, правда, потім неможливо використовувати деінде (висока когезія).
Лікування
Щоб впоратися з цією пороком, програмісту слід користуватися вбудованим в IDE debugger'ом як помічником у разі нездатності крокувати за кодом рядково. У Visual Studio, наприклад, можна встановити breakpoint на початку «проблемної» зони і потім крокувати, натискаючи F11, паралельно стежачи за значеннями змінних, доки стане ясно, що саме код робить. Якщо в цільовому оточенні немає такої можливості, слід практикуватися у тому, в якому це можливо.
Мета - досягти такого рівня, коли вам більше не потрібний debugger, щоб виконувати код «у голові», коли ви досить терплячі для того, щоб думати про те, як код змінює стан програми. Як нагорода ви отримаєте можливість визначати надлишковий і непотрібний код, а також уміння знаходити помилки в існуючому коді без реалізації всього алгоритму заново.
Погане розуміння моделі мови програмування
Об'єктно-орієнтоване програмування — приклад моделі мови програмування, як і функціональне, і декларативне програмування. Всі вони суттєво відрізняються від процедурного чи імперативного програмування, так само як і процедурне програмування суттєво відрізняється від асемблера чи програмування за допомогою GOTO-інструкцій.Також існують мови, які наслідують якусь поширену модель програмування (скажімо, об'єктно-орієнтоване програмування), але вносять до неї якісь удосконалення, як наприклад генераторні вирази (list comprehensions), узагальнене програмування (generics), качина типізація (duck typing ) тощо.
Симптоми
- Використання будь-якого необхідного синтаксису для того, щоб «вирватися» з запропонованої мовою моделі, і написання частини програми, що залишилася, в імперативному/процедурному стилі.
- (ООП) Спроби виклику не статичних функцій або присвоєння змінних у неінстанційованих класах, проблеми з розумінням, чому такі конструкції не компілюються.
- (ООП) Наявність величезної кількості”. Manager» класів, які містять усі методи маніпуляції з об'єктами, які, своєю чергою, зовсім не містять (або містять мало) методів.
- (Реляційне) Поводження з базою даних як зі сховищем об'єктів, виконання всіх JOIN'ів та перевірки цілісності на клієнтській стороні.
- (Функціональне) Створення багатьох версій одного й того самого алгоритму обробки різних типів чи операторів замість передачі функцій вищого порядку узагальненому алгоритму.
- (Функціональне) Ручне кешування результатів детерміністичних функцій на платформах, які роблять це автоматично (SQL або Haskell).
- (Функціональне з «чистими» (pure) функціями) Використання копіпасти з чужого коду для того, щоб подолати I/O та монади.
- (Декларативне) Встановлення індивідуальних значень в імперативному коді замість використання зв'язування даних (data binding).
Лікування
Якщо ваша вада - результат неефективного навчання, то найкращий ваш учитель - компілятор.Немає ефективнішого способу вивчити нову модель програмування, ніж розпочати новий проект, прийнявши рішення використовувати нові конструкції, неважливо з яким ступенем усвідомленості. Вам також потрібна практика пояснення можливостей нової моделі через терміни, з якими ви вже знайомі, і рекурсивна побудова нового словникового запасу до тих пір, поки ви не зрозумієте всіх тонкощів. Наприклад:
Крок 1: «ООП — це структури з методами».
Крок 2: «Методи в ОВП - це просто функції, що виконують міні-програму зі своїм власним набором глобальних змінних».
Крок 3: "Глобальні змінні називаються полями, деякі з них приватні і невидимі зовні міні-програм".
Крок 4: «Сама ідея наявності приватних та публічних елементів – приховати деталі реалізації та виставити назовні чистий інтерфейс, і називається це інкапсуляція».
Крок 5: "Інкапсуляція означає, що моя бізнес-логіка не повинна засмічуватися деталями реалізації".
Останній крок однаковий всім мов, оскільки всі мови намагаються привести програміста до можливості висловлювання сенсу програми без закапування цього змісту у деталях реалізації. Візьмемо функціональне програмування:
Крок 1: "Функціональне програмування - це коли все робиться через ланцюжки детерміністичних функцій".
Крок 2: «Коли функції детерміністичні, їх потрібно обчислювати до того часу, поки це знадобилося у вихідних даних, і обчислювати необхідно лише частину, яка справді знадобилася. Це називається лінивими та частковими обчисленнями».
Крок 3: «Для того, щоб підтримувати ліниві та часткові обчислення, компілятор вимагає, щоб я писав функції в термінах трансформації одного параметра, іноді роблячи результатом таких перетворень іншу функцію. Це називається каріруванням (currying)».
Крок 4: «Коли всі функції каріровані, це дозволяє компілятор вибрати найкращий план виконання за допомогою constraint solver'а».
Крок 5: "Дозволяючи constraint solver'у самому вирішувати всі неважливі деталі, я можу писати програми, описуючи, що я хочу, а не як саме це отримати".
Дефіцит дослідницьких навичок / Хронічно погане знання можливостей платформи
Сучасні мови та фреймворки тепер поставляються з напрочуд великою кількістю вбудованих команд та можливостей. Деякі технології (Java, .Net, Cocoa), мабуть, навіть занадто великі, щоб очікувати від будь-якого програміста, навіть дуже хорошого, що він вивчить їх швидше, ніж за кілька років. Але хороші програмісти будуть шукати вбудованих функцій, які роблять те, що їм потрібно, перш ніж вони почнуть писати свої. А чудові програмісти зуміють розбити свої завдання на частини, виявити абстрактні проблеми, а потім знайти фреймворки, патерни, моделі та мови, які можуть бути використані.
Симптоми
Наведені нижче симптоми дійсно вказують на проблему, тільки якщо продовжують виявлятися в роботі програміста досить довгий час після того, як він почав освоювати нову платформу.
- Винахід або створення механізмів, які вже вбудовані в мову, наприклад, event'и та handler'и, регулярні вирази.
- Винахід класів та функцій, які вже є у фреймворку (наприклад, таймери, колекції, алгоритми сортування та пошуку).
- Повідомлення «Напишіть мені код, пліз!» у різних форумах.
- "Кільцевий код", який виконує своє завдання з набагато більшою кількістю інструкцій, ніж потрібно (наприклад, округлення числа через перетворення до рядка і назад).
- Постійне використання старомодних технік, навіть якщо нові краще в поточній ситуації (наприклад, створення повноцінних іменованих функцій там, де потрібна лямбда-вираз «на раз»).
- Нереального розміру "зона комфорту", коли людина готова пройти екстремально довгий шлях, вирішуючи проблему примітивними засобами.
Лікування
Програміст не може набути таких знань не припинившись, і, швидше за все, це була відчайдушна спроба змусити кожну функцію працювати, хоч би чого це йому коштувало. Йому потрібні технічний довідник по платформі і можливість дивитися в нього з мінімальними зусиллями, що означає, що у нього мають бути або тверда копія на столі поруч із клавіатурою, або другий монітор для браузера. Щоб отримати початкову звичку писати «правильно», йому слід намагатися рефакторити свій старий код, ставлячи собі за мету зменшення кількості інструкцій хоча б на порядок.
Нездатність зрозуміти покажчики
Якщо ви не розумієте покажчики, залишається дуже невелике коло типів програм, які ви можете написати, оскільки це розуміння дозволяє створювати складні структури даних і доцільні API. Керовані мови використовують посилання замість покажчиків, які схожі, але забезпечують автоматичне розіменування та забороняють арифметичні операції над покажчиками для усунення цілого класу помилок.Вони, як і раніше, досить схожі, проте нерозуміння концепції покажчиків відобразиться у бідному проектуванні структур даних та помилках, причини яких криються в різниці між передачею за значенням та засланням.
Симптоми
- Нездатність написати зв'язковий список або написати код, який вставляє/видаляє вузли зі зв'язкового списку без втрат даних.
- Виділення довільних великих масивів для змінного розміру замість зв'язкових списків або інших динамічних структур даних.
- Нездатність знайти або виправити помилки, пов'язані з арифметикою над покажчиками.
- Зміна розіменованих значень із покажчиків, переданих у функцію, не усвідомлюючи, що це змінить значення поза області дії (scope) функції.
- Створення копії покажчика, зміна розіменованого значення через копію з очікуваннями, що оригінальний покажчик, як і раніше, вказує на старе значення.
- Серіалізація покажчика, тоді як серіалізоване має бути розіменоване значення.
- Сортування масиву покажчиків порівнянням самих покажчиків, а чи не значень.
Лікування
Мій друг Джо жив у тому самому готелі, що я, але я не знав, у якому саме номері. Однак я знав, де зупинився його знайомий Френк. Тож я пішов туди, постукав у двері і спитав Френка: «Де зупинився Джо?». Френк не знав, але він знав, у якій кімнаті живе Теодор, колега Джо. Так що я пішов у кімнату Теодора і спитав, де зупинився Джо, і Теодор сказав мені, що Джо в кімнаті 414. Там я його і знайшов!
Покажчики можуть бути описані за допомогою різних метафор, структур даних може бути знайдено безліч аналогів. Вище наведено просту аналогію для зв'язкових списків.Нерозуміння покажчиків трапляється не через те, як саме описані покажчики (ви не зможете описати їх докладніше, ніж вони були описані досі). Нерозуміння відбувається, коли програміст намагається уявити, що відбувається в пам'яті комп'ютера, і ця картина зливається з його розумінням звичайних змінних, які дуже схожі. Допомогти в міркуваннях про те, що ж насправді відбувається, може такий переклад алгоритму в просту історію. Цим варто займатися до тих пір, поки нарешті у програміста не виникне здатність розрізняти та представляти покажчики та структури даних так само легко, як і скалярні значення та масиви.
Складнощі з рекурсією
Ідею рекурсії досить легко зрозуміти, але у програмістів часто виникають проблеми для того, щоб представити результат рекурсивної операції або наскільки складні обчислення можуть бути зроблені з простою функцією. Проблеми з поданням «де ви знаходитесь», коли ви починаєте писати умову продовження рекурсії, або з формалізацією параметрів рекурсивної функції, можуть зробити розробку рекурсивної функції дуже складною для вас.
Симптоми
- Дуже складні ітеративні алгоритми для вирішення проблем, які можуть бути вирішені рекурсивно (наприклад, обхід дерева файлової системи).
- Рекурсивні функції, які перевіряють одну й ту саму умову до та після рекурсивного виклику.
- Рекурсивні функції, що не перевіряють основну умову.
- Рекурсивні процедури, які конкатенують/накопичують значення глобальної змінної або переносять вихідну змінну, і не реалізують хвостову рекурсію.
- Плутанина з тим, що передавати як параметри при рекурсивному виклику, або рекурсивні виклики, які передають постійні параметри.
Лікування
Закатайте рукави і будьте готові до переповнення стеку. Почніть з написання функції з однією основною умовою та з одним рекурсивним викликом, який використовує той самий, не змінений аргумент, що й отримано на вході. Зупиніться навіть якщо вам здається, що цього недостатньо, і запустіть. Подивіться на переповнення стеку, поверніться назад і додайте зміну аргументу під час рекурсивного виклику. Знову переповнення? Надмірний висновок? Тоді ще кілька ітерацій, перемикаючись між змінами в умові та виклику, до тих пір, поки ви не почнете чути, як функція трансформує вхідні дані. Опирайтеся бажанню використовувати більш ніж одну основну умову або більше одного виклику, якщо ви не знаєте, навіщо ви це робите.
Ваша мета - мати впевненість, щоб почати, навіть якщо у вас немає повного відчуття, «де ви є» в уявному рекурсивному шляху. Коли вам потрібно буде написати функцію в реальному проекті, ви почнете з unit-тесту і продовжите писати, використовуючи схожу техніку.
Ознаки пересічного програміста
Нездатність мислити колекціями
Перехід від імперативного програмування до функціонального і декларативного вимагатиме від вас можливості думати про операції над наборами даних. Колекції стануть вашим примітивом замість скалярних значень. Це потрібно, якщо ви використовуєте SQL і реляційні бази даних, якщо ви розробляєте програми, які повинні масштабуватися пропорційно до кількості ядер процесора, або коли ви пишете код, який запускатиметься на SIMD-чіпах (як, наприклад, сучасні графічні карти та ігрові приставки) .
Симптоми
Ці симптоми мають значення, тільки якщо вони виявляються у роботі з платформою з декларативними чи функціональними можливостями, про які програміст мав би знати.
- Виконує атомарні операції над елементами колекції всередині циклу for або foreach.
- Map або reduce функції, що містять цикли для ітерації набору даних.
- Отримання великого набору даних із сервера та обчислення сум на клієнті замість використання агрегуючих функцій у запиті.
- Написання функцій бізнес-логіки з трагічними сайд-ефектами, на кшталт зміни інтерфейсу користувача або виконання I/O функцій.
- Класи сутностей, які відкривають власні з'єднання з базою даних або отримують файлові дескриптори і тримають їх активними весь час життя кожного з об'єктів.
Лікування
- в'їзд на платну дорогу, обладнаний кількома пунктами оплати (паралельна обробка);
- струмки, які з'єднуються в потоки, які з'єднуються в рукави, з яких виходить річка (парралельне виконання reduce/агрегуючі функції);
- застібка-блискавка (прості join'и);
- транспортна РНК, що збирає амінокислоти і з'єднується з інформаційною РНК усередині рибосоми, щоб стати протеїном (багатостадійні funtion-driven join'и);
- те ж саме, що відбувається в мільярдах клітин в апельсиновому дереві, щоб перетворити грунт, воду та сонячне світло на апельсиновий сік (map/reduce у великих розподілених кластерах);
Відсутність критичного мислення
Якщо ви не ставитеся критично до своїх власних ідей і не шукаєте недоліків під час своїх думок, ви обов'язково пропустите проблеми, які можуть бути вирішені ще до того, як ви почали кодувати.Якщо ви також не здатні критично оцінювати свій код, ви зможете вчитися лише дуже повільно, методом спроб та помилок. Це корінь і лінивого мислення, і егоцентричного мислення, так що симптоми можуть прийти з двох абсолютно різних сторін.
Симптоми
- «Двигуни бізнес-правил».
- Товсті класи зі статичними утилітами, чи бібліотеки, вирішальні безліч різних завдань, але мають одну область імен (namespace).
- Архітектури, яким почали потрібні епіцикли.
- Додавання в таблиці колонок для даних, що не мають прямого відношення до цієї таблиці.
- Недотримання однорідності у назві змінних і способів.
- Ментальність «мужика з кувалдою», або зміна умов завдання так, щоб вона могла бути вирішена за допомогою однієї конкретної технології.
- Програми, які своєю складністю затьмарюють завдання, яке вони мають вирішувати.
- Патологічне та зайве «захисне» програмування (defensive programming), «ентерпрайзненький код».
Лікування
Почніть із книги «Критичне мислення» Paul і Elder, працюйте над управлінням своїм его, і тренуйтеся чинити опір бажанню захиститися, коли ви довіряєте свої ідеї друзям та колегам для критики.
Коли ви звикнете до того, що інші люди вивчають, перевіряють ваші ідеї, почніть всебічно вивчати свої ідеї самостійно. На додаток, вам необхідно розвинути почуття пропорції (щоб розуміти, наскільки дизайн підходить розміру завдання), звичку перевіряти припущення (щоб ви не переоцінювали розмір завдання), і здорове ставлення до невдач (Ісаак Ньютон був неправий про гравітацію, але ми все одно любимо його , та його припущення дуже важливі для нас).
Ну, і, нарешті, ви повинні бути дисципліновані.Поінформованість про вади вашого плану не зробить вас продуктивнішим доти, доки ви не натренуєте волю до виправлення і до перебудови того, над чим ви працюєте.
Пінбол-програмування
Якщо ви пнете автомат рівно так, як треба, відтягнете пружинку рівно наскільки потрібно і вдарите кнопки лапок у потрібній послідовності, тільки тоді програма бездоганно здійсниться.
Симптоми
- Один try-catch блок, що включає все тіло Main(), що рестартує програму.
- Використання рядків або цілих чисел для значень, які могли б мати більш відповідний їм тип у мові зі строгою типізацією.
- Упаковка складних даних у розділені рядки та його парсинг кожної функції, де ці дані використовуються.
- Нездатність використовувати затвердження чи контракти методів на функціях, які роблять припущення про свої аргументи.
- Використання sleep() для очікування поки інший thread закінчить свою роботу.
- Інструкції Switch над значеннями, що не перераховуються, без блоку «інакше».
- Використання automethod'ів або reflection'ів для виклику методів, виходячи з непідготовленого введення користувача.
- Використання глобальних змінних для повернення із функції більше одного значення.
- Класи з одним методом і набором полів, яким необхідно встановити значення, по суті, передачі параметрів метод.
- Оновлення пов'язаних даних у БД без використання транзакцій.
- Спроби відновити стан бази даних без транзакцій та rollback.
Лікування
Уявіть, що ваша програма – вода. Вона може проникнути через кожну тріщину і наповнити будь-яку западинку, так що вам потрібно думати про наслідки того, що вона може текти деінде, крім місць, які ви для неї побудували.
- Ті, що зупиняють виконання програми до того, як заподіяно якусь шкоду тим, що сталося щось несподіване, а потім допомагають вам визначити, що саме пішло не так (системи типів, assert'и, exception'и).
- Ті, що направляють програму шляхом, який найкраще обробляє несподіванки (try-catch блоки, мультиметоди (multiple dispatch), подієво-орієнтоване (event-driven) програмування).
- Ті, що зупиняють thread до досягнення необхідного стану (інструкції WaitUntil, м'ютекси та семафори, SyncLock'і).
Використання цих механізмів має бути для вас так само природно, як і розміщення ком в пропозиції. Щоб досягти цього, пройдіться по перерахованих у дужках механізмах і відрефакторте якусь стару програму так, щоб вона використовувала їх скрізь, де тільки зможете їх прилаштувати, навіть якщо це виявиться неприйнятним (особливо якщо це виявиться неприйнятним, тільки так ви почнете розуміти чому) .
Незнання принципів безпеки
Якщо такі симптоми були б такі небезпечні, це було б швидше питання «оздоблення», «полірування» більшість програм. Що означає, що якщо вони у вас проявляються, то ви не обов'язково поганий програміст. Просто ви програміст, якому не слід працювати над мережевими програмами або безпечними системами, доки ви не попрацюєте над своїми недоліками.
Симптоми
- Зберігання важливої інформації (імена, номери кредитних карток, паролі) без шифрування.
- Зберігання важливої інформації з використанням неефективних засобів шифрування (симетричні коди з ключами, вбудованими в саму програму; прості паролі; шифри підстановки; самостійно розроблені та неперевірені коди).
- Програми, які не обмежують власних привілеїв перед тим, як приймати мережеві з'єднання або інтерпретувати вхідні дані з ненадійних джерел.
- Невиконання перевірок кордонів та інших перевірок вхідних даних, особливо у некерованих оточеннях.
- Створення SQL-запитів конкатенацією рядків із необробленими вхідними даними.
- Код, який намагається запобігти використанню вразливості, намагаючись знайти характерні особливості застосування цієї вразливості.
- Номери кредитних карток та паролі хешуються без солі.
Лікування
Тут перераховані лише основні принципи, але вони дозволяють уникнути найбільш кричучих помилок, які можу скомпрометувати всю систему. Для будь-якої системи, яка обробляє або зберігає інформацію, цінну для вас чи ваших користувачів, або керує цінним ресурсом, завжди запитуйте рецензію вашого дизайну та реалізації у спеціаліста з безпеки.
Почніть аудит власних програм з коду, який зберігає вхідні дані в масив або інші виділені області пам'яті. Переконайтеся, що існують перевірки того, що розмір вхідних даних не перевищує розмір виділеної під них пам'яті. Немає іншого класу помилок, який би викликав таку величезну кількість «дір» у безпеці, як переповнення буфера. А це означає, що ви повинні серйозно розглядати керовані мови та оточення, коли пишете мережеві програми, або у будь-якому іншому місці, де безпека не на останньому місці.
Далі, перевірте запити до баз даних, які конкатенують незмінені вхідні дані в SQL запит, і перепишіть цей код за допомогою параметризованих запитів, якщо це дозволяє ваша платформа.Ну, або додайте фільтрацію/екранування всіх вхідних даних, якщо ні. Це щоб запобігти атакам з SQL-ін'єкціями.
Після того, як ви позбулися двох найбільш сумнозвісних класів помилок, пов'язаних з безпекою, ви повинні почати думати про всі вхідні параметри програми як про ненадійні та потенційно небезпечні. Дуже важливо визначити допустимі значення вхідних аргументів у вигляді працюючого коду, що валідує. Ваша програма повинна відкидати вхідні дані, якщо вони не проходять валідацію, тоді ви зможете лагодити «дірки», виправляючи валідацію, роблячи її більш детальною замість того, щоб шукати у вхідних даних характерні для тих чи інших уразливостей особливості.
Ви завжди повинні думати про те, які операції повинні виконати вашу програму, яких привілеїв вони вимагають. Ви повинні думати про це ще до початку розробки, тому що це найкращий спосіб з'ясувати, як написати програму, використовуючи мінімально необхідну кількість привілеїв. Сенс цього полягає в тому, щоб обмежити шкоду решті всієї системи, якщо раптом у вашій програмі знайдеться вразливість. Іншими словами: якщо ви перестали довіряти вхідним даним, вам потрібно навчитися не довіряти і своїм власним програмам.
І останнє: вам потрібно вивчити основи шифрування, починаючи з принципу Керкгоффса. Він може бути сформульований як "безпека має бути укладена в ключі". Також існує кілька цікавих висновків, які ґрунтуються на цьому принципі.
По-перше, ви не повинні довіряти коду або іншому криптографічному примітиву, якщо він не опублікований відкрито і не був проаналізований та випробуваний спільнотою.Не можна досягти безпеки через неясність (security through obscurity), через пропрієтарність або через новизну. 10 років або більше, і вам добре б використовувати ті з них, що здалися з іншого боку цієї «труби» неушкодженими.
По-друге, якщо ключ слабкий або зберігається неналежним чином, то це так само погано, як якщо б не було ніякого шифрування зовсім. тільки публічного ключа з асиметричної пари, а розшифровку виконуйте окремо, використовуючи приватний ключ, що знаходиться в сховищі під надійним паролем, який користувач повинен вводити щоразу.
Чим більше на кону, тим більше ви повинні готуватися і тим довше ви повинні проектувати вашу програму.
Частина помилок, що залишилася в безпеці, зазвичай зводиться до дурних помилок, більшість яких можна успішно уникати, перевіряючи вхідні дані, консервативно використовуючи ресурси, покладаючись на здоровий глузд і розробляючи програму зі швидкістю, що не перевищує швидкість, з якою ви можете про неї міркувати.
Ознаки того, що вам не варто було б бути програмістом
Наступні «хвороби» невиліковні. Тому якщо ви все ще страждаєте ними після шкільного курсу програмування, вам краще спробувати себе в іншій професії.
Нездатність визначити порядок виконання програми
Симптоми
print a
Ви дивитеся на цей код і не впевнені, яке саме число буде надруковано.
