Русский
Русский
English
Статистика
Реклама

Ошибки программистов

Перевод Четыре ошибки программистов, которые я осознал, только когда стал CTO

08.05.2021 14:13:54 | Автор: admin
image

Я работал программистом более пяти лет. Не особо впечатляет, ведь кто-то из вас, вероятно, имеет в три раза больший опыт, но мне нравилось думать о себе как о сениор-разработчике. Звучит серьёзно и солидно, правда?

Однажды мне предложили стать Chief Technology Officer (CTO) в медтех-стартапе. Поработав некоторое время на этой новой должности, я могу обернуться назад и сказать, что не был сениор-разработчиком. Не поймите меня неправильно я по-прежнему считаю, что обладаю отличными знаниями программирования, особенно веб-разработки; но если это так, почему я не думаю, что был сениором?

Всё это из-за четырёх заблуждений, которые у меня были.


Пользователь (?)

1. Пользователь это идиот


Нет, он не идиот.

Да, пользователи работают с приложением неожиданными, часто странными способами.

Да, пользователи могут задавать вопросы, которые кажутся по-настоящему глупыми.

Да, иногда пользователи просят добавить функции, которые кажутся бессмысленными.

Да, пользователи испытывают трудности с функциями, которые кажутся понятными сами по себе.

Пользователь не специалист. Мой врач не требует от меня, чтобы я знал отличия между липопротеинами низкой и высокой плотности. Так почему я привык предполагать, что пользователь знает, каким браузером он пользуется? Это очевидно вам и мне, но моя мама считает, что Google и Интернет это синонимы. Она бы сказала, что не пользуется никаким браузером, потому что использует Google.

Иногда чтобы удовлетворить пользователя мне нужно было переопределять части фреймворков для изменения их стандартного поведения. Иногда мне приходилось добавлять поддержку браузеров, которые я поддерживать не хотел (привет, пользователи Safari). Сегодня это кажется мне глупым, но в то время я действительно думал, что если мне приходится создавать в своём коде обходные пути для удовлетворения требованиям клиента, то в этом виноват клиент.


Выбираем самое лучшее имя для переменной.

2. Мой код это произведение искусства, и он должен быть идеальным


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

Когда мой менеджер по продукту попросил отказаться от юнит-тестов, чтобы увеличить скорость разработки, я испытал гнев разве он не понимает, насколько важны юнит-тесты? У нас не было никакого автоматизированного тестирования, поэтому юнит-тесты оставались единственной надеждой на обеспечение стабильности и отсутствие регрессий в продукте.

Это решение показалось мне недальновидным. Кроме того, он рекомендовал перестать писать документацию и преобразовать код в менее сложную архитектуру (мы могли это сделать, потому что находились в самом начале проекта).

Да, я согласился, что это в какой-то степени ускорит разработку, но был уверен, что это грозит кучей проблем в будущем. Мы потратим кучу времени на устранение регрессионных ошибок, а новая архитектура окажется слишком простой, когда масштаб проекта начнёт расти! И как мы будем знакомить новых программистов с проектом без хорошего readme?

Мы часами обсуждали то, насколько плохо это решение, и сколько оно будет стоить нам в будущем.

Этот проект завершился провалом спустя несколько месяцев, потому что значительно превысил бюджет.

Годы спустя я вынужден признать правду: наша команда совершила огромную ошибку. Мы думали о будущем и позабыли о настоящем. Мы совершенно игнорировали обстоятельства ограниченный бюджет и необходимость создания MVP за короткое время.

Разумеется, замечательно писать код, который ты можешь показывать другим и гордиться. Но ещё лучше успешно завершать проекты. В конце концов, программирование это не искусство.


Отношение моей старой команды к пробованию чего-то нового.

3. Я буду использовать для этого проекта X, потому что знаю его


В моей предыдущей компании мы создавали каждый проект с одинаковым технологическим стеком: Symfony и Angular. Почему? Является ли Symfony лучшим бэкенд-фреймворком? Нет. Может быть, Angular единственный способ создания современного фронтенда? Нет. Мы всегда выбирали эту связку технологий, потому что не знали другие так же хорошо, как эти. Это была наша зона комфорта, но действительно ли неправильно выбирать хорошо известные технологии для новых проектов? Это зависит от разных факторов.

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

Помню проект, в котором самым важным требованием был хорошо работающий WebSocket. Что мы выбрали для создания бэкенда? Symfony, разумеется. Возможно, сегодня реализация WS на PHP будет выглядеть проще, но в то время это было кошмаром. Мы потратили много времени, чтобы заставить его работать. ОЧЕНЬ много. Мы знали, сколько времени (и денег) будет потрачено для создания WS на PHP, но мы отказались от идеи использования Node. Почему? Не могу сказать точно. На Node мы бы создали API в десять раз быстрее, но он не был в технологическом стеке нашей команды.

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


Что я думал о решениях менеджера по продукту.

4. Владелец продукта/менеджер по продукту ошибается, я бы сделал лучше


Когда я работал программистом, мои отношения с менеджером по продукту были натянутыми. Каждый раз когда он говорил мне о новых изменениях в содержании задачи, я думал: Почему ты не можешь сразу сделать свою работу и определиться с задачей до того, как я начну работать? Разве так сложно решить заранее, как должна работать фича?

Это было так наивно, но я действительно считал, что всё так просто. Теперь я полностью понимаю, как сложно спланировать каждую деталь проекта. Нужно учитывать ограничения технологий и бюджета (что на самом деле одно и то же), необходимо думать о пользователях, которые будут работать с твоим продуктом, нельзя забывать о требованиях бизнеса и маркетинга. Иногда некоторые требования неизвестны в начале; иногда меняются обстоятельства у бизнеса, а иногда нужно сначала что-то создать, чтобы понять, что это можно сделать лучше.

Ещё один аспект менеджеры по продукту могут совершать ошибки. Да, всё так просто. Программисты создают баги и PM тоже. Сегодня это кажется мне настолько очевидным. Если бы я был программистом получше, то понял бы это раньше. Вместо того, чтобы пытаться доказать, насколько он ошибается, мне нужно было сосредоточиться на поиске решений.

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

Подведём итог


Для кого-то из вас эти четыре пункта могут оказаться очевидными. Если вы работаете в отличной организованной agile-команде с хорошим руководителем и не забываете основные правила UX, то я искренне рад за вас. Наверно, вы можете быть гораздо лучшим программистом, чем был я. Ведь чтобы быть хорошим программистом, недостаточно только технических навыков. Гораздо важнее понимать, какую ценность ты можешь принести компании, и как это сделать. Теперь я понимаю определение сениор-разработчика следующим образом:

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




На правах рекламы


Подыскиваете VDS для отладки проектов, сервер для разработки и размещения? Вы точно наш клиент :) Посуточная тарификация серверов самых различных конфигураций, антиDDoS и лицензии Windows уже включены в стоимость.

Подробнее..

Из песочницы 11 предпосылок того, что ваш сайт убогий

20.06.2020 12:14:32 | Автор: admin
Сейчас каждой уважающей себя компании следует иметь свой сайт. Иногда это сводится к абсурду: сеть из двух-трёх автомоек в пределах одного города покупает домен, находит дизайнеров и программистов и пилит персональный лендинг. На фоне всего этого растет количество псевдо-дизайнеров и псевдо-программистов, которые после первого более-менее красивого проекта бегут на фриланс и создают сайты, выглядящие, мягко говоря, не очень.

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

1. Главная страница намного красивее других


Это значит, что сайт создавался на отвяжись и основной бюджет был влит именно в главную страницу. В этом случае лучше либо приземлить главную страницу до уровня остальных (это будет глупым решением), либо вложиться чуть больше и допилить другие разделы.

Согласитесь, неудобно после открытия минималистичной главной страницы переходить на страницу Примеры работ или О нас с дизайном эпохи динозавров?

2. Стиль сайта не соответствует сфере деятельности компании


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

Важно сохранить особенности выбранной вами отрасли: где-то нужно подчеркнуть стабильность и спокойствие, где-то динамичность и современность.

Дизайнерам: гуглите цвета и эмоции и отталкивайтесь для начала от этого, а затем действуйте по профессиональной интуиции.

3. Неправильные цвета


image

Красный цвет не подходит для кнопки согласия, а зеленый явно неуместен для предупреждения. Думаем, это очевидно, но порой и такие ошибки встречаются.

4. Много интерактива, всплывающих окон


image

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

То же самое и с формами заявок. Лучше пусть они будут внизу сайта, а по клику пользователь будет перемещаться к ним.

5. У сайта нет адаптивности или даже отзывчивости


image

Большинство пользователей интернета сейчас пользуются мобильными устройствами, поэтому логично сделать сайт удобным для телефона.

Но не стоит указывать дизайнерам делать разные разрешения для сайта, ведь это задача frontend-программистов.

6. Стиль лого не соответствует стилю сайта


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

7. Много или мало разделов


image

Разделов принято делать от трёх, но не более шести. Тут всё максимально просто: много разделов путаница, мало разделов та же путаница.

Постарайтесь сгруппировать некоторые похожие разделы (часто компания выделяет пункты О нас и История) или же, наоборот, раздробить очень большие (убрать Примеры работ из О нас).

8. Много текста


image

За текстом в Войну и мир, пожалуйста! Сайт компании должен быть минималистичным, а с лонгридами без иллюстраций это уже стрёмный журнал, а не канал привлечения клиентов.

9. На главной странице нет ключевого действия


Главная страница на многостраничнике должна быть ещё и посадочной, то есть собирать заявки, ведь первое, что увидит потенциальный клиент, именно она.

Сайт должен помочь лиду эволюционировать в заказчика: сопроводить до формы, подсказать, на что обратить внимание, подстроиться под нужды определённого человека.

10. Нельзя связаться


Люди разные и к каждому нужен индивидуальный подход. Внедрить искусственный интеллект на сайт, конечно, можно, но не рационально. Поэтому лучше дать возможность потенциальному клиенту позвонить вашему администратору или вам самим.

11. Изображения с фотобанков


Касательно этого пункта Максим Ильяхов всё написал за нас:
Чтобы фотограф окупил расходы на одну фотосессию и что-то заработал, он должен за день отснять несколько сотен фотобанкопригодных кадров. Он берет одну модель, несколько смен одежды, визажиста и студию с декорациями. И начинает снимать. Вы покупаете фотографию красивой девушки-туристки, а она же уже была и медсестрой, и стюардессой, и депутатом, и проституткой, и службой техподдержки, и заботливой мамой, и ревнивой подругой, и героиней ваших любимых мемасов

Люди из фотостока полезны, когда вам нужен не конкретный человек, а просто любой какой-то человек. Но если вам подходит любой человек, у вас плохая иллюстрация вы не иллюстрируете, а разбавляете текст. Это значит, что текст слабый, продукт в целом слабый, и единственное, что его украшает это Алена, королева Фотостока.

Автор статьи Арсен Осипян
Подробнее..

Часто встречающиеся ошибки

23.02.2021 00:18:51 | Автор: admin

Решил написать о часто встречающейся ошибке в сетевых приложениях и сетевых устройствах. Постараюсь объяснить проблему, на примере Linux стека. И буду больше рассуждать Абстрактно, пытаясь объяснить принцип. Ведь все приложения разные, хоть суть одна. (Переносят биты туда-сюда. ) И к каждому сетевому приложению, или к сетевому устройству нужен свой подход, чтоб исправить допущенные в нём ошибки.


Проблема заключается в тех маленьких порциях данных, которыми обмениваются системы. Точнее не в самих этих порциях, а в том, как они далее собираются и обрабатываются.

Например, одна система отправляет другой системе фразу Hello World !

Как это можно сделать? Да как угодно. Выбирается любой протокол передачи данных: TCP, MPTCP, UDP. Данные разбиваются на части, которые мы назовём пакетами. И отправляются на конечную систему. (Как именно? Да это абсолютно не важно. )

Важно то, что(и как) конечная система будет делать с полученными данными. Если строка Hello World ! была разбита на два пакета:

Hello - Это содержимое первого пакета.

World ! - А это, уже второй пакет.

То после того, как сетевое устройство начнёт принимать пакеты (они могут быть обработаны самим сетевым устройством) при удачной обработке, они будут переданы далее в сетевой стек Операционной Системы (ОС). (О проблеме на этом этапе будет написано далее. )

Если пакеты попали в Сетевой Стек, то ОС обрабатывает данные пакета последовательно. Это значит, что часть пакета будет указывать, как пакет был доставлен до системы. И мы эту часть, смело пропускаем т.к. это Не важно. Отбрасываем всю часть рассуждений вплоть до важного момента до Сборки данных на транспортном уровне.

В конечном итоге, система должна понять какова правильная последовательность пакетов. Ведь, до системы мог сначала дойти пакет

World ! - Второй пакет.

А потом

Hello - Первый пакета.

И если, ОС не определяла правильную последовательность пакетов. То до приложения пользовательского уровня. Дойдёт такая строка: World !Hello . Разумеется такой подход большинство не устраивает и поэтому протоколы поддерживают номера последовательностей (а также временные метки, но это всё частности, мы будем говорить только о номерах последовательностей и назовём их seq).

Мы уже оперируем такими важными вещами: Данные и seq. Добавим к нашим знаниям, также Размер Данных.Данных и их размера, достаточно, чтоб произвести их отправку через сокет. Но зачем тогда упоминать seq?Тут нужно осознать, что можно предугадать состояние второй системы, которая принимает наш Hello World !

Смотрим на примере Linux и протокола TCP ( Код привожу из ядра Linux-5.10.7 ) В файле tcp_ipv4.c есть функция tcp_v4_fill_cb , которая прольёт свет на происходящее на конечной системе. А точнее, нас интересует

TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +    skb->len - th->doff * 4);

end_seq Это значение используется для указания конца данных пакета. (Любой следующий пакет, должен быть как минимум на единицу больше предыдущего (Для того, чтоб не быть отброшенным до начала копирования данных пакетов из сокета)

Например: Hello - Первый пакета. Размер 6 байт.

Первый пакет, имеет seq = 0x1 и end_seq = 0x7

World ! - Второй пакет. Размер 7 байт.

Второй пакет, имеет seq = 0x7 и end_seq = 0xE

Тогда данные собирутся в строку Hello World !

А вот если

Второй пакет, имеет seq = 0x4 и end_seq = 0xB

Тогда данные собирутся в строку Hello ld !

Символы Wor Будут отброшены. (Это происходит при копировании данных из пакетов, при чтении сокета ) После копирования данных. Через функцию tcp_rcv_nxt_update файла tcp_input.c указывается значение rcv_nxt в структуре протокола struct tcp_sock. Это значение, будет равняться end_seq после копирования всех пакетов в общий буфер (после чтения данных из сокета). (Первое значение rcv_nxt будет установлено сразу после tcp рукопожатия)

Короче говоря: сначала приходят пакеты и передвигается значение end_seqДалее данные копируются в общий буфер, и передвигается значение copied_seq структуры tcp_sock. И после того, как данные из пакетов (буферов сокетов) будут скопированы в общий буфер, произойдёт установка rcv_nxt в end_seq. И итерация повторяется.

Теперь рассмотрим следующее. Что будет если

Первый пакет: seq = 0xFFFFFFF0 и размер 0x64 (100)то

TCP_SKB_CB(skb)->end_seq = (0xFFFFFFF0  + 0x1 + 0 +  0x140 - 0x40);(если  doff = 5)TCP_SKB_CB(skb)->end_seq = 0xFFFFFFF0 + 0x65 = 0x100000055

Т. е. произошло переполнение, и результат end_seq = 0x55 (85 в десятичной)

при этом rcv_nxt = 0xFFFFFFF0 , т. к. ещё копирования данных из сокета не произошло.

Здесь возникает ситуация, когда end_seq < seq

0x55 < 0xFFFFFFF0

А также, можно далее слать пакеты, имеющие большой порядковый номер и больший размер данных пакета. (для того, чтоб влиять на значение skb_len )

Например такой пакет будет корректен.

seq = 0xFFFFFC6E размером в 1000 байт (end_seq = 0x56 )

В этом нет ничего интересного, если не помнить о флаге URG . В Википедии сказано: 16-битовое значение положительного смещения от порядкового номера в данном сегменте. Это поле указывает порядковый номер октета, которым заканчиваются важные (urgent) данные.

И вот тут то, и находятся возможные ошибки. Всё зависит от того, как сетевое устройство обрабатывает urg пакеты. Ошибки могут быть в реализации драйверов. Или в аппаратной части. (при TCP Offload Engine )

При больших значениях seq (близких к целочисленному переполнению),возможности регулировать размер буфера сокета (размером данных пакета),возможностью указать смещение для urg в диапазоне 0-0xffff, установкой значения rcv_nxt.Можно влиять на дальнейшее поведение системы. (на уровне ядра)Добавлю ещё такую информацию. Она не будет лишней.

Проверки номеров последовательностей пакетов, базируются на функциях: after и before. Которые проверяют, где находится число в последовательности "до" указанного числа, либо "после" или "равно".

Вот результаты работы функций с некоторыми числами, как пример.

inline bool before(__u32 seq1, __u32 seq2){   return (__s32)(seq1-seq2) < 0;}#define after(seq2, seq1) before(seq1, seq2)after( 0x80000000,  0x7fffffff ) = 1   after( 0x7fffffff,  0x80000000 ) = 0   after( 0x80000000,  0x80000000 ) = 0  before( 0x80000000,  0x7fffffff ) = 0   before( 0x7fffffff,  0x80000000 ) = 1   before( 0x80000000,  0x80000000 ) = 0  

Как видно, сравнение больше или равно, сводится к вычитанию второго аргумента из первого и сравнения результата с нулём.

В большинстве случаев, с помощью данных функций определяется, как следует поступить с пакетом. Если оказывается, что end_seq имеет номер меньший или равный последнему принятому пакету, то такой пакет отбрасывается.

На примере end_seq < seq

0x55 < 0xFFFFFFF0

В тех случаях, когда происходят математические действия над двумя и более параметрами на которые можно влиять, и сравнение их с каким то числом, то

if(TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq >= какое то число) {Можно зайти сюда } else { или сюда }if(0x55 - 0xfffffff0 >= какое то число)if(0xFFFFFF9B >=  какое то число)

Привожу пример кода из файла chtls_cm.c который может содержать ошибку.

В функция handle_urg_ptr присутствует такой код.

if (skb && tp->copied_seq - ULP_SKB_CB(skb)->seq >= skb->len)chtls_free_skb(sk, skb);

В нем присутствуют три переменных: copied_seq, seq, skb->len на которые можно влиять.

На самом деле нет (из-за особенностей работы устройства, нельзя влиять на ULP_SKB_CB(skb)->seq ). Еслиб можно было влиять на (skb)->seq, тогда можно подобрать такие значения seq, copied и skb->len при которых, сработает очистка буфера сокета и код драйвера, продолжит свою работу.

Далее, рассмотрим такой пример: в файле chtls_cm.c

Есть функция chtls_recv_data в ней присутствует такой код

if (unlikely(hdr->urg))handle_urg_ptr(sk, tp->rcv_nxt + ntohs(hdr->urg));if (unlikely(tp->urg_data == TCP_URG_NOTYET &&     tp->urg_seq - tp->rcv_nxt < skb->len))tp->urg_data = TCP_URG_VALID |       skb->data[tp->urg_seq - tp->rcv_nxt];

Сразу можно обратить внимание на вызов handle_urg_ptr(sk, tp->rcv_nxt + ntohs(hdr->urg)); Где находятся два аргумента tp->rcv_nxt + ntohs(hdr->urg) .

rcv_nxt можно предсказать, а hdr->urg установить в пакете. Таким образом, пердав какое то число в функцию handle_urg_ptr для дальнейшей обработки. Но это не так кретично, как следущий код.

if (unlikely(tp->urg_data == TCP_URG_NOTYET &&     tp->urg_seq - tp->rcv_nxt < skb->len))tp->urg_data = TCP_URG_VALID |       skb->data[tp->urg_seq - tp->rcv_nxt];

Тут снова видим tp->urgseq - tp->rcv_nxt < skb->len , два числи на которые может воздействовать отправитель пакетов, сравниваются с значением размера данных сокета, который также указывается отправителем (через количество отправляемых данных). А далее skb->data[tp->urg_seq - tp->rcv_nxt];

Снова два значения, устанавливаемые удалённо tp->urg_seq - tp->rcv_nxt. Обратятся, к данным по индексу - ???

tp->urg_seq - tp->rcv_nxt < skb->len Данное условие создаёт иллюзию, что при обращении к массиву skb->dataurg_seq - tp->rcv_nxt  Будут находиться, внутри массива данных сокета.И не могут быть больше skb->len, ведь чуть выше делалась проверка tp->urg_seq - tp->rcv_nxt < skb->lenВобщем,  в суровой реальности индекс массива может бытьskb->data[0xffffffff];skb->data[0xfffffff0];skb->data[0xffffff00]; и тд.

Это приводит к чтению памяти, по указному индексу. Либо к зависанию системы.

Далее ещё один пример.

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

Фактически, можно произвести тестирование "черного ящика" но с допущением, что проверяться будут различные условия для порядковых номеров пакетов.

Когда устройство делает аппаратную обработку tcp пакетов, то предполагается что взаимодействие клиент/сервер происходит, по стандартному сценарию. Когда все действия систем перекладываются на сетевой стек. Все данные имеют, порядковые номера указываемые сетевой подсистемой (временные метки, размер пакетов и тд.). Но если, пакеты сформированы вне "системы", то есть огромная вероятность, что что-то пойдёт не так. Ведь, когда программист тестирует сетевое приложение (или аппаратуру), то он не выходит из стандартной схемы тестирования. Берёт приложение, или пишет его сам. Создаёт сокет и шлёт данные. Как именно шлются эти данные, программисту не важно. В этом проблема. Люди больше концентрируют внимание на том, какие именно данные шлются, а не на том, как они отправляются.

Пример ошибки с индексом массива, невозможно найти в обычной схеме тестирования. Через отправку произвольных данных.

А когда тестируется сетевое устройство, то после ошибки обработки данных (или не ошибки) в устройстве. Оно может передать в драйвер не корректные данные. Которые по сути, никак не могли появиться. (в теории) (Но если вспомнить о проблемах проверки порядковых номеров. То вероятность обнаружить ошибку, резко возрастает)

Вот пример: в файле chtls_main.c

Есть функция chtls_recv , она работает с пакетом который уже был обработан сетевым устройством.

void chtls_recv(struct chtls_dev *cdev,       struct sk_buff **skbs, const __be64 *rsp){struct sk_buff *skb = *skbs;unsigned int opcode;int ret;opcode = *(u8 *)rsp;   // Тут находится ОШИБОЧНЙ ОПКОД__skb_push(skb, sizeof(struct rss_header));skb_copy_to_linear_data(skb, rsp, sizeof(struct rss_header));ret = chtls_handlers[opcode](cdev, skb); // Вызов функции по, не правильному опкодуif (ret & CPL_RET_BUF_DONE)kfree_skb(skb);}

После обработки пакета устройством, сетевая карта передаёт драйверу опкод операции которую должна выполнить система.

opcode = *(u8 *)rsp; Содержит опкод инструкции, которую будет выполнять система.

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

В данном примере

ret = chtls_handlers[opcode](cdev, skb);

Будет выполнена функция по адресу NULL. Что приведёт к зависанию системы.

И такие ошибки остаются не замеченными ГОДАМИ.

Также скажу, что пытался рассказать о проблеме на примере TCP и флага urg. Но точно такие же проблемы, можно обнаружить и при сборке UDP пакетов (везде. не важно, драйвера или приложения прикладного уровня, или сетевые устройства). Сколько сетевых устройств подвержено данной проблеме, не знаю. Думаю, что очень не мало.

Проверял всего одно устройство (которое было на руках). Результат, удалённый вызов нулевого указателя в ядре. Отказ в обслуживании. ( + доступ к памяти системы, в определённых диапазонах) Писал производителю о проблемах, но им это не интересно, проигнорировали и выпустили новый флагман) с теми же проблемами.

На этом пока всё.

Подробнее..

Почему ты не учишь английский язык?

13.04.2021 22:15:19 | Автор: admin

Часто ли вы натыкались в вакансиях на слова "English B2" / "Intermediate English" / "Английский на уровне чтения документации" и задавались ли вы вопросом, почему это резко стало так важно? Сейчас действительно наблюдается тенденция, что больше и больше компаний выделяют английский язык как требуемый навык, несмотря на то что команда полностью русскоговорящая и с иностранными заказчиками не работает.

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

Сегодня я как раз хочу поговорить об этом. Эта статья будет интересна тем людям, кто задумывается, стоит ли сейчас тратить время на изучение английского.

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


Я смогу выучить, когда он мне понадобится

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

Да, тебе не нужно знать многие грамматический конструкции, и не так уж надо уметь говорить на языке, но документация написана сложным техническим языком с использованием специфических терминов. Если ты изначально не привыкнешь что массив - это array, а переменная - это variable, то потом будет тяжело покрывать весь этот объем слов, и ты просто будешь спотыкаться на каждом слове в какой-нибудь статье.

Да и в работе момент, когда "понадобится" наступит очень быстро. Когда будут возникать какие-то теоретические вопросы, тебе могут скинуть англоязычную статью или часть документации, который тебе придется как-то читать. Но без знаний и практики конечно это будет медленнее, чем могло бы быть.

Большинство вещей, которые мне могут понадобиться, уже переведены на русский язык

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

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

MDN - один из самых популярных ресурсов для чтения документации по JavaScript

Давайте зайдем на статью по методу window.scroll, она довольно часто используется для прокрутки.

Русская версия
Обратите внимание на пераметрыОбратите внимание на пераметры
Английская версия
Параметры уже немного другие или мне кажется?Параметры уже немного другие или мне кажется?

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

Nuxt - SSR фреймворк для Vue

У Vue замечательная документация, которая действительно хорошо переведена. Чего не скажешь о Nuxt. Если сейчас переключить на русский, то вы можете увидеть подобную картину:

Давайте же попробуем почитать
Ну в общем-то все понятноНу в общем-то все понятно

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

Английский - это международный язык разработки, самая актуальная и верная информация будет именно на нем.

Русских разработчиков так много, что я смогу найти ответ на любой вопрос

Когда что-то не получается, человек идет задавать вопросы гуглу. Кто знает английский язык, тот задаст на английском, а кто не знает - будет задавать на русском. Как вы думаете, кто быстрее найдет ответ?

Большая часть вопросов на том же stackoverflow написана на английском, большая часть issues в пакетах на github написана на английском. Как я уже говорила выше, этот язык - международный в плане разработки, а значит, задавая вопрос на английском, вы получаете доступ к мировой базе информации, большему количеству кейсов и огромному количеству ответов и решений.

Я буду работать с русскоговорящими людьми, зачем мне понадобиться английский

Есть стандарты того, что код оформляется на английском языке. То есть названия переменных - это не русская транскрипция, а английские слова. Комментарии к коду часто пишут на английском. Грубо говоря, если ты видишь переменную width, ты быстро понимаешь, что это связано с шириной. Человек же не знакомый с этим языком, будет дольше по времени читать программу.

Работа с git тоже часто происходит именно на английском: те же названия веток и коммиты. И даже если ты не используешь иностранный язык, другой человек в команде может, и читая историю коммитов не получится быстро сориентироваться.


Надеюсь я убедила вас, что английский надо начинать учить как можно раньше и развеяла ваши заблуждения, если они у вас были.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru