Ошибка №7. Операции над указателями. Арифметика.
Запись от steelcraft размещена 27.06.2024 в 01:46
Показов 5330
Комментарии 75
|
Указатели, пожалуй, самая интересная тема в языке C. Собственно, больше ничего интересного в нем и нет, все остальное очевидно и просто. Именно указатели придают этому языку его силу и одновременно опасность. Неудивительно, что большинство ошибок на собеседованиях вызывает именно эта тема. Итак, очередной вопрос: перечислите операции над указателями. Как правило, операции поименования (&) и разыменования (*) проблем не вызывают. Далее черед доходит до адресной арифметики. Тут появляются первые симптомы: есть некоторое количество кандидатов, которые вообще не знают, что это такое. Как правило, это люди, которые специализируются в области электроники, а на C пишут лишь небольшие фрагменты, чтобы проверить работоспособность макета. В продукцию этот код не идет. В этом случае на этом дискуссию сворачиваем и переходим ко второй части собеседования - по электронике (за редким исключением эмбеддеры собеседуются по двум дисциплинам сразу). Бывает и такой ответ: поскольку указатель - это адрес, а адрес - это целое число, то над указателями можно делать любые арифметические операции. Определенная логика тут, конечно присутствует (о том, является ли указатель в действительности адресом, поговорим отдельно), но возникает вопрос: какова семантика результата? Что дает перемножение, деление или сложение адресов (про вычитание пока молчок, это отдельная тема)? Типичная реакция - пожимание плечами. Те, кто изучал язык более тщательно, называют еще две допустимые операции: прибавление/вычитание целочисленной величины к указателю. Тут кроются еще две тонкости (правда, все же относительно толстые). 1. Каков результат прибавления целой величины k к указателю p? Плохой ответ: указатель смещается на k байтов относительно исходного положения. Хороший ответ: величина умножается на размер типа, на который указывает p, и полученное число используется как смещение указателя. Для вычитания верно то же самое. Вопрос довольно легкий, и с ним успешно справляется довольно большое число кандидатов. 2. При каком условии полученное новое значение указателя валидно? Тут обычно дело гораздо хуже, лишь небольшое количество кандидатов дает правильный ответ. Это уже показатель продвинутого уровня и дает возможность претендовать на миддла. Правильный ответ: если указатель указывал на элемент некоторого массива, и после смещения продолжает указывать на элемент этого же массива или на ячейку памяти непосредственно за концом массива, такая операция валидна. В противном случае возникает неопределенное поведение. В стандарте ISO/IEC 9899:2018 эта ситуация описана в разделе 6.5.6 "Additive operators", п. 8 (стр. 67). Итак, приходим к соглашению: к указателю можно прибавить (либо вычесть) целочисленное значение, и при определенных условиях мы получим новое значение указателя, смещенное на несколько элементов относительно исходного. Умножение, деление и сложение указателей не имеет никакого смысла. Вычитание указателей я пока обхожу, это тема отдельного вопроса. |
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 75
Комментарии
-
Ну в общем тут на Западе абсолютно другой подход к собеседованиям. Первое обычно вообше не касается технических вопросов а выясняется совпадение интересов человека и конторы. Второе обычно базово-техническое - т.е. общие вопросы на предмет выяснения уровня инженерного мышления. Третье уже с командой в основном то же самое общие вопросы но уже более в конкретике проекта. В конце обычно небольшой тест по работе с кодом. При этом есть или нет сенс продолжать становится понятно уже на первом-втором собеседовании. Если уровень мышления кандидата выше уровня мышления тимлида который собеседует то уже сразу забракуют - ищи себе по уровню или организовывай контору своего уровня.
Сообщение от steelcraft
Собеседуют при этом обычно менеджер а второе собеседование менеджер и тим-лид тима в коорый планируют брать.
Хотя это опять же касается в основном мелких в плане команд разработки контор которые ищут людейй на джоббордах.
Крупные те просто ежегодно приезжают в универы и вербуют всех лучших выпускников (а с учетом что рядом с универами обычно технопарки в котоорых лаборатории этих контор и гнездятся то преддипломники у них и практику проходят преддипломную и дипломы уже на их темы пишут - т.е. вникают в суть именно их проектов еще перед дипломом) и потом стараются делать так чтобы им никуда уходить не хотелось.Запись от Fulcrum_013 размещена 30.06.2024 в 17:24
-
Да, я использовал это слово без пояснений, оно дезинформирует. У нас в иерерхии лаборант (он же стажер) - это предынженерная ступень. Недоинженер, которому порой нужно передвигать ноги. Способен причинять пользу, но под внимательным надзором. Так что разработка входит, более того, это его основное занятие.
Сообщение от Fulcrum_013
Когда наберет достаточный скилл, чтобы самостоятельно и качественно решать хорошо специфицированную и детализированную задачу, он становится джуниором (младшим инженером).
Увы, IDE тут ничего не решает, это всего лишь продвинутый текстовый редактор с кнопочками сборки проекта и вызова отладчика. Проблема глубже.
Сообщение от Fulcrum_013
Модульные тесты по определению должны выполняться изолированно, без обращения к зависимостям. Все обращения к другим модулям должны заменяться на вызовы мок-объектов. В объектно-ориентированных языках это делается элементарно, за счет полиморфизма и принципа подстановки Лисков. В C это реальная проблема, поэтому полноценные инструменты модульного тестирования для C можно пересчитать по пальцам одной руки, и еще останутся свободные пальцы.
Сообщение от Fulcrum_013
Опять же проблема шире. По определению рефакторинг должен полностью сохранить функциональность исходного кода. Если код не покрыт автоматическими модульными тестами, то убедиться, что изменение является именно рефакторингом, сложно и трудоемко. Мартин Фаулер в своем букваре по рефакторингу писал:
Сообщение от Fulcrum_013
Поэтому вместо формулы "нужны тесты будут тесты" больше подходит другая: "есть тесты - будет рефакторинг".
Впрочем, тестирование и рефакторинг - это отдельные разделы собеседования, после азов языка.Запись от steelcraft размещена 30.06.2024 в 17:54
-
А как он диплом получил если он недоинжинер? Бакалавр на местном наречии означает одиночка - т.е. диплом бакалавра уж покаазывает что он умеет решать весь спектр задач самостоятельно. Магистр (Мастер по местному) уже способен решать более комплексные задачи руководя группами бакалавров. Это диплом и подтверждает. Или вы туда без диплома набирает после курсов? Так это фэйл для эмбеддеда. Это бугалтерию считать и в банках косячить селф-мейд мэнс как то могут. А для эмбеддеда нужен очень высокий уровень и фундаментальных знаний и практическийх умений как и для всей автоматики. Тут без университетского образования по специальности никак.
Сообщение от steelcraft
Как бы объектно-ориентированный язык или нет относится к поддержке компиляором проверки правил Лескоу а не к возможнстям их использовать. Подавляющее большинство софта на С кстати написано в объектно-ориентированном стиле а не в классическом процедурном (кстати почему Сртауструп и начал его с Симулой сращивать - кода С как такового уже не было были сплошной макрос-хэлл имитирующий поддержку ООП ядром). Но даже в том же процедурном замена любой функции заглушкой производится элементарно подменой модуля зависимости на модуль с заглушками. На самом деле заглушки пришли из С и именно разделение юнита трансляции на хидер и код именно это и имело одной из главных целей. Тут вопрос в модульности а не в принципах Лескоу. Модулем же в С является каждая функция, а соответссвенно подменить вызова зависимостей заглушками вообще не проблема. Во всяком случае кода кааждый слой зависимостей выделен в отдельные юниты трансляции.
Сообщение от steelcraft
Строго говря рефакторинг обычно нужен чтобы привести архитектуру в соответтсвие. А соответсвенно если интерфейсы меняются то и код функций тоже. Остаются неизменными только алгоритмы не касающиеся архитектурной части. СОбственно их обычно и тестируют.
Сообщение от steelcraft
Кстати основное что проверяют по тестам - это понимние того что тесты вообще ничего не гарантируют. Поэтому все эти бехавиор и т.д. тесты с ккаким то там покрытием кода после - это ни о чем. Они могут показать ВНИМАНИЕ! не то что код написан правильно и т.д. а то что переход на другой компилятор не превел к недопустимім изменениям. А для контроля качества кода они абсолютно бесполезны. Для этого нужно брэнч-тэестирование , которое зависмо от внутренней реализации, со 100% покрытием всех веток. Но и то оно опять же ничего не гарантирует, оно помогает ОТЛАЖИВАТЬ код. А именно показывает не только что что то неправильно но и где именно. А это делается в любом случае в процессе написания кода. Если не автоматические тесты то ручные в любом случае будут.Запись от Fulcrum_013 размещена 30.06.2024 в 18:26
-
Мы ничего не пропустили? Сделать постановку задачи с нуля (с голого ТЗ а то и сам ТЗ сначала) - это и есть основная задача инженера-программиста. Реализация в коде это финальная часть. Всему этому собстввенно говоря 5 лет в универе и учат. Потому что водопад с разделением на гуру-архитекторов и обезьян-быдлокодеров тут не работает -для реализации в коде и отладки необходимо понимать всю полноту постановки на уровне архитектора. А сответсвенно и рапараллеливание работы идет не по стадиям одной задачи, а по подсистемам/подзадачам/модулям/библиотекам (компонентам). Это собственно говоря и называется Эджайл и именно поэтому ко всем кандидатам выдвигается требование скила фулл дэвэлопмэнт лайфцикл. Кстати основным драв-бэком эджайла называется то что для того чтобы он был эффективен все разрабы должны быть одинаково высокого уровня. Хотя конечно с нашим подходом хуяк-хуяк и в продакшин - это просто бледная породия, а в купе с подходом американского (майкрасофто-гугло-эппловского) менджемнта стремящегося к мифическому снижению порога вхождения, все это превращается в срамо-облажайл и получается вооще полный 3,14здец поднимающийся для индустрии в полный рост.
Сообщение от steelcraft
Запись от Fulcrum_013 размещена 30.06.2024 в 18:57
-
Делаем поправку на то, что я их не из MIT набираю. В местных реалиях все свелось к тому, что из и без того неидеальной 5-летней программы вырвали год обучения, в оставшиеся 4 года кое-как напихали, что уместилось. Что не уместилось - выкинули. Я сначала думал, что меня дурят, когда бакалавр физики заявил, что они не проходили квантовую механику. Навел справки - а ее действительно нет в программе.
Сообщение от Fulcrum_013
Тут две проблемы. Во-первых, делать подмены для каждого тестируемого модуля вручную долго, трудоемко и чревато ошибками. Один раз для проверки только что написанного кода это еще терпимо. Поддерживать такой сценарий сборки проекта для регрессионного тестирования при непрерывной интеграции нереально. Нужен автоматический инструмент.
Сообщение от Fulcrum_013
Во-вторых, заглушки позволяют тестировать только самые простые случаи. Для полноценного тестирования нужны более сложные подставные функции, а они сложны, и поэтому могут сами содержать ошибки. Опять же нужен инструмент.
К счастью, такой инструмент есть, ребята из Atomic Object разработали и поделились.
Тест гарантирует (хотя я предпочитаю слово "демонстрирует"), что в определенных условиях вызов функции дает ожидаемый результат и ожидаемые побочные эффекты. Это гораздо больше, чем ничего. Если набор тестов сделан как выполняемая спецификация, он позволит выполнить рутинную часть проверок автоматически, освобождая тестировщика для исследовательского и подобных видов тестирования, где человек пока еще лучше машины.
Сообщение от Fulcrum_013
Запись от steelcraft размещена 30.06.2024 в 19:16
-
Инженер, обладающий навыками аналитика и архитектора, в нашей иерархии находится на уровне миддла. Именно он способен декомпозировать сложную задачу на простые, раздать спецификации джунам и проконтролировать соответствие результата. Те тащат на себе весь код, используя стажеров как вспомогательную рабочую силу, одновременно осуществляя надзор.
Сообщение от Fulcrum_013
Очевидно, что набрать всю команду из одних миддлов не получится: их столько нет, да и бюджета не хватило бы. Это как армия с солдатами не ниже полковника.
Этот подход предлагаю не обсуждать (ибо пустая трата времени), поскольку я бесконечно далек от уровня руководства и ничего менять не могу, даже если бы знал как. Все, что могу, - это по достоинству оценить возможности конкретного кандидата и определить его место в этой лестнице, чтобы он приносил максимальную пользу и при этом не был недооценен.
Я работаю с тем материалом, что реально есть, а не с тем, что должно было бы быть, если бы...Запись от steelcraft размещена 30.06.2024 в 19:34
-
Ну как бы физиков в программисты автоматики брать это не годится. Даже если в плане прикладной математики они вторые после программистов из все STEM специальностей, то для автоматики тут нужно именно специальное образование. Да и то смотреть надо какое именно. У нас кстати на факультете были кафедры АСУТП (промавтоматика) и ВТ и ПМ (информатика). Так вот те которые АСУТП они программисты вообще по стольку по скольку. Их на самом деле расширенно (по сравнению с остальными просто инжинерами) обучают программированию. Но только для того чтобы имели возможность с программистами на одном языке разговаривать их задача - общее исследование объекта аввтоматизации и построение схем размещения датчиков и силовых приводов не программирование (точно так же как программисты имеют 2 семестра ТАУ чтобы с автоматчиками на одном языке разговаривать). Т.е. по ходу софт разрабатывать они не смогут в принципе. Там математической подотовки не хватит. Она как у обычных инжинеров - 3 семестра на всю высшую математику.
Сообщение от steelcraft
Так что нечего удивляться что люди с других специальностей не потянут. И нефиг пытаться их воткнуть в разработку - у них базис недостаточный.
Строго говоря тестировать без депенденсов это не какое то жесткое требование. Это реалии разработки сверху вниз - т.е. исходить из того что депенденсы еще не разработаны (параллельная разработка компонентов она вся как сверху вниз). Вот и придумали поставщиков данных для тестов в виде заглушек. Но подавляющее большинство подсистем которые делает отдельный тим/команда разрабатываются таки снизу вверх. А соответственно тут уже можно и с подключением реальных поставщиков данных тестировать. Заглушки же остаются на уровне компонентов.
Сообщение от steelcraft
Он вообще ничего не гарантирует. Потому что тест это точно такая же программа которая по сути ничем не тестирована, как и набор данных для нее. Только вот такая штука что тесты эти должны покрывать все внутренние ветки функции. Иначе они вообще ничего не демонстрируют - т.е. быть зависимыми от реализации. Тогда они и с отладкой помогают и т.д. Но и писать их надо вместе с функцией, при изменении кода функции соответсвенно переписывать. Ну и соответсвенно тут все это упростить помогает качественная декомпозиция. Т.е. основное требование - если цикломатическое число графа выполнения функции превышает 5 проводить декомпозицию. Это значит больше 5 тестов на каждую функцию не понадобится.
Сообщение от steelcraft
Запись от Fulcrum_013 размещена 30.06.2024 в 19:52
-
Результат фейл. Потому что если не может полный лафцайкл то это вредитель по определению а не разработчик. Дл того чтобы отладить тот или иной алгоритм его надо понимать. Тут это кстати требование даже к интернам не говоря уже про джунов.
Сообщение от steelcraft
А так у вас получается что наиболее способная часть тима занимается подтиранием задниц обделавшейся неспособной. А соответсвенно разработкой им заниматься некогда. Мало того все приходится делать на быдлокодерском уровне а то джуны/стажеры не потянут. А это всегда куча быдлокода у которой сложность взаимосвязей растет экспоненциально. Соответвенно любой апгрейд требует еще большей толпы которая еще хуже подготовлена . Поднимите порог. Возьмите человек 5 уровня нормальных магистров (это те которые реально диплому соответсвуют) больше вам скорее всего вообще не понадобится. И качество разработки выростет и бюджет сэкономите. Ну или хотя бы мидлов для начала освободите от подтирания задниц некомпитентной части. Здесь кстати в эмбеддед конторах существует обычно два уровня - сеньйоры и интеры/апрентисы сеньйоров. Разница в том что аппрентисы новые в проекте люди которых в конкретику еще вводят (хотя если с докой все в порядке они пока что больше доку читают чем код пишут не отвлекая сеньйоров) обычно один апрентис на 2-3 сеньйора. Ну и да это обычно молодняк после универов. Так да тимы небольшие 4-6 человек которые обычно тянут всю систему.Запись от Fulcrum_013 размещена 30.06.2024 в 20:08
-
Плюс реализовать это в коде, отладить, написать доку и мануалы пользователя - это уровень СТУДЕНТА по специальности Прикладная Математика и Вычислительная Техника, требуемый для получения допуска к экзаменам после ПЕРВОГО СЕМЕСТРА обучения. Это точно такой же порог вхождения в изучение специальности как и знание языка.
Сообщение от steelcraft
Запись от Fulcrum_013 размещена 30.06.2024 в 21:49
-
Тесты бывают разные. Это жесткое требование именно для модульных тестов. Предположим, что модуль A пользуется сервисом модуля B. Если в модуле B появится ошибка, из-за этого при отсутствии изоляции могут провалиться тесты A. А это неправильно, если тесты модуля выдают ошибку, когда в этом модуле ошибок нет.
Сообщение от Fulcrum_013
Вместе со всеми зависимостями модуль прогоняется впоследствии через интеграционные тесты, но они пишутся по-другому и для других целей.
Для этого (подавить ошибки компиляции и сборки из-за еще не реализованных модулей) заглушки подходят идеально. Подходят также для сценариев, которые Месарош в своих паттернах называет "опосредованным вводом". Для тестирования более сложного поведения нужны более развитые инструменты - "шпионы", подставные объекты, поддельные объекты.
Сообщение от Fulcrum_013
Для функциональных, системных и приемочных тестов даже нужно. Для модульных и интеграционных - однозначно нет, по определению.
Сообщение от Fulcrum_013
Для модульных/интеграционных тестов совсем не такая. Линейная структура, классический четырехфазный паттерн. Для системных/приемочных предпочтительнее DSL в стиле Given...When...Then.
Сообщение от Fulcrum_013
Я для краткости не включаю фразу "в используемой мной методике разработки через тестирование" в каждое утверждение для краткости, поскольку не люблю холивары с претензией на истину, но считаю такой подход целостным. Конечно, и заглушками можно обходиться, и зависимости не рвать, и на реальных данных тестировать.
Разных взглядов на тестирование много. Я часто на вопрос "какими инструментами для тестирования кода вы пользуетесь?" слышу ответ: "отладчиком". А во множестве источников (по крайней мере, российских) тестирование часто называют странным обозначением QA.Запись от steelcraft размещена 30.06.2024 в 23:09
-
Главный вопрос что считать модулем. Функцию? Класc? Юнит трансляции? Компонент? Библиотеку? Обычный подход в этом вопросе - именно выходной модуль - т.е. lib/dll/exe. то что внутри тестируется без изоляции.
Сообщение от steelcraft
Бренч тесты не? Во всяком случае пока не надо многопоточную синхронизацию тестировать. При правильном ООП подходе к архитектуре этого абсолютно достаточно.
Сообщение от steelcraft
Это автоматика. Тут данные для тестов может оказаться получить вообще не реально. Неизвестно зарание какой результат должна дать софтина. Все будет на показаниях датчиков в процессе реальной работы. Тут приходится разве что компоненты тестировать чтобы не упороли выход на аварийные режимы. А счет схем обработки это уже подстраивается в продакшине.
Сообщение от steelcraft
Ну тесты - это инструмент отладки как бы.
Сообщение от steelcraft
Вообще то QA - Quality assurance что в данном контексте переводится как контроль качества. К сожалению существует тенденция всю эту баламуть с толпой тестов, которые ничего не тестируют, делать инструментом именно технического контроля а не отладки. Стока дров уже из за этого наломали включая Ариан-5...
Сообщение от steelcraft
В общем если бездумно копировать принципы тестирования качесва аналоговых схем, у которых внутреннего сосотяния как такового нет, на цифровые то 3,14здец гарантирован. А именно оттуда у всех этих модульной интеграционной бехавиор и т.д. баламути ноги и роостут включая изоляцию при тестировнии.Запись от Fulcrum_013 размещена 30.06.2024 в 23:44
-
Запись от CoderHuligan размещена 01.07.2024 в 08:31
-
А вы себе представляете как так тестировать к прмеру такие библиотеки нижнего слоя абстракции как к примеру STL? Там кстати где изоляция при отладке нужна меду методами одного и того же класса, а где и группу классов надо без изоляции. Вы кстати к ней кода нибудь вообще видели какие нибудь юнит или интеграционные или вообще какие нибудь тесты?
Сообщение от CoderHuligan
От в том то и дело что нет - там только иплементейшн-депендент бренч-тестирование работает при ОТЛАДКЕ. А больше ничего и не надо. Поэтому в комплекте тестов и нету.Запись от Fulcrum_013 размещена 02.07.2024 в 14:24
-
Я не знаю как там в плюсах, я только в стадии их постижения. Тема блога все же про Си. Но плюсы взяли всё самое худшее из Си. В Си модуль есть файл. Точнее: В Си вообще-то нет модулей. Файл лишь эмулирует модуль, и то через костыли вида: вместо одного файла по крайней мере требуются 2 файла, заголовочный и с кодом. И в заголовочном нужно поставить костыль от множественного включения. По настоящему в Си модуль есть функция. А в C++ класс есть модуль (как бы). И если будет одна функция на файл (.h и .c), то линкер будет иметь дело с объектными модулями, в которых всего один экземпляр какой-то функции или другими сущностями. Это позволяет снизить время компиляции и не попадать в трудноуловимые зависимости между файлами.Запись от CoderHuligan размещена 02.07.2024 в 16:17
-
Запись от Fulcrum_013 размещена 02.07.2024 в 16:43


