Comments 274
Давайте я лучше список разверну на доске, окей???
Почему многие разработчики не любят Java?Боже, нет, такие вопросы я бы меньше всего хотел слышать на техническом собеседовании.
Что делает хороший код хорошим?
Что вы узнали за последнюю неделю?
Объясните Юникод или транзакции в СУБД пятилетнему ребёнку.
Ваше последнее достижение, которым вы гордитесь?
...<много подобного в статье>...
Хотя… для нетрезвых конкурсов на корпоративе они вполне сгодятся.
Вероятно автор спутал тех.собеседование и приём у психолога
Хотите обсудить эту тему?
Что делает хороший код хорошим?
аааааа в голос просто
Думаю, тут еще в коvментах происходит тестирование на то, наколько человек хочет понять что сказал собеседник и поискать там рациональное зерно или насколько хочет доказать что собеседник неправ :)
Для мне это что-то типа «нравится ли уборщице швабра?» или «нравится ли кузнецу молот?». Мне на самом деле мне нравится решать задачи, а каким образом, — это уже второй вопрос. Обычно приходится решать теми инструментами, которые заказчик предпочитает. Если он захочет забивать гвозди мороженной колбасой, — забью без проблем. :) Эстетов будет воротить, но гвоздь будет забит.
Если он захочет забивать гвозди мороженной колбасой, — забью без проблем.
А не бывает ли таких ситуаций когда есть возможность выбрать инструмент или поговорить с заказчиком и убедить использовать другой?
Во-вторых, вопрос может быть не для того, чтобы дать вам выбирать а просто выяснить ваш кругозор — насколько вы знаете возможности Джавы и насколько вы будете готовы, когда следующая версия принесет новые возможности из других языков
А не бывает ли таких ситуаций когда есть возможность выбрать инструмент или поговорить с заказчиком и убедить использовать другой?
А это вообще тонкий вопрос. Тут как повезёт. Некоторые загипнотизированы фразами «новые технологии», «новые возможности». А некоторые думают «а где мы найдем специалистов на этот зоопарк, давайте по-старинке работать?»
вот тоже интересно.
я, например, немного недолюбливаю(недолюбливал?) за отсутствие некоторых очевидных вещей типа лямбд и val, которые теперь есть.
ну и нелюблю саму jvm по причине отсутствия unsigned типов и ряда других нюансов.
Вы сами-то эту статью читали?) Автор говорит о том, что аксессоры — зло лишь тогда, когда они втупую проксируют приватное поле. А вы возводите кричащий заголовок в абсолют.
Они генерируются синтаксисом, а не просто вообще для всех полей. возможностью перекрытия. Как в с#
public int X -> public int X {get;} -> public int X { get { return myWebService.method1() }}
Так же это полезно для любой вещи, где вы думаете о чем-то кк о характеристике объекта — это говорит UI что можно отрендерить нечно как поле и прочее.
enableX / disableX — это значит что у вас есть X который у вас голове связан с enable и disable, а в интерфейсе сущности X нет.
Фактически вы генерируете код только ручками.
Мысль заключается в том, что геттеры/сеттеры предоставляют доступ к состоянию, но не предоставляют поведения. Т.е. придают объектам свойства структур данных, образуя собой объекты-гибриды, недостатки которых хорошо раскрыл Robert C. Martin в своей книге «Clean Code».
Посмотрите, как устроены правильные OO-языки (Smalltalk, Objective-C, Ruby и т.д.). Объекты общаются посредством сообщений. Интерфейс — это протокол взаимодействия. Геттеры/сеттеры никакого взаимодействия не осуществляют, и в большинстве случаев (разумеется, не всегда) просто воплощают Code Smell под названием Feature Envy.
Посмотрите письма Alan Kay, того самого, кто и провозгласил термин OOP:
«I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (so messaging came at the very beginning – it took a while to see how to do messaging in a programming language efficiently enough to be useful).» (Alan Kay)
«OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.» (Alan Kay)Собственно, упомянутая oxidmod статья именно об этом. Письма Alan Kay можно найти в интернете, два наиболее важных из них я цитировал здесь. Кстати, статья по ссылке тоже посвящена этому вопросу, только уже на уровне паттерна «Event Sourcing».
Мысль заключается в том, что геттеры/сеттеры предоставляют доступ к состоянию, но не предоставляют поведения.
Мне кажется даже во времена дельты присваивание значения свойству вызывало какое-то поведение. Например изменение текста кнопки. То есть это как бы "интерфейсное состояние" изменение которого есть поведение.
Акцессоры — это просто группа сообщений о которой снаружи удобно думать как о состоянии. При этом за ними может крыться какое-то поведение. Насколько, я знаю, в смолтоке акцессоры есть.
Тот, который на собеседовании написал минимум три образца плохого кода.
На его футболке написано: «Единство дизайна означает элитность архитекторов».
Так вопрос не о достоинствах и недостатках (хотя многие недостатки исключительно субъективны), а о том, "почему многие разработчики не любят Java". А вот это уже бред, ибо не любить можно за что угодно (например, что там "if" а не "если")
Так собеседующему интересно мнение собеседуемого, пускай даже "там "if" а не "если"". Вопрос не подразумевает обязательного перечисления недостатков близкого к объективному или субъективной позиции "почему я не люблю Java". Вопрос подразумевает, скорее всего, осведомленность в области "джавасрачей". :)
Ну, как тут не вспомнить гениальное:
XXX шо есть транзакцыи?
YYY как бы тебе объяснить.
YYY вот ты бежышь срать в толчок.
YYY но по дороге не донёс.
YYY и обосрался.
YYY так вот с транзакциями можно сделать так, будто ваще и не бежал и не обосрался
да и некоторые ответы могут превратиться в нехилый холивар вместо собеседования :D
я middle php разраб и ответил всего на 80% вопросов (не знаю java, нуб в nosql и не teamLead для открытых вопросов) при чем по ощущению правильных ответов процентов 40-50. Это нормально?
Извиняюсь, забыл отправить комментарий на проверку моему личному grammar nazi
Объясните мне, я до сих пор уверен, что не отличается практически ничем.
Различие форм "извиняюсь" и "прошу прощения" — для эстетов. И классические объяснения училок "извиняю себя" некорректно, т.к. форма скорее несёт смысловую нагрузку "приношу извинения", а в такой формулировке разница ещё более никакая.
Часто бывает так, что работать надо не со знакомым языком/ технологией, а с чем-то специализированным. К примеру, 1С-ники иногда поддерживают groovy-код, а джависты попадают в Perl или JavaScript или вообще в ABAP, питонисты попадают в 1С и т.п…
И тут тимлид ищет тех, кто знает основы (сетевые протоколы, устройство юникода и принципы работы СУБД).
Часто бывает так, что работать надо не со знакомым языком/ технологией..
а с пятилетними детьми
Как-то определиться надо или они зло или нет.Темной силы стороной владеть уметь необходимо!
Да там прям ниже "Как произвести рефакторинг такого кода" с кучей уровней вложенности, который идеально рефакторится goto
function()
{
if(!SUCCEEDED(Operation1()))
return OPERATION1FAILED;
if(!SUCCEEDED(Operation2()))
return OPERATION2FAILED;
if(!SUCCEEDED(Operation3()))
return OPERATION3FAILED;
if(!SUCCEEDED(Operation4()))
return OPERATION4FAILED;
return S_OK;
}
Да любой более-менее сложный конечный автомат. Например: https://www.thibault.org/newhome/thoughts/goto-and-fsms.html
Согасен с тем, что goto никаким злом не является. Просто конструкция, которую стоит применять обдуманно.
Спуститесь на уровень пониже (в ассемблер), и (о боже!) там везде goto! Безусловные и условные переходы по-другому и не работают.
Излишняя демонизация goto и глобальных переменных говорит скорее об узости мышления таких демонизаторов.
Излишняя демонизация goto и глобальных переменных говорит скорее об узости мышления таких демонизаторов.
Мне кажется, когда на вопрос "Почему goto зло" начинают отвечать, что "goto — не зло" это свидетельствует просто о нежелании понять вопрос. Человек вступает в режим конфронтации. Любая живая речь недостаточно формализована, чтобы иметь некотору свободу интерпретации. С моей точки зрения, наиболее адекватно воспринять вопрос "Почему [в каких-то случаях] goto — зло". И рассказать про идеи структурного программирования, отметив, что в каких-то случаях goto может быть полезным.
Интересно, что сейчас в оригинале перевода вопрос поставлен так:
Is goto evil? You may have heard of the famous paper "Go To Statement Considered Harmful" by Edsger Dijkstra, in which he criticized the use of the goto statement and advocated structured programming instead. The use of goto has always been controversial, so much that even Dijkstra's letter was criticized with articles such as "'GOTO Considered Harmful' Considered Harmful". What's your opinion on the use of goto?
В случае с конечным автоматом мне ближе подход, когда задача описывается в терминах конечного автомата и в языке достаточно средств, чтобы описать eDSL для удобной формулировки конечных автоматов. Хотя я признаю, что в случае низкоуровневого языка и сильных требований к быстродействию, когда-то допустим и goto.
Сейчас разработка ПО коллективный процесс, и, если человек не хочет услышать то, что ему пытаются сказать, а требует 100% точного формального вопроса, в моих глазах у него будет минус.
Примеров, где goto может использоваться я и так предостаточно знаю, но практически в любом случае можно без него обойтись (об ассемблере я не говорю).
Но при этом легко обойтись и без него.
1) когда перед return есть работа, мы ее вложим в фигурные скобочки или вынесем в функцию.
2) когда разные if дают одинаковый результат, условия объединяют в одном if
Вообще, ничего не имею против goto, лишь бы не в моём проекте.
я имел ввиду когда if(!SUCCEEDED(Operation1())) и if(!SUCCEEDED(Operation2())) должны сделать одинаковую работу. Но сами if' разные.
Тогда их можно соединить через && (в некоторых языках).
Вообще, это похоже на монаду или исключения. :)
CMP DX, 00 ; Compare the DX value with zero
JE label_yes ; If yes, then jump to label L7
JMP label_no
LABEL_YES: ...
LABEL_NO:...
Например, в вашем примере написано «деинициализируем в обратном порядке», а порядок тот же.
foo(...)
{
if (!init_some1())
goto deinit_some1;
if (!init_some2())
goto deinit_some2;
// и так далее
// деинициализируем в обратном порядке
deinit_some2:
//
deinit_some1:
//
// и так далее
}
Неоднократно видел такое в сишных прогах.
Вложенность кода понижаем? Если 1-5 уровней — можно и вложить, если больше — кривота и смелл, что с goto, что без.
foo(...)
{
var int flag1 = 0, flag2 = 0;
if (!init_some1())
flag1 = 1;
if (!init_some2())
flag2 = 1;
// и так далее
// деинициализируем в обратном порядке
if flag2:
//
if flag1 || flag2:
//
// и так далее
}
Потому что часто компоненты init_some2()
и init_some1()
взаимосвязаны.
Сравните код какого подхода чище:
void foo()
{
Window *wnd = CreateWindow();
if (!wnd) goto cleanup_wnd;
Context *ctx = GetContext(wnd);
if (!ctx) goto cleanup_ctx;
Renderer *renderer = GetRenderer(ctx);
if (!renderer) goto cleanup_renderer;
renderer->drawline(0, 0, 100, 100);
cleanup_renderer:
FreeRenderer(renderer);
cleanup_ctx:
FreeContext(ctx);
cleanup_wnd:
DestroyWindow(wnd);
}
Или:
void foo()
{
bool wnd_failed = false;
bool context_failed = false;
bool renderer_failed = false;
Window *wnd = CreateWindow();
if (!wnd)
wnd_failed = true;
Context *ctx = NULL;
if (!wnd_failed)
ctx = GetContext(wnd);
if (!ctx)
context_failed = true;
Renderer *renderer = NULL;
if (!context_failed)
GetRenderer(ctx);
if (!renderer)
renderer_failed = true;
if (!renderer_failed)
renderer->drawline(0, 0, 100, 100);
if (renderer_failed)
FreeRenderer(renderer);
if (context_failed)
FreeContext(ctx);
if (wnd_failed)
DestroyWindow(wnd);
}
void foo()
{
int stage = 0;
Window *wnd = CreateWindow();
if (wnd) {
stage++;
Context *ctx = GetContext(wnd);
if (ctx) {
stage++;
Renderer *renderer = GetRenderer(ctx);
if (renderer) {
stage++;
renderer->drawline(0, 0, 100, 100);
}
}
}
switch(stage) {
case 2:
FreeRenderer(renderer);
case 1:
FreeContext(ctx);
case 0 :
DestroyWindow(renderer);
}
Или так
#define WINDOW_STAGE 1
#define CONTEXT_STAGE 2
#define RENDER_STAGE 3
void foo()
{
Window *wnd = CreateWindow();
if (!wnd) {
release(WINDOW_STAGE);
return;
}
Context *ctx = GetContext(wnd);
if (!ctx) {
release(CONTEXT_STAGE);
return;
}
Renderer *renderer = GetRenderer(ctx);
if (!renderer) {
release(RENDER_STAGE);
return;
}
renderer->drawline(0, 0, 100, 100);
}
void release(int stage)
{
switch(stage) {
case RENDER_STAGE :
FreeRenderer(renderer);
case CONTEXT_STAGE:
FreeContext(ctx);
case WINDOW_STAGE:
FreeRenderer(renderer);
}
}
В первом случае:
Допустим, в случае полного успеха уничтожать ничего не надо. Делаем if перед свичом?
Во втором случае:
Вот уже появилась функция о четырех переменных, вместо простого гоуту
Зачем плодить сущности без необходимости?
Допустим, в случае полного успеха уничтожать ничего не надо. Делаем if перед свичом?
Нет. в случае успеха stage = 3 и свич не выполнится.
Вот уже появилась функция о четырех переменных, вместо простого гоуту
Во-первых, не всегда с 4 переменными, при классах в C++ переменные могли быть полями, так же они могут быть глобальные, частями одной структуры или даже массива (вы же все равно их как-то использовать и освобождать будете? Тогда код в примере выше все равно неправильный, так как созданные объекты в случае успеха никогда не удалятся).
Во-вторых, в случае программирования бритва Оккама не работает. Принцип единственной ответственности и чистый код советуют делать функции с одной ответственностью — в данном случае, их две — создать и очистить в случае ошибки. Поэтому с определенной стороны (для понимания другими разработчиками), две функции лучше чем одна, но большая.
P.S. Вопрос, что будет если вы в последнем goto вместо goto cleanup_renderer напишите goto cleanup_ctx? Правильно утечка памяти, причем другой программист голову сломает это специально так задумано (может вы по каким-то причинам решили пока рендер не очищать) или вы ошиблись.
Goto чуть-чуть экономит место, но делает код сложнее для понимания. Оно того стоит?
В ваших примерах окно не очищается.
Так какой код лучше: с багом или без?
В ваших примерах окно не очищается.
Так какой код лучше: с багом или без?
Это называется описки (увы, писал без компа), исправить примеры ничего не стоит.
void foo()
{
Window *wnd = CreateWindow();
if (wnd) {
Context *ctx = GetContext(wnd);
if (ctx) {
Renderer *renderer = GetRenderer(ctx);
if (renderer) {
renderer->drawline(0, 0, 100, 100);
}
FreeRenderer(renderer);
}
FreeContext(ctx);
}
DestroyWindow(wnd);
}
*Это если предположить, что нам действительно зачем-то нужно очищать пустые объекты, как у вас в примере, иначе даже проще получится.
А разве такое использование if-ов или свичей у vedenin1980 — не тот же code smell?!!! Имхо лучше как-то так:
void foo() {
Window *wnd = CreateWindow();
if (wnd) {
context(wnd);
}
DestroyWindow(wnd);
}
void context(Window *wnd) {
Context *ctx = GetContext(wnd);
if (ctx) {
render(ctx);
}
FreeContext(ctx);
}
void render(Context *ctx) {
Renderer *renderer = GetRenderer(ctx);
if (renderer)
renderer->drawline(0, 0, 100, 100);
FreeRenderer(renderer)
}
foo(...)
{
bool init1_success= !init_some1();
// если init1_success == 0, init_some2() не будет выполнено
bool init2_success = init1_success && !init_some2();
// и так далее
// деинициализируем в обратном порядке
if (!init2_success) {
deinit2();
}
if (!init1_success) {
deinit3();
}
//
// и так далее
}
С ООП было бы, конечно, гораздо красивее и понятнее.
С ООП было бы, конечно, гораздо красивее и понятнее.
Вот именно. Дядьки объектную модель придумали не для того, чтобы круг от элипса наследовать, а потому что задолбались управлять ресурсами вручную. Хочется жить, а нужно следить за порядком выделения и освобождения памяти — даже о крепких нервах взвоешь.
P.S. Код ваш еще хуже того, что с goto. Вторая и последующие строки будут без надобности исполняться, хотя уже в первой может стать очевидно, что этого не требуется. Плюс замена условий выражениями. Не плюс, а минус, конечно. Ибо абстракции протекли уже во второй строке, где «init2_success» по смыслу является «init1_and_init2_success». Это путь к головокружительному дебагу, слезам, мату и дурной репутации. Не нужно так.
объектную модель придумали не для того, чтобы круг от элипса наследовать, а потому что задолбались управлять ресурсами вручную
Вот это для меня новость. Вы не могли бы привести ссылку на источник?
Вторая и последующие строки будут без надобности исполняться
bool init2_success = init1_success && !init_some2();
— это точно то же самое, что и
bool init2_success;
if (init1_success) {
init2_success = !init_some2();
} else {
init2_success = 0;
}
Мне всегда казалось, что это понятная и распространённая конструкция (разве не так принято писать на С?)
На самом деле, я готов согласиться с тем, что возможны очень редкие случаи использования goto. В конце концов, Никлаус Вирт после долгих размышлений оставил этот оператор в своём языке Паскаль, изначально предназначенном исключительно для обучения.
Я только могу заметить, что за свою тридцатилетнюю практику работы разработчиком всего пару раз использовал оператор goto, и то в лишь в начале карьеры.
Что касается глобальных объектов, да — по большому счёту это зло. Почему — хорошо объясняется, например, здесь: ru.stackoverflow.com/questions/510910/%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83-%D0%B3%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D1%8D%D1%82%D0%BE-%D0%B7%D0%BB%D0%BE-%D0%B0-%D0%BF%D0%BE%D0%BB%D1%8F-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0-%D0%BD%D0%B5%D1%82. Но иногда глобальные обекты все-же приходится использовать, и thread-safe singletone — это лучший паттерн для этого. Кстати, сфера применения паттерна singletone чуть больше, чем просто объявление глобального объекта.
Ну и самое интересное что если вам кажется что вы ответили на большинство вопросов, то вам это только кажется, т.к. почти каждый можно растянуть на жесточайший холивар, а ответить по верхам это не ответ, ну смысла от него нет никакого.
Занятный конечно же списочек, но интересно какой уровень зарплаты предложат человеку который может ответить на все вопросы)
«Ну, для начала, 25 на руки. Белыми, конечно. По итогам года можно будет говорить о постепенном пересмотре зарплаты, накинем пару тыщ, не обидим. А как вы относитесь к переработкам?»
На мой взгляд «открытые вопросы» хороший вариант понять как рассуждает кандидат. Да и вообще понять насколько комфортно общаться с человеком, как он воспринимает критику. Все таки живем и работаем мы чаще в команде и общение играет не последнюю роль.
Почему глобальные объекты и статика — это зло? Можете показать на примере кода?
Чо эт сразу зло-то? В ФП вот всё по умолчанию статика и глобальные объекты. Ну не учитывая разбивку на модули (по сути неймспейс).
Наверное стоит спрашивать почему ИЗМЕНЯЕМЫЕ глобальные объекты зло? Но и это не всегда правда, может у меня есть изменяемый глобально параметр LogLevel, небеса не развернутся если я его буду менять из разных кусков кода.
Многие другие вопросы заранее в себе содержат "правильный" ответ, который собеседуемый должен взять за основу рассуждений (например: почему Java это плохо?).
Короче, плохой опросник.
Для бэкенд-разработчика статика — зло очевидное. Да и за глобальными объектами нужно внимательно приглядывать. Тут даже кода не надо приводить, только 2 волшебных слова: «сервер приложений»
Я вот бекенд разработчик, занимаюсь "чёрными ящиками" (вход -> магия -> выход) — WebAPI, ETL, Streaming. И мне очевидно две вещи:
- я хочу всё распараллелить, заасинхронить
- я не хочу проблем
Поэтому я просто пишу в ФП стиле: иммутабельность везде. Сразу снимает проблемы с рейс кондишнами и проблемой глобальных объектов. У меня всё глобально доступно, но кого это волнует если функции чистые и они не мутируют объекты, а создают новые?
Я видимо плохой бекенд разработчик, потому что хороший, судя по опросу, использует для бекенда исключительно ООП.
Конечный пользователь берет и устанавливает несколько экземпляров приложения, с разными контекстами, на одной виртуальной машине. Какой будет результат?
Про библиотеки и говорить нечего
Я видимо плохой бекенд разработчик, потому что хороший, судя по опросу, использует для бекенда исключительно ООП.
Хорошие разрабы используют ОО языки для процедурного программирования.
В Erlang вообще нет глобальных и статических переменных, только локальные, принадлежащие стеку или куче процесса. Процесс закончился — память очищаем, все в мусорку улетело, все параметры, переменные, результаты, мэйлбокс. Хотите что-то передать — будьте добры явно этим озаботиться. Собственно, для того gen_server и придумали, чтобы можно было эмулировать сохранение состояния.
Есть правда нюанс с бинарниками, самый известный способ все-таки выстрелить себе в ногу, когда большие бинарники лежат в куче и на них передаются ссылки другим процессам. Я так словил знатную утечку памяти один раз, когда еще не знал особенностей. Но если об этом знать и знать решения, то это дело можно купировать.
Вопросы о сервис-ориентированной архитектуре и микросервисах:
• В чём разница между SOA и микросервисами?
А-А-А-А-… как это развидеть ?!?!
я бы такому тимлиду задал вопрос, сколько стоит его медицинская страховка
• Что случится, если я отсканирую зеркало?
Люли от владельца сканера? Вообще будет черный лист. Вопрос, судя по формулировке, не предполагает объяснения почему. Честно говоря я не знаю почему, но тем не менее он реально будет черный… а люли не приятными.
• Почему ответы Quora лучше, чем Yahoo Answers?
А что это? Я оба названия первый раз слышу. Или туда берут только тех, кто знает?
• Сыграем в игру: защитите Cobol против современных языков и попробуйте найти как можно больше разумных аргументов.
А если я кобол вообще ни разу в жизни не видел то тоже не подхожу?
upd.
Погуглил… афигеть, оно еще живо… и это с таким-то жутким синтаксисом.
Если бы вы могли вернуться в прошлое, какой совет дали бы молодому себе?
Чувак, я из твоего будущего. Мой тебе добрый совет: иди на кружок бокса, авиамоделирования или дизайна. Не ходи в тот корпус, не ходи.
Выглядит так, будто чувак чудом устроился на работу и теперь на собеседованиях глумится над кандидатами
Объясните Юникод или транзакции в СУБД пятилетнему ребёнку.Просто объяснить или так, чтобы он понял? Если второе, надо ли в конце проводить проверку того, что пятилетний ребенок все понял правильно? А то, что мозг пятилетнего ребенка недостаточно развит для понимания концепций такого уровня сложности, автора не смущает?
А то, что мозг пятилетнего ребенка недостаточно развит для понимания концепций такого уровня сложности, автора не смущает?Вы сильно недооцениваете детские мозги. В этом возрасте они такие объемы информации перелопачивают, что людям зрелого возраста и не снились.
Можно объяснить первокласснику как решать дифуры. Только вы почитайте про судьбу вундеркиндов сами.
Вот лет с 9 — 10 уже можно начинать пробовать. Некоторые точно поймут.
самое важное для бэкенд-разработчика
Чет мне кажется, это не каждому разработчику надо знать. А кому надо, к тому это знание само придет.
Как бы вы справитесь с очень большой текучкой и убедите разработчиков не покидать команду без повышения зарплаты
Пневмопистолет с гвоздями, пару убедить — остальные сами останутся. Небольшая потеря производительности (прибитыми к столу руками код не набрать), но можно оформить их консультантами. Это будет крайне логичным решением, учитывая остальные вопросы при приёме на работу в компании.
вам один месяц и бюджет
А вот и средства для реализации пункта 2.
Если Cat — это Animal, то верно ли, что TakeCare Cat — это TakeCare Animal?
О, контрвариантность подъехала. Хотя по вопросу фиг догадаешься, чего вообще они хотят.
Что вернёт эта функция JavaScript?
function hookupevents() {
for (var i = 0; i < 3; i++) {
document.getElementById("button" + i)
.addEventListener("click", function() {
alert(i);
});
}
}
About Type Erasure, what's the output of this Java snippet, and why?
ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
System.out.println("Equal");
Это специально так? Или это ошибка копипаста?
o return a value other than the default, a function must have a return statement that specifies the value to return. A function without a return statement will return a default value. In the case of a constructor called with the new keyword, the default value is the value of its this parameter. For all other functions, the default return value is undefined.
Вопросы, в целом, хороши, поскольку они предполагают рассуждения, а не заученные ответы.
Вы в совершенстве владеете балансировкой красно-черного дерева?
Ваши коммиты есть в опенс-сорс, решениях используемых в крупных компаниях?
Вы подняли и поставили на ноги более двух стартапов? Вы знаете SQL и no-SQL решения?
Віg Data и Data Science не пустой звук для вас?
Добро пожаловать к нам, на позицию Front-end developer в стабильный с 2002 года крупный enterprise проект документооборота в одном из крупнейших отечественных банков, в ваши задачи будет входить доработка UI части проекта на основе тикетов от группы поддержки.
Похоже пора писать статью "Кто убил сеньйора?"
Не встречал еще крутого спеца по морде и по бэкенду одновременно. Что-то из этого будет хромать на фоне дева специализирующегося на чем-то одном, знающего весь инструментарий в совершенстве, когда какие языки и т.п.
При поиске работы с 10-летнем стажем бэкэнд разработчика/архитектора, я прорешал всяких тупых алгоритмических задачек больше, чем на олимпиадах на первых курсах университета.
Не смотря на отличное интервью с HR-ом, забородили на должность архитектора, не задав ни одного вопроса по архитектуре.
HR, пропускающий два раза подряд интервью по скайпу — так тоже бывает.
Давать непрошедшим кандидатам фидбэк — западло.
Лучший способ провести выходные — за решением тестовых заданий. Жена, дети, домашние дела — это всё ерунда.
Надоело строить из себя девственницу и каждый раз выдумывать, почему именно в этой из 20 зааплаенных компаний я хочу работать.
Немного грустно, когда ты квалифицированнее собеседующего тебя «сеньора» и тебя не берут только поэтому.
Я замечал такое только в российских компаниях. Иностранцы более прагматичны и рациональны.
Эээ, тут вы не совсем правы. У иностранцев (Европа/США и т.п.) еще важнее личное впечатление, если у вас подвешен язык, вы улыбаетесь, на собеседовании шутите и говорите на хорошем английском ваши шансы намного выше чем у замкнутого ботаника, который обладает огромным опытом, но двух слов связать не может. В России с этим даже попроще.
В России попроще с этим если вы землекоп. Во всех остальных случаях нужны связи и знакомства.
что российские компании слишком много уделяют внимания непонятным тестам
Эти тесты и вопросы про люки, опишите свои недостатки или кем вы себя видите через 10 лет, пришли с Запада.
старательных, позитивных и улыбчивых людей.
Кто сказал, что человек, умеющий себя продавать, старательный? Ну и позитивность и улыбчивость тоже маска для собеседования. Часто вопрос не в блестящести, а просто в том что хорошо приноровившийся продавать себя товарищ мастерски научившийся проходить собеседования может оказаться никаким программистом и работником. Хуже всего что такие специалисты участвуют в собеседованиях и подбирают таких же спецов в команду, в результате в какой-то момент вся команды позитивная, дружная, улыбчивая… и ни черта не делающая и не умеющая.
Во всех остальных случаях нужны связи и знакомства.
Программисту? Никогда не требовалось, там скорее наоборот нужны связи и знакомства чтобы выйти на хорошего специалиста.
В целом-то неплохой набор для создания собеседования. Правда, вот, не на бекенд и даже не на фронтенд, и даже не на программиста вообще, а на роль автора-теоретика для выпуска какой-нибудь очередной книжки из разряда "Стань программистом на… за… часов". Я не шучу, правда. Вся эта муть интересна, как теория. На практике же это не более, чем повод потолкаться в курилке, на хабре или в обществе себе подобных фриков где-нибудь в большой картонной коробке под мостом (это я про будущее, т.к. скоро программировать будет ИИ вместо нас и ряды маргинальных жителей трущоб пополнятся МИЛЛИОНАМИ небритых, патлатых и одиноких бродяг, готовых за еду на ...)
Какие три главные вещи о программировании нужно знать гуманитариям, по вашему мнению?»
я считаю, важнее было бы:
— какие три главные качества/вещи вы хотите от вашего руководства?
— интересно ли вам, какие три главные качества/вещи хотят от вас?
Кто вам мешает их подготовить и задать?
если бы соискатель также составлял список технических вопросов и это было бы вроде версуса — ты отвечаешь на мои, я на твои.
А это можно сделать на любом собеседовании. Вас спрашивают о технологии X, а вы даете ответ и спрашиваете «а как реализовано в вашей компании? А почему именно так?», иногда техническую беседу можно построить в виде одних ваших вопросов «У вас так? А вы не сталкивались с проблемой Y? Сталкивались? Я помню на одном проекте ее решил способом Z. А как это работает с технологией N?», главное задавать вопросы и давать комментарии так чтобы все поняли, что вы в теме (это тоже не легко).
Почему в большинстве языков индекс массива начинается с нуля?
В Си массив — это указатель, индекс указывал смещение относительно начала массива.
Ты мог обратиться к элементу несколькими способами. через [], через *(pointer + 2) (не уверен, что правильно написал). Твой код был завязан на то, как массив хранится в памяти
Думаю, остальные языки просто продолжили традицию.
в PL/SQL и Паскале индекс начинается с 1, и всё нормально. В Перле по умолчанию ноль, но можно поменять, хоть на 2.
Думаю нет какой-то специальной причины, почему 0 во многих языках, где тебе похрен на то, как массив хранится в памяти. В других языках у тебя есть некая абстракция «массив», и ты не знаешь, как элементы хранятся в памяти: рядом, не рядом, а обращение к элементу массиву всегда происходит через операцию [] и никак иначе.
Проще: потому что большинство языков старались быть похожими на C, а не на Fortran :)
Паскале индекс начинается с 1
var a: array[-1..1] of integer; и вот он с -1, с 1 начинался во всяких примерах обычно.
Написали array[0… и он уже с 0.
Вот string в OP/Delphi с 1, потому как в 0 длина (и для совместимости в длинных строках).
И вообще массив начинается с low(массив), для динамических array of это 0.
1) Компилятор не разбирается в константных выражениях. Этот кусок кода компилируется, хотя содержит ошибку, которую можно выявить уже на этапе компиляции.
int i=(false?0:null);
2) Возможно неожиданное зависание в рекурсивной процедуре. Ни какой ошибки не выдается, просто висит.
public static void work(){
try{
work();
}finally{
work();
}
}
3) Все говорят о high perfomance в java. IMHO high perfomance связан с утилизацией оборудования на полную катушку, а java далека от этого. Например, мало кто из джавистов знает, чем отличается физическая память от виртуальной, и что такое блокировка блоков в физической памяти. Ушел процесс в swap и будешь терять миллисекунды при просыпании. В примерах на параллелизм нет анализа, сколько процессоров в системе.
4) Все спрашивающие озабочены деталями, как работает сборщик мусора. IMHO в хорошей системе это не должно быть проблемой.
5) При переполнении числа не выдается ошибка, а просто идет по кругу. То есть можно не заметить переполнения и попортить данные.
int i = Integer.MAX_VALUE+1;
Я нашел пунктов 10, которые меня смущают при всей рекламе крутости java.
При большом количестве понтов есть куча неадекватностей.
Так можно про любой язык сказать если в нём разобраться.
1) Компилятор не разбирается в константных выражениях. Этот кусок кода компилируется, хотя содержит ошибку, которую можно выявить уже на этапе компиляции.
int i=(false?0:null);
Это и не должен. Такие вещи вроде «Integer x = null; int i = x;» приведут к ошибке, но сознательно не ловятся компилятором. Если программисты хотят они настраивают в IDE статистический анализ, который ловит такие странные вещи и не дает их скомпилировать или сделать коммит.
Во-первых, стандарт языка общий для большого количества Java компиляторов (да их много), усложнение проверок сильно усложнит реализацию стандарта (там и так много тысяч тестов, которые нужно пройти).
Во-вторых, компилятор сознательно не додумывает за программиста, хочешь бесконечный цикл — делай, напишешь так чтобы null pointer в первой строчки будет, компилятор не будет тебе мешать. Хочешь чтобы тебя ловили за руку — статические анализаторы (например, IDEA) тебе в помощь.
В-третьих, компилятор всегда компромисс между скоростью компиляции и количеством функций. Хочешь добавить сто тысяч подобных проверок — ожидай, что компиляция будет как в С идти медленно и печально. Это всем не надо, поэтому этого в стандарте нет.
2) Возможно неожиданное зависание в рекурсивной процедуре. Ни какой ошибки не выдается, просто висит.
Зачем так сложно? Можно же проще:
public static void work(){
work();
}
Бесконечная рекурсия, где система просто весит и в лучшем случае упадет с стак оферфлоу экспешнеом. А что вы тут ожидали? Можно еще бесконечный цикл написать — тоже система повиснет. Это ожидаемое поведение, компилятор не должен за вас решать нужен ли вам бесконечный цикл/бесконечная рекурсия или нет. Но это тоже ловится статистическими анализаторами, надо — включайте, не надо не включайте.
3) high perfomance в java — надо понимать, что java почти всегда медленнее C/C++ и его аналогов (Go, D и т.д.), но скорее всего быстрее многих высокоуровневых языков. В целом, просто для серверных приложений, бекэнда, обработки больших данных и т.п. производительности Java хватит с головой, а если тормозить будет то скорее из-за кривых рук. Вопросы кол-ва процессоров, памяти и т.п. можно отдать на откуп виртуальной машине, она в большинстве случаев сама разбирается. Это нелепо когда пытаются оптимизировать производительность на копейки, когда один кривой sql запрос сжирает в тысячи раз больше ресурсов. Для простых задач вы скорее упретесь в пропускную способность сети, кол-во открытых портов, скорость работы жесткого диска или базы данных.
С другой стороны, если вам нужна максимальная производительность на уровне C++ (игрушки, ОС, драйверы, 3D моделирование и прочее) — вам не к Java.
4) Сборщики мусора в Java (их несколько на выбор) очень сложные и отлаженные системы. В 90-95% случаев стандартный и так будет хорошо работать. Но с помощью выбора сборщика и его настройки можно получить приличный выигрыш в оставшихся 5-10%. Поэтому знать его работу — полезно (ну и чтобы не сделать утечек из-за кривых рук).
5) Можно, это решение архитекторов языка. Вероятно причина в производительности (каждый раз проверять на переполнения — дорого), Integer хранит 2 млд. значений, крайне редко кому-то удается вызвать переполнение без танцев c Integer.MAX_VALUE или ошибке в коде, А вызвать переполнения long или BigInteger — вообще крайне сложно. Если у вас может быть переполнения используйте long/BigInteger или специально проверяйте на переполнения.
Сначала купился на рекламу
Зря, у Java есть своя ниша где ей хорошо (бэкэнд, сервера, большие данные), плюсом — огромное кол-во библиотек и открытых проектов на любой вкус и тупо много вакансий, разработчиков и уже существующих приложений.
Но для новых проектов есть более интересные языки в мире JVM (скала, котлин), для десктопных приложений под Вин — лучше взять, скорее всего что-то вроде Net. Если вам интересны самые новые подходы в разработке — в Java новые возможности приходят медленно и печально (впрочем для энтерпрайза это скорее плюс).
Вообще, не стоит верить рекламе, Java стабильная и надежная лошадка, бегающая в своих задачах весьма шустро, но не скаковой бегун, как по производительности, так и по новым интересным возможностям языка.
Как способ всегда иметь кусок хлеба хороша, как средство разработки приложений на десяток лет — тоже, как очень стабильная и продуманная экосистема — тоже, но не как убийца С++ или самый модный язык с самыми последними функциями. Ну и она просто многословна.
На счет переполнения чисел для меня была самая болезненная проблема в одном проекте, в котором было много математики. Проект работает, работает, а потом фиг знает где начинает что-то глючить. И разобраться трудно. Приходилось обкладывать проверками вручную. На паскале, например, есть опция компилятора, которая заставляет при переполнении вызывать исключение и отладчик.
Знаете что-то схожее по функциональности с большей скоростью работы?
Не следует ли отсюда, если не вывод, до гипотеза: фичи требуют ресурсов, а язык вторичен?
А вот когда все в абстракциях и или код не очень, то начинается phpstorm. Это мое мнение дилетанта.
int i=(false?0:null);
Просто по анализу AST проверить семантику типов в операции. Для языка со строгой типизацией, неужели сложно?
public static void work(){
try{
work();
}finally{
work();
}
}
Цикл без выходной дуге в графе вызовов? Тоже практически без накладных расходов (при компиляции). И тоже я бы ожидал от java увидеть при компиляции варнинг.ожидал бы, что в настройках по умолчанию java выведет как минимум 2 варнинга в compile-time.
1) Null можно использовать как любой тип. То есть выражение «условие? число: null» — полностью корректно. Если бы было Integer i=(false?0:null); — это было бы 100% рабочее выражение. Если бы была число и скажем строка вместо null — программа бы не собралась.
2) Данное выражение не константа, оно аналогично следующему коду с точки зрения компилятора:
Integer tmp;
if(false) {
tmp = null;
} else {
tmp = 0;
}
int i = tmp;
Есть общее правило, при касте null к примитивному типу — выкидывается NullPointer, делать исключение только для такого крайне редкого случая когда можно вывести значение при компиляции не стоит. На самом деле, в новых языках пытаются избавиться от проблем с типом null, но 20 лет назад это казалось хорошим решением, а потом уже поздно было ломать обратную совместимость.
Цикл без выходной дуге в графе вызовов? Тоже практически без накладных расходов (при компиляции). И тоже я бы ожидал от java увидеть при компиляции варнинг.
В ряде случаев это корректный код, скажем иногда используется код «for(;;) {...}» для того чтобы один тред висел в бесконечном цикле, а другой делал работу.
2) Данное выражение не константа, оно аналогично следующему коду с точки зрения компилятора:
Почему тогда effective final в java вычисляется без проблем? Это ж по сложности вычисления примерно одно и тоже, что и константные выражение.
int a=1; // effective final
class test_a{
test_a(){
System.err.println(a);
}
}
int a=1;
class test_a{
test_a(){
System.err.println(a); // ошбика ожидается final или effecive final
}
}
a=2; // переслало быть effective final
class A {
private int a1 = 1;
private final int a2 = 1;
private final static int A3 = 1;
public void method() {
// Чему равны a1, a2, A3 ?
}
}
Чему равны a1, a2, A3 в method()? Всегда 1? А если возьму Java reflection и поменяю в промежутке между созданием и вызовом method() все значения на 2 (насколько помню это возможно даже для private final static, хотя там могут быть свои подводные камни)? А у вас компилятор уже заложил, что там всегда будет 1.
Зачем заниматься оптимизацией, которая сломает Java reflection, разное поведение для локальных переменных и приватных полей класса — тоже будет сбивать с толку (представьте вы просто перенесли переменную из приватного поля класса в локальную переменную функции и компиляция упала)?
Потом не забывайте простую вещь, по-хорошему каждый Java программист должен знать стандарт языка наизусть (хотя бы для ответа на собеседовании, а что вернет Java в этом коде), то есть каждая такая оптимизация потратит несколько минут/часов жизни у каждого изучающего Java на проф.уровне, а это огромные потери времени в сумме для всех программистов. Оно того стоит?
effective final — оно про поля метода и на поля класса не распространяется. А до значения переменной/константы внутри тела метода без дизассемблирования-перекомпиляции (хоть это и возможно на лету) вы никак не доберётесь, в том числе и рефлекшеном. Ну а дизасм-перекомпиляция создадут новый инстанс класса и загрузят его через лоадер.
Компилятор не разбирается в константных выражениях. Этот кусок кода компилируется, хотя содержит ошибку, которую можно выявить уже на этапе компиляции.
int i=(false?0:null);
Возьмем код
public class A {
private final B b = null;
private final static C с = null;
public method1() {
b.test();
}
public method1() {
c.test();
}
}
Вот тут некорректно просить компилятор, чтобы он не стал копилироваться. потому что там будет NullPointerException, потом что в реальности с помощью рефлексии там может быть вовсе не NullPointerException (это нормальное поведение для всяких библиотек типа JPA/Hibernet/Dependecy injection).
Ну и разная компиляция у схожего кода — будет странной:
public class A {
private final B b1 = null;
public method1() {
final B b2 = null;
b1.test();
b2.test(); // странно если компиляция b1 и b2 будет
// происходить по разным правилам и b1.test(); пропустит, а b2.test(); нет.
}
}
Ну и запоминать правила при которых компилятор решит довычислить значения переменных и дать по рукам — муторно, намного проще самому настроить статический анализ, как я уже говорил.
Ну наверное не стоит демагогией заниматься. Я ответил на один кокретный ваш комментарий, где вы некорректно отослались к полям класса, как допустимым к вычислению в режим effective final, хотя на самом деле это не так.
В спор про условную корректность компиляции int i = (false:1:null) я вмешиваться не стал.
PS да автобоксинг-автоанбоксинг иногда доставляет головоной боли, но в большинстве случаев — сильно упрощает работу с данными, так что засчитать невалидной компиляцию такого куска действительно можно только в качестве надиванника-теоретика или бреда. А ловить редкие случаи возможных проблем — это действительно про стат. анализ.
У Java много проблем никто не спорит (многословность, костыли обратной совместимости), но в данном случае у вас полно придирок и неточностей, лень все разбирать, но пример
Просто к тому времени, как она появилась (год 95й), я уже несколько лет программировал на С++ и pascal. Сейчас решил перескочить на что-то более удобное. Но впечатления неоднозначные. Особенно с отсутствием контроля переполнения арифметики и кучей «удобств», которые сначала задумывались как лучше, а получилось как всегда. Молодым может и норм, но мне хотелось бы не ходить по кругу, а получить качественный инструмент не хуже того, что я использовал до этого.
Когда кэш не нужен и даже вредит?
Когда позволяет читать память других процессов из-за ошибки в реализации спекулятивного выполнения команд процессора?
Да и плюсов у статьи 36.
Хабраюзерские фишки видимо))
Просто не все воспринимают собеседование как экзамен :)
2. У автора 154 публикации, достаточно чтобы набрать кармы,
3. Часть вопросов полезные, часть вопрос — вредные, но их тоже могут задать на собеседовании. Интервью по этой статье проводить я бы не стал, а вот просмотреть вопросы при следующем поиску работы — имеет смысл.
Вопросы по логике и алгоритмам:
• Написать пример кода, который создаёт утечку памяти.
Уже третий час не получаеться сделать на javascript, это задание для гениев.
Находил такое «IE до версии 8 не умел очищать циклические ссылки».
Также встретил предположение что утечек воможно добиться через замыкание, но достичь желаемого эффетка не удалось, либо V8 слишком умна, либо делал что-то не так.
Т.е. технически такое возможно (к примеру в IE), но т.к. задача находилась в разделе «Вопросы по логике и алгоритмам», считаю случай с IE не показательным, мелкомягкие всегда умели порадовать своих фанов.
Думал, что сборщик мусора должен автоматически закрывать системные хэндлы, а он зараза не закрывал
А с чего ему их закрывать? Сами закрываются они только вместе с JVM
Это в каком это месте утечка? Или у вас в каких-то других языках хендлеры сами закрываются?
Ну и как написал уже ApeCoder есть удобные языковые конструкции для закрытия хендлеров после окончания использования. Их просто надо использовать. Но никто не заставляет — вдруг у вас какой-то хендлер должен жить весь ЖЦ приложения.
Ну вы познакомьтесь с понятием ЖЦ приложения
и поймёте что это оно. Только в Java сессия жизни
не ограничена одним запросом и не вынуждает придумывать способы быстро загрузить/закешировать данные приложения, которые нужны между сессиями. Естественно, при этом, заставляя разработчиков больше думать о других нюансах.
Самое главное — не удаляй их. Просто не удаляй. Забудь. Ну цикл еще эдак на миллионов десять итераций.
Профит? :)
Людей следует искать под конкретный проект, конкретную задачу а не «сферического программиста в вакууме». Соответственно этому нужно и готовить список вопросов. В обсуждаемой статье отсутствует цель найти кого-то определённого, т.к. слишком много направлений затронуто (frontend, backend, менеджмент, архитектура...). К тому же, чтобы обстоятельно ответить хотя бы на половину вопросов, да ещё и с неминуемыми уточнениями по ходу разговора, денька два может уйти влёгкую. Пойдёт-ли на такие расходы фирма и согласится-ли на такое, с позволения сказать, собеседование мало-мальски толковый профи — вопрос, думаю, риторический.
Вот как своеобразная шпаргалка, база «дежурных» вопросов (а скорее — тем для построения своих вопросов) эта статья очень даже полезна, как по мне.
«Послушаешь вопросы на собеседованиях — не иначе как гениев ищут. Посмотришь код проекта — и куда только всех гениев дели?»((с)тырено)
Видимо причинно-следственная связь иная: гениев на проэкте изначально не было, и в какой-то момент, увидев код, решение становиться очевидным — нужен гений.
Бывают такие задачи, когда действительно жестко-специализированный человек с таким широким в рамках специальности кругозором может быть крут и полезен, но требование от каждого бекендщика — явная монополизация экспертизы.
Т.е. чтоб держать в голове пачку глубоких и порой нечасто используемых знаний, надо себя заставлять их постоянно поддерживать или реально быть увлеченным. Если большая часть времени тратится на задачки для собеседования, вопросы и прочие тесты, то времени и сил на реальные интересы может не оставаться. Стоит ли это редких блистаний у привередливых собеседователей, которые как правило не являются лучшими работодателями и коллегами (согласен с комментарием)? В любом случае, я рад что рынок есть и он довольно свободный. Всегда можно просто не связываться с теми, с кем не удобно. (:
Либо люди с легкой руки одного сотрудника названными «с альтернативным мышлением». Человек либо фанатик в определенной области, что остальные просто выпадают из поля зрения. Либо комплексы двигают показать свое превосходство над кандидатом.
Я воспринимаю вопросы на собеседовании не как требования, а как способ узнать какой кандидат пришел. То есть он может не ответить на какое-то количество вопросов и, может быть, никто не может ответить на них все — но дает представление о кандидатах. Это как линейка которая должна быть длинее измеряемого объекта, но объект может быть меньше линейки и все равно нам подходить.
По результатам может быть вывод "Реально крутой в ООП чувак но хреново с облаком, но у нас есть Вася он его научит".
Так же, я воспринмаю этот текст как палитру вопросов из которых можно выбрать а не перечень вопросов которые обязательно можно задать все.
Прекрасное сравнение с линейкой! В самом деле, чтобы понять где заканчиваются знания человека, придётся задавать вопросы до тех пор, пока на какой-то он не сможет ответить. Но цель интервью же не в том, чтоб измерить уровень, а в том, чтоб понять. подходит ли человек именно нам.
Это как линейка которая должна быть длинее измеряемого объекта, но объект может быть меньше линейки и все равно нам подходить.
знаете, что самое смешное? Метрическая система была задумана как раз с тем, чтобы используя метровую "линейку" можно было измерить километровое поле.
Почему вы слово "линейка" использовали в кавычках? Наверное потому, что здесь нет линейки как инструмента измерения, а есть абстракция линейки как выражения меры. Но метры ткани и километровые поля наверняка на практике измеряют используя разные инструменты, да? В-общем, я не очень понял смысл вашего высказывания.
Еще
Так же, я воспринмаю этот текст как палитру вопросов из которых можно выбрать а не перечень вопросов которые обязательно можно задать все.
Но метры ткани и километровые поля наверняка на практике измеряют используя разные инструменты, да?
Конечно да, банально с тканью в большинстве случаев допустима погрешность при условии ускорения измерения. Ну и, соответственно, пользуются разметкой на раскроечном столе. А поле столом не померяешь — в худшем случае берётся деревянная линейка (а то и просто шаблон) на метр-два и с её помощью измеряется. В лучшем случае промер происходит в несколько замеров с использованием оптических измерительных приборов.
А говорил я это к тому, что ваша аналогия "линейка для измерения должна быть больше измеряемого объекта" некорректна. Т.к. как раз линейка для измерений — нередко меньше измеряемого объекта. Но только благодаря достаточно совершенной в данной области модели — модели метрических измерений. Для вашего же случая нужна или другая аналогия или вообще отказ от аналогии в пользу построения более достоверной модели.
— Что?
— Фильм например, у вас есть блюрей дамп, отсортируйте его.
— …
Есть какие нить идеи?
«Почему люки круглые» — плохо.
«Напиши с нуля какой-нибудь из алгоритмов» — плохо.
«Абстрактный вопрос для того, чтобы завязалась дискуссия» — плохо.
«Покажи код на гитхабе» — плохо.
Как убедиться, что человек знает и умеет, а не пытается «проскочить»? Не брать же каждого соискателя на испытательный срок? Пока поймет что к чему и втянется в процесс, пройдет не меньше недели. Так можно месяцами искать.
Как убедиться, что человек знает и умеет, а не пытается «проскочить»?Люки или академические алгоритмы в этом точно помогут? Репозиторий с открытым кодом — это хорошо, если он есть, может быть плюсом.
Спрашивать о том, что будет необходимо в работе? Про интересующие работодателя технологии, как что работает и взаимодействует. Про архитектуру: как бы вы спроектировали то-то и то-то. Иметь компьютер с подготовленным учебным проектом, чтобы предентедт сделал намётки новой фичи или исправил хитрый баг.
Про прошлый опыт попросить рассказать. Ну и ряд вопросов на ширину кругозора (не в зачёт).
Многие критикуют подобные вопросы. Интересно было бы узнать их мнение — как с определенным процентом уверенности убедиться, что пришедший на собеседование программист достаточно компетентен?
Один из вариантов — дружить с программистом заранее, устраивать конференции, учебные курсы и тп чтобы товарищи могли себя проявить.
Как вариант NDA + доступ + реальная задача = 1-2 дня и любители халявы отвалились, некоторые не справились, с остальными можно посмотреть.
Вопросы для собеседования бэкенд-разработчика