Вопросы кандидатам при собеседовании

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Вопросы кандидатам при собеседовании

Сообщение serbod » 26.12.2017 13:25:54

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

темы вопросов

  • побитовые операции (чтение, изменение битов, битовая маска, сдвиг)
  • структуры (record, packed record)
  • указатели (Pointer, PChar, @, ^, арифметика указателей)
  • параметры var, const, out
  • исключения (try, except, finally)
  • управление памятью (стек, куча, выделение, освобождение, как избежать проблем (array, string))
  • проектирование классов (private, public, property read write)
  • управление объектами (создание, хранение и передача, освобождение, счетчик ссылок)
  • контейнеры данных (TList, TStringList, TObjectList, TCollection)
  • компоненты приложения (TForm, TFrame, TDataModule, TActionList, TApplicationEvents, TListView, TTreeView, режим OwnerData)
  • сериализация (маршалинг) данных
  • хранение, отображение, экспорт больших таблиц (больше миллиона строк)
  • многопоточность, TThread.Execute, Synchronize
  • потокобезопасность переменных, атомарные операции, TCriticalSection, семафоры (TEvent)
  • файлы и устройства ввода-вывода (Open, Read, Write, IOCtl, Close), TStream
  • последовательный порт, UART
  • сокеты, TCP, UDP
  • SQL, первичный ключ, индексы
  • отладка, удаленная отладка, отладка по фотографии
  • сборка дистрибутива (Inno Setup)
  • ведение документации




побитовые операции

  • чтение - операция and с маской из проверяемых битов
  • установка - операция or с маской из устанавливаемых битов
  • снятие - операция and с инвертированной маской снимаемых битов (операция not)
  • сдвиг - операции shl, shr для получения числового значения определенной части двоичного числа. Увеличивает/уменьшает число в 2 раза на каждый бит сдвига. Неопределенные биты обнуляются.

..или использовать TBits

структуры

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

указатели

  • Pointer - переменная, указывающая на адрес в памяти, нетипизированный указатель. Типизированный указатель указывает на начало данных определенного типа.
  • PChar - указатель на начало массива (строки) символов любого размера, с завершающим нулем.
  • @ (в начале имени) - взятие адреса, превращает переменную в указатель
  • ^ (в конце имени) - разыменовывание указателя, превращает указатель в переменную
  • арифметика указателей - на указатель можно применять функции Inc() и Dec() для изменения адреса. Изменяя адрес кратно размеру элемента массива, можно получить указатель на требуемый элемент. Не рекомендуется этим пользоваться без особой необходимости.

параметры

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

Для типов, занимающих память больше машинного слова (record, array, string, int64) рекомендуется использовать модификаторы:

  • var - параметр передается как указатель (ссылка) изменение параметра внутри функции видно снаружи.
  • const - параметр передается как указатель (ссылка) и защищен от изменений.
  • out - то же, что и var, но предназначено только для чтения данных из функции

исключения

Ошибка в блоке try приводит к переходу в блок except, где можно предусмотреть ошибку или сообщить подробности об ошибке.

Блок finally выполняется в любом случае (была ошибка или нет), поэтому он используется для обязательных завершающих операций - возврат памяти, закрытие файлов.

управление памятью

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

Куча (heap) - память выделяется и возвращается в произвольном порядке менеджером памяти. Используется для динамических массивов, строк, объектов. Работает медленней, чем стек.

Выделение памяти (GetMem() или New()) должно обязательно сопровождаться освобождением (FreeMem(), Dispose()), желательно внутри конструкции try .. finally. Иначе возникает утечка памяти.

Для избежания проблем с утечками памяти рекомендуется использовать динамические массивы (array, string), контейнеры объектов (TObjectList, TComponentList), подсчет ссылок (IInterface).

проектирование классов

  • секция private - доступна только внутри класса, переменные и функции для собственных нужд
  • секция public - доступна всем
  • модификатор abstract задает описание метода, который должен быть реализован в классе-наследнике
  • модификатор virtual разрешает переопределять метод в классе-наследнике с тем же описанием
  • модификатор override переопределяет метод, описанный в классе-предке с тем же описанием
  • модификатор reintroduce переопределяет описание метода класса-предка
  • inherited в коде метода вызывает метод класса-предка
  • property - свойство, может ссылаться на поле (переменную) или на метод класса. Модификатор read определяет поле/метод для чтения значения, модификатор write определяет поле/метод для установки значения.
  • создаваемые внутри класса данные должны быть доступны в public только как read-only property, для избежания повреждения

управление объектами

Объекты создаются из классов методом класса Create() и освобождаются методом объекта Destroy()

Переменная объекта имеет тип класса и является указателем на область памяти, выделенную экземпляру класса. Объекты всегда передаются по ссылке (var).

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

контейнеры данных

для хранения данных есть стандартные контейнеры:

  • TList - массив нетипизированных указателей с сортировкой
  • TStringList - массив строк (с разбивкой на имя-значение) с поиском, сортировкой, привязкой объекта.
  • TObjectList - массив объектов, с сортировкой и очисткой при удалении из списка
  • TCollection - набор однотипных значений без сортировки, но с обратной связью (при изменении значения)

компоненты приложения

  • TForm - визуальная форма в виде отдельного окна
  • TFrame - визуальная форма не имеющая своего окна, для встраивания в другие формы
  • TDataModule - невизуальная форма, для невизуальных контролов и манипуляций с данными
  • TActionList - список действий TAction, которые можно назначать стандартным контролам (кнопкам, меню, итд)
  • TApplicationEvents - обработчики по умолчанию для разных событий приложения (например, любых исключений)
  • TListView - визуальный список значений, в режиме Report отображается как таблица
  • TTreeView - визуальное дерево значений
  • режим OwnerData для TListView и TTreeView позволяет не добавлять элементы, а отображать любое количество «пустых» элементов. При отображении элемента в окне, его данные запрашиваются в обработчике OnData.

сериализация

Сериализация (маршалинг) данных - это последовательная запись множества данных в текст или файл (для передачи по сети), с последующей десериализацией - чтением из текста/файла в исходное состояние. Важно при этом сохранить целостность данных - последовательность и размер полей, кодировку текста. Для внутренного использования предпочтительны бинарные форматы, для экспорта-импорта - текстовые (XML, JSON).

большие таблицы

Структурированные данные занимают много места в памяти и требуют значительного времени на инициализацию. Поэтому для больших объемов необходимо использовать либо базу данных, либо виртуальные таблицы, где данные по мере обращения к ним запрашиваются/вычисляются, например, из memory-mapped file. Зная номер строки и колонки, мы можем найти нужные данные в файле. При экспорте больших таблиц, следует использовать потоковый экспорт в файл нужного формата, например xls вместо экспорта в открытую таблицу Excel.

многопоточность

Все, что внутри TThread.Execute() выполняется в фоновом потоке. Методы Create(), Destroy() и остальные выполняются в основном (вызывающем) потоке, поэтому весь код фонового процесса, включая инициализацию и финализацию объектов, необходимо размещать внутри Execute(). Метод Synchronize() останавливает поток и передает выполнение указанного в параметре метода в основной поток приложения. Нельзя из TThread использовать внешние визуальные (и не только) объекты без синхронизации. Лучше вообще из TThread ничего внешнего не использовать.

потокобезопасность переменных

  • Переменные размером с машинное слово или меньше - потокобезопасны, но не атомарны.
  • Атомарные операции (InterlockedIncrement, InterlockedExchange, итд) блокируют доступ других потоков к переменной на время ее изменения.
  • TCriticalSection создает межпоточную блокировку, кабинку, «войти» в которую может только один поток за раз, остальные будут ждать, пока блокировка освободится.
  • Семафоры (TEvent) - может быть установлен (Set) или снят (Reset). Метод WaitFor() стоит и ждет, пока семафор будет кем-то установлен (Set).

файлы и устройства ввода-вывода

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

  • Open - открывает файл/устройство/порт по имени, возвращает хендл (handle) - идентификатор.
  • Read - прочитать данные в буфер, с текущей позиции (если есть позиция)
  • Write - записать данные из буфера с текущей позиции (если есть позиция)
  • IOCtl - управление файлом/устройством/портом - чтение/запись свойств, режимов, метаданных. Например, состояние сигнальных линий для COM/LPT, настройки сокета, свойства файла или устройства.
  • Close - закрытие файла/устройства, освобождение хендла

последовательный порт

Последовательный порт (COM-порт, UART) низкоскоростной аппаратный интерфейс обмена данными, где данные передаются побитно, посылками по одному символу (байту). Контроль целостности очень слабый, поэтому при пакетной передаче (множество байтов) необходимо обеспечить целостность структуры пакета (байт-стаффинг) и контроль целостности (CRC).

сокеты

Сокеты с точки зрения операционной системы, это устройства ввода-вывода, с которыми можно работать как с файлами. Помимо стандартных операций (Open, Read, Write, Close, IOCtl), доступны действия:

  • Bind - привязка к IP-адресу и номеру порта (для TCP и UDP)
  • Listen - открытие порта в режиме сервера, на прием входящих подключений (только для TCP)
  • Accept - ожидание и прием входящего подключения, которое работает как Open отдельного сокета.

Протоколы:

  • UDP - данные передаются пакетами (обычно до 1500 байт), без контроля порядка и доставки (потери) пакетов. В заголовке только адрес/порт отправителя и получателя, контрольная сумма.
  • TCP - сеансовый протокол, устанавливает соединение с контролем порядка и доставки, потерянные пакеты передаются повторно.

SQL

  • Structured Query Language, язык запросов к базе данных.
  • первичный ключ - уникальный идентификатор строки таблицы, на который могут ссылаться другие таблицы
  • индексы - «оглавление» по колонке (или нескольким колонкам), ускоряет поиск значения. Индексы ускоряют чтение и замедляют запись данных.

отладка

Запуск программы в отладчике, пошаговое выполнение, просмотр стека вызовов, текущих значений переменных, установка break-point.

Запись в лог-файл или syslog отладочных сообщений, просмотр потока сообщений в файле или терминале.

Поиск ошибки по адресу исключения (отладка по фотографии). Адрес типа 0000XXXX - переход по нулевому указателю (обращение к освобожденному объекту). Сообщения «out of range» и «range check error».

сборка дистрибутива

  • makefile
  • Inno Setup

ведение документации

  • wiki
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Вопросы кандидатам при собеседовании

Сообщение wofs » 26.12.2017 18:59:07

serbod писал(а):Поиск ошибки по адресу исключения (отладка по фотографии). Адрес типа 0000XXXX - переход по нулевому указателю (обращение к освобожденному объекту).

А не затруднит осветить эту тему, или ссылок накидать?
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Вопросы кандидатам при собеседовании

Сообщение serbod » 27.12.2017 16:39:55

http://www.gunsmoker.ru/2009/05/access-violation.html

Если сгенерировать map-файл (опция -Xm в fpc/lazarus), то можно поискать в какой строке исходников выскочила ошибка. Лучше это делать автоматически, при помощи специальных компонентов или модулей. Лично я использую модуль JclDebug из набора JEDI.

Код: Выделить всё
function GetExceptionMessage(): string;
type
  PRaiseFrame = ^TRaiseFrame;
  TRaiseFrame = packed record
    NextRaise: PRaiseFrame;
    ExceptAddr: Pointer;
    ExceptObject: TObject;
    ExceptionRecord: PExceptionRecord;
  end;

var
  E: Exception;
  NextRaise: Pointer;

begin
  Result := '';
  {$WARNINGS OFF}
  NextRaise := RaiseList();
  {$WARNINGS ON}

  while NextRaise <> nil do
  begin
    E := Pointer(PRaiseFrame(NextRaise)^.ExceptObject);
    if Result <> '' then
      Result := Result + '; ';
    Result := Result + E.ClassName+'($' + IntToHex(Cardinal(PRaiseFrame(NextRaise)^.ExceptAddr), 8) + '): ' + E.Message;
    {$ifdef DEBUG}
    Result := Result + ' {' + GetLocationInfoStr(PRaiseFrame(NextRaise)^.ExceptAddr, True, True, True, True) + '}';
    {$endif}
    NextRaise := PRaiseFrame(NextRaise)^.NextRaise;
  end;
end;


Это код из проекта на Delphi 7, но вроде должен и в FPC работать. Там "раскручивается" весь стек исключений, на случай, если были исключения внутри исключений, такое бывает при старте Application. Можно сделать проще, GetLocationInfoStr(ExceptAddr).

Еще можно попробовать порыться в map-файле вручную. Вычитаем из адреса ошибки адрес начала сегмента кода (обычно это $00400000), затем вычитаем "магическое число" $1000. Оставшийся адрес ищем в map-файле. Не обязательно будет точное совпадение, из-за оптимизаций. Но примерное место найти можно.

Тут об этом подробнее на английском:
https://www.experts-exchange.com/questi ... #a12542741
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Вопросы кандидатам при собеседовании

Сообщение wofs » 27.12.2017 16:56:25

serbod Спасибо! Добавил в закладки, буду читать - интересно.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Вопросы кандидатам при собеседовании

Сообщение zub » 27.12.2017 20:48:02

serbod
Вы на полном серьезе рассказываете какието фантазии. нужно просто не резать отладочную инфу и смотреть стек вызовов.
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы кандидатам при собеседовании

Сообщение serbod » 27.12.2017 22:06:37

Жду описания, как смотреть стек вызова без отладчика, по телефону. "У нас ничего не работает, тут что-то выскочило, мы закрыли, а оно снова выскакивает!".
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Вопросы кандидатам при собеседовании

Сообщение zub » 27.12.2017 22:27:17

Почитав выхлоп стандартного обработчика исключений в консоли.
Или "руками" размотав стек и преобразовав адреса в строки файлов по отладочной информации (на это есть стандартные функции в ртл) - подготовить отчет о вылете.
никакие мап файлы тут нафиг ненужны, нужна отладочная информация
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы кандидатам при собеседовании

Сообщение serbod » 28.12.2017 12:08:29

zub писал(а):Почитав выхлоп стандартного обработчика исключений в консоли.

- У нас ничего не работает! Вот, сами посмотрите.
Изображение
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Вопросы кандидатам при собеседовании

Сообщение zub » 28.12.2017 12:39:35

- У нас ничего не работает! Вот, сами посмотрите.
- Линукс? Шлите выхлоп консоли!

или

- У нас ничего не работает! Вот, сами посмотрите.
- Пришлите пжст файлик "т:\ам\то\такой.то"
Код: Выделить всё
ZCAD crashed((

Stack trace:
  $0045AB12
  $00644DEE  GDBDIMSTYLE__SETVALUEFROMDXF,  line 376 of ./zengine/styles/uzestylesdim.pas
  $00686DE0  READDIMSTYLES,  line 1176 of ./zengine/fileformats/uzeffdxf.pas
  $006873F2  ADDFROMDXF2000,  line 1266 of ./zengine/fileformats/uzeffdxf.pas
  $00688243  ADDFROMDXF,  line 1464 of ./zengine/fileformats/uzeffdxf.pas
  $004669A1  LOAD_MERGE,  line 230 of ./zcad/commands/uzccombase.pas
  $00486B98  LOAD_COM,  line 351 of ./zcad/commands/uzccominterface.pas
  $0062F600  COMMANDFASTOBJECTPLUGIN__COMMANDSTART,  line 217 of ./zcad/commands/uzccommandsimpl.pas
  $00454E48  GDBCOMMANDMANAGER__RUN,  line 556 of ./zcad/commands/uzccommandsmanager.pas
  $00454FFB  GDBCOMMANDMANAGER__EXECUTE,  line 593 of ./zcad/commands/uzccommandsmanager.pas
  $004550F0  GDBCOMMANDMANAGER__EXECUTECOMMAND,  line 613 of ./zcad/commands/uzccommandsmanager.pas
  $006327D1  TMYACTION__EXECUTE,  line 335 of ./zcad/lclmod/uzctreenode.pas
  $00433227
  $005831DA  TMENUITEM__CLICK,  line 86 of ./include/menuitem.inc
  $005837DF  TMENUITEM__DOCLICKED,  line 280 of ./include/menuitem.inc
  $0040E131
  $00543A7B  WINDOWPROC,  line 2676 of ./win32/win32callback.inc

Latest log:
  Register log module "DEFAULT"
  GetSysInfo
  ProcessParamStr
  Found param command line parameter "NOSPLASH"
  Found param command line parameter "UPDATEPO"
  Found param command line parameter "QNLL"
  Found param command line parameter "QSI"
  end;{ProcessParamStr}
  ZCAD log v0.9.8 Revision SVN:Unknown started
  Program compiled on Free Pascal Compiler
  Program compiled with {$DEFINE BREACKPOINTSONERRORS}
  DefaultSystemCodePage:=65001
  DefaultUnicodeCodePage:=1200
  UTF8CompareLocale:=0
  SysParam.ProgramPath="E:\zcad\cad\"
  SysParam.TempPath="D:\temp\"
  SysParam.ScreenX=2560
  SysParam.ScreenY=1440
  SysParam.NoSplash=True
  SysParam.NoLoadLayout=False
  SysParam.UpdatePO=True
  SysParam.PreloadedFile=""
  end;{GetSysInfo}
  Register log module "TRANSLATOR"
  Register log module "SHX"
  GDBPlugins.LoadPlugins("E:\zcad\cad\PLUGINS\")
  end;
  Register log module "DXF_CONTENTS"
Log end.

Build and runtime info:
  ZCAD 0.9.8 Revision SVN:Unknown
  Build with Free Pascal Compiler (FPC) v3.1.1
  Target CPU: i386
  Target OS: Win32
  Compile date: 2017/10/10
  Compile time: 02:49:51
  LCL version: 1.9.0.0
  Environment version: Windows 6.1 build 7601 Service Pack 1
  Program  path: E:\zcad\cad\
  Temporary  path: D:\temp\
end.

Date:
10.17 0:29:59
______________________________________________________________________________________


мап файл для этого не нужен!
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы кандидатам при собеседовании

Сообщение Mirage » 28.12.2017 13:25:57

map файл это та же дебажная инфа, только не включенная в екзешник, а лежащая рядом. И стектрейсы с ними поактуальнее должны получаться, если оптимизации включены. Хотя сам не сравнивал.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 10

Рейтинг@Mail.ru