Комментарии 151
Считаете ли, что гуглить зазорно, и лучше пойти прочесть пару книг?Это взаимодополняющие процессы. Я стараюсь много читать, причём книги из самых разных областей программирования. У меня нет цели запомнить всё или начать использовать эти знания на следующий день. Моя цель — расширять кругозор, чтобы когда появится необходимость, я знал в какую сторону копать. А сам этот процесс всегда начинается с поисковика.
Главное для чего нужно читать книжки — это не чтобы найти правильное решение (его вам выдаст Google), а для того, чтобы отсеять кучу неправильных (их тоже будет в выдаче поисковика в достатке).
С другой стороны, использование готовых решений из интернета не отменяет чтение книг. Чтение книг создаёт базу, а «готовые решения» — это для конкретной проблемы. Причём часто без базы невозможно подобрать или адаптировать «готовое решение» под конкретную проблему. И беда многих начинающих программистов, что они этого не понимают.
Но книги дают систематические знания. А практика дает знания отрывочные.
С систематическими знаниями можно решать задачи быстро и эффективно, а с отрывочными — просто решать. А скорость и эффективность — дело случая.
Можно сколько угодно много рассказывать о простоте и эффективности самообучения, но истина проста: систематическое обучение это другое и никакое самообуение не может его на 100% заменить.
Я лично перестал себя обманывать и стал больше времени уделять систематическим и структурированным источникам знаний. Чего и вам желаю.
Именно поэтому лично я считаю идиотизмом задачи на собеседованиях вроде «а сбалансируйте-ка бинарное дерево». Недавно было такое собеседование, на мой вопрос «разрешается ли пользоваться гуглом», ответили «мы хотим проверить ваши навыки программирования, а не навыки пользоваться гуглом». Так и хотелось спросить, не запрещено ли у них случаем пользоваться гуглом в рабочее время, а то может быть, не стоит тратить время.
Как по мне, так гораздо более адекватно сегодня давать задачи более сложные (те, на которые невозможно найти ответ в гугле за 30 секунд поиска), но с возможностью пользоваться любыми источниками — такие задачи гораздо ближе к реальности, чем эфемерные «изобретите алгоритм, который точно кто-то уже изобрел до вас».
Это на какую должность такое спрашивают? Что за язык? А то у меня синдром самозванца начинает развиваться…
Сейчас работаю в компании, в которой на собеседовании не задали ни одного технического вопроса, зато предложили обсудить мои предыдущие проекты, самые трудные задачи, с которыми я сталкивался, как я их решил тогда и что бы я изменил в их решении сегодня.
Таких собеседований, к счастью, тоже было достаточно.
Собсеседования с вопросами из серии «вспомни первый курс по алгоритмам», были, но бинарные деревья были один раз. В основном задавали вопросы про всякие linked-list'ы, там все гораздо проще, если помнишь хоть что-нибудь.
В основном задавали вопросы про всякие linked-list'ы, там все гораздо проще, если помнишь хоть что-нибудь.И тем не менее простейший вопрос типа «посчитайте количество элементов в бесконечном односвязном списке» ставит огромный процент претендентов в тупик.
посчитайте количество элементов в бесконечном односвязном списке
Нормальный претендент в ответ на такой вопрос напишет единственную строчку: return(INFINITY)
.
Потому что человек с программистким мышлением требует точной постановки задачи. В условии сказано: бесконечный — значит, размер равен бесконечности. Если Вы имели в виду "стопицот" — то это не "бесконечный", а "не помещающийся в памяти", и так и надо писать при постановке задачи; программист не играет в угадайку "а что постановщик вообще этим сказать хотел".
Потому что человек с программистким мышлением требует точной постановки задачи.Вы уж извините, но постановка задачи как раз вполне себе чёткая.
В условии сказано: бесконечный — значит, размер равен бесконечности.Если сказано бесконечный, то это значит, что это списка без конца (по английски используется слово endless, что несколько упрощает задачу, но идея та же). А дальше — да, небольшой тест на разумность: хороший кандидат поймёт, что имелось в виду сразу или переспросит, а плохой да, напишет
return(INFINITY)
.Если Вы имели в виду «стопицот» — то это не «бесконечный», а «не помещающийся в памяти», и так и надо писать при постановке задачи; программист не играет в угадайку «а что постановщик вообще этим сказать хотел».Мы как бы говорим не об аутсорсе, а о приёме человека в штат. Если человек не готов додумывать, задавать вопросы в случае непонимания условия задачи, и требует, чтобы ему всё разжевали и в рот положили — то он нам, извините, не нужен: с подобными задачами отлично справляются условные «индусы» на аутсорсе, которые стоят гораздо, гораздо, дешевле.
P.S. Про «постановку в тупик» — я имел в виду, конечно, неумение написать код. Понятно, что
return(INFINITY)
— это клиника, но большинство кандидатов, даже поняв — что именно от них хотят неспособны это сделать.Если сказано бесконечный, то это значит, что это списка без конца (по английски используется слово endless, что несколько упрощает задачу, но идея та же)
"endless" — это в данном случае не "бесконечный", а "неограниченный". Переводчики такие переводчики.
Если человек не готов додумывать
Вот в этом-то и проблема: у большинства нанимателей почему-то не возникает даже и намёка на мысль о том, что разные люди могут думать по-разному, и воспринимать Ваше задание по-разному. Попытки "додумать" при этом могут привести к весьма плачевным результатам. Тут в соседнем треде кто-то "додумал", что при нечисловых данных на входе программа должна падать — "а чо, всё равно ничего сделать нельзя" — а если, утрируя, эта программа управляет реактором на АЭС?
Например, я в упор не понимаю Вашу задачу. "Посчитать количество слов" в неограниченном списке невозможно: если критерий останова есть, то список не является неограниченным, и наоборот, если критерия останова нет, то return(INFINITY)
является правильным ответом. Вы явно имеете в виду что-то другое, но — как собака: "знать-то знаю, но выговорить не могу".
Например, я в упор не понимаю Вашу задачу. «Посчитать количество слов» в неограниченном списке невозможно: если критерий останова есть, то список не является неограниченным, и наоборот, если критерия останова нет, то return(INFINITY) является правильным ответом. Вы явно имеете в виду что-то другое, но — как собака: «знать-то знаю, но выговорить не могу».Это у Вас какой-то заскок. Бывает. При очном собеседовании всегда переспросить можно, а на Хабре понять малость сложнее.
Отсутствие конца в списке не обозначает, что элементов в нём бесконечное число. Тут вроде про python говорили, так что пусть пример будет на питоне:
>>> a = [1, [2, [3, []]]]
>>> a[1][1][1] = a[1]
Теперь у нас в переменной a
список «без конца»:>>> a[0]
1
>>> a[1][0]
2
>>> a[1][1][0]
3
>>> a[1][1][1][0]
2
>>> a[1][1][1][1][0]
3
>>> a[1][1][1][1][1][0]
2
>>> a[1][1][1][1][1][1][0]
3
>>> a[1][1][1][1][1][1][1][0]
2
>>> a[1][1][1][1][1][1][1][1][0]
3
Однако: ходить-то вы по этому списку можете сколько угодно, но элементов-то там больше не стало! Их там по прежлему три!Вот я и хочу, чтобы мне написали функцию, которая выдавала бы это число, оценили бы сложность (как зависит время работы вашей фукнции от размера списка?) и т.п. Элементарная, в общем-то, задача, но народ путается.
Дело в том, что для того, чтобы взять поток мысли, выдаваемый клиентом, и перевести его в однозначную формулировку, понятную программисту (software developer), предназначен специальный человек — software consultant. И платят ему, мягко говоря, несколько больше, чем программисту, потому что работа очень нервная — целый день с идиотами общаться.
(Иногда software developer и software consultant совмещаются в одном человеке — мне, например, но это далеко не всегда так ;)
Ваша задача по-человеческипрограммистски будет звучать так:
Дан однонаправленный связный список (a[i].next = a[j]
) из конечного числа элементовL
, при этом известно, что он зациклен (т.е.a[y].next = a[x]
при некоторых неизвестныхx
иy
, таких, чтоx < y
). ОпределитьL
.
А есть ещё следующая ступень — software archaeologist: это когда есть куча кода без комментариев и документации, и надо понять, что эта куча делает, и почему она написана именно таким, а не иным образом. Это уже ещё более другие деньги.
Дело в том, что для того, чтобы взять поток мысли, выдаваемый клиентом, и перевести его в однозначную формулировку, понятную программисту (software developer), предназначен специальный человек — software consultant. И платят ему, мягко говоря, несколько больше, чем программисту, потому что работа очень нервная — целый день с идиотами общаться.Опять оказывается, что мы говорим «мимо» друг друга. «Клиенты» и «потоки мысли» существуют только в одном из миров (Консультационное ПО), во всех остальных програмист ну никак не может получить готовую формулировку, потому что важная часть его работы — это разработка требований и сочетание «хотелок» и «возможностей».
А ваша «человеческая» формулировка — невероятно узка. Можно же ведь переформулировать и так: «найти количество разных чисел, которые выдаст функция erand48 при заданном «зерне»» — ведь это та же самая задача, не так ли?
Но породить формулировку — это, как я уже заметил, полдела: да, совсем плохие кандидаты и на это не способны, но это позволяет отсеять только лишь небольшой процент. В любом случае: придумав точную формулировку нужно ведь потом эту задачу ещё и решить — и вот тут-то оказывается как-то, что мастера «Google-oriented programming»а на это зачастую неспособны.
вот тут-то оказывается как-то, что мастера «Google-oriented programming»а на это зачастую неспособны.
«найти количество разных чисел, которые выдаст функция erand48 при заданном «зерне»»
Это другая задача (Мне почему-то кажется, что это количество одинаково вне зависимости от зерна и ограничено разрядностью используемых чисел, но я могу ошибаться).
Моё гугл-фу сильнее твоего ;)Ну да — это половина решения. Но это всё-таки классическая задача, на практике всё-таки приходится придумывать «алгоритм похожий вон на то», а не просто copy-paste делать.
Это другая задача (Мне почему-то кажется, что это количество одинаково вне зависимости от зерна и ограничено разрядностью используемых чисел, но я могу ошибаться).Вы имеете в виду, что генератор всегда обходит все 248 чисел? Это, конечно, хорошее замечание, но это ведь не мешает вам написать функцию и проверить — действительно ли это так? Это ведь верно только для линейно-конгруэнтного метода (и то не всегда). А для других PRNG количество чисел вполне может зависеть от зерна.
Видите ли, мало поставить задачу, нужны ещё и граничные условия. Например — где у нас ограничение: по памяти или по процессору? В случае с массивом в памяти решение одно, а в Вашем втором примере (про res = erand48(res)
), возможно, имеет смысл кешировать возвращаемые подопытной функцией результаты, чтобы два раза не вставать вызывать erand48(x)
(один раз — для "быстрого" указателя, второй — для "медленного"). Предлагаемые решения могут сиииильно отличаться в зависимости от.
В случае с массивом в памяти решение одноЭто кто ж вам сказал, что «в случае с массивом решение одно»? Во-первых не с массивом, а со списком, а во-вторых обращение в память — это тоже, в общем-то, недёшево. И вполне может оказаться, что кеширование окажется небесполезно.
Мы как раз обход одной структуры в памяти пару недель назад оптимизировали с помощью введения нескольких кешей и обсуждали — сколько этих кешей нужно, когда их заводить и т.п., так что это не просто теоретические рассуждения (правда структура была чуть-чуть посложнее вышеописанного списка).
Предлагаемые решения могут сиииильно отличаться в зависимости от.Ну дык. Собственно в этом и заключается специфика работы не в области Консультационное ПО: когда у тебя нет чётких, заранее обговоренных криетериев «приёмки», то очень часто постановка задачи меняется в зависимости от того, что показывают эксперименты с той или иной реализацией. Так что выявлять «граничные условия» приходится, собственно, тому, кто решает задачу.
И да, все эти вещи обсудить с хорошим кандидатом тоже не грех… после того, как он напишет хоть какую-нибудь реализацию, конечно.
Во-первых не с массивом, а со списком,
Под "массивом" я подразумеваю структуру данных, имеющую интерфейсный метод []
, то есть допускающую доступ по индексу — а Ваш список это допускает: даже если для этого требуется вернуться к корню и добежать при помощи .next
до нужного элемента — всё равно это возможно, а детали реализации нас в данный момент не интересуют. (И не надо мне тыкать на википедийное "набор компонентов, расположенных в памяти непосредственно друг за другом", а то я Вам припомню про отображение виртуальных страниц на физическое ОЗУ и файл подкачки ;)
А мой "бесконечный список" из /dev/rand
такого интерфейса не имеет иметь не может ;)
А мой «бесконечный список» из /dev/rand такого интерфейса не имеет иметь не может ;)То есть списком и не является.
А вот списк erand48 таки списком является и «интерфейсный метод
[]
» он, разумеется, поддерживает.(И не надо мне тыкать на википедийное «набор компонентов, расположенных в памяти непосредственно друг за другом», а то я Вам припомню про отображение виртуальных страниц на физическое ОЗУ и файл подкачки ;)Припомните, почему нет. А заодно объясните — как именно всё это делает среднее время доступа по индексу зависящим от индекса для массива или не зависящим — для списка (это ведь практически самое важное различие между ними).
Мы с Вами просто опять говорим на разных языках. Я же сказал:
Под "массивом" я подразумеваю структуру данных, имеющую интерфейсный метод []
Всё. Про время доступа я ничего не говорил. Ваше определение "массива" отличается от него, всего-то делов. Бывает.
Ваше определение «массива» отличается от негоЭто не «моё определение». Это как раз то самое «википедийное» определение. На русской википедии:
одинаковое время доступа ко всем элементамНа английской:
Both store and select take (deterministic worst case) constant time.
всего-то делов.И действительно: когда задача на собеседовании определяется в неформальных терминах, то это ужас, это качмар, это небо падает на землю, когда одно из фундаментальных понятий Computer Scrience придаётся извращённый смысл — то это «всего-то делов».
Хороший подход. Объективный такой. Мне нравится.
Стоит заметить, что в русской вики определение получается некорректное в отличии от английской, где рассматривается determenistic worst case time.
Пример: доступ к элементу массива, находящемуся в той же кэш-линии, что и предыдущий использовавшийся элемент, и доступ к элементу, отсутствующему в кэше соответствующего уровня, осуществляется за разное время.
одинаковое время доступа ко всем элементам
"Одинаковое время доступа" — это "достоинство" (Вы заголовки секций, на которые ссылаетесь, хоть читаете?), а не часть определения; а про то, что "одинаковое" оно преимущественно в теории — можно долго спорить (с учётом того, что искомая область памяти может оказаться высвопленной в файл подкачки).
одно из фундаментальных понятий Computer Scrience придаётся извращённый смысл
Извращённый смысл ему придан десятилетиями виртуализации. В наше время массив — это "структура данных, предоставляющая доступ к своим элементам по целочисленному индексу". Всё. Как оно хранится, как оно работает — это всё детали реализации. Это может быть обычный сишный массив — *(base + sizeof(element) * index)
, это может быть memory mapped file, это может быть sparse array, это может быть всё, что угодно; если возможен доступ arr[i]
для любого i
— то для целей дискуссии за пивом, каковую мы с Вами тут имеем, это "массив". Dixi.
Ту же самую задачу можно хоть на Бейсике переписать и решить — суть-то не в синтаксисе.
Умение красиво рассказывать про ленивые вычисления в Хаскеле (где действительно бывают структуры, о размере которых нельзя говорить) не заменяет умение работать со структурами данных.
P.S. Можно, конечно, нарваться на условного «Нильса Бора», который всё знает и понимает, но не хочет отвечать потому, что его это всё достало и отсеять его — но так ли это страшно? Это ведь всего лишь обозначает, что этот самый условный «Бор» не очень-то и хочет работать конкретно у вас и вместо того, чтобы просто забрать CV вот так вот выкаблучивается — ну дык стоит ли тогда пытаться его силой затаскивать, если его душа реально чего-то другого хочет?
А пример ваш питоньий можете на C++ переписать?На C++ будет чуть длиннее, но, в общем, всё то же самое:
struct Node {
int value;
Node* next;
};
int main() {
Node *head = new Node{1, new Node{2, new Node{3, nullptr}}};
head->next->next->next = head->next;
std::cout << find_len(head) << std::endl;
}
Мне просто очень интересно, что из этого получится, можно ли это будет называть списком, и так далее.А почему нет? SICP, упражнение 3.18, к примеру — как раз от таких говорит.
И если бы мы с вами сошлись на том, что это таки список, то, вполне вероятно, на построенной в ходе дискуссии аксиоматике удалось бы доказать, что и в списке с числами Фибоначчи всего один элемент.Это — вряд ли. Там всё таки все элементы разные :-) Ну, почти.
Я вообще плохо представляю, кем надо быть, чтобы люди хотели не задачки интересные решать, не делать продукты в окрестности специализации вашей фирмы, не деньги зарабатывать, в конце концов, а именно работать у вас.Работодателем. Собственно любой работодатель смотрит, в том числе, и на то, насколько кандидат заинтересован в том, чтобы устроиться к нему на работу.
Собственно любой работодатель смотрит, в том числе, и на то, насколько кандидат заинтересован в том, чтобы устроиться к нему на работу.
"Это было давно и неправда" ©. Последние лет так десять в нашей отрасли кандидаты смотрят на то, насколько работодатель заинтересован, в том, чтобы кандидат работал именно на него. Просыпайтесь.
Последние лет так десять в нашей отрасли кандидаты смотрят на то, насколько работодатель заинтересован, в том, чтобы кандидат работал именно на него.Ну дык. Финальная стадия пузыря, чего вы хотите.
А статья смешная, да. Достойна того, чтобы занять на полке место рядом с пресловутым Концом истории. Будет смотреться также смешно лет так через 10.
Одни рассказ про то, что ошибки, которые стоят, в буквальном смысле слова, сотни миллиардов долларов (Space Shuttle, ТУ-144) это ерунда по сравнению с тем, какой ужас способны устроить программисты — уже смешон. А уж выводы.
А правда заключается в том, что в любой отрасли есть люди, которые очень дорого стоят и за «головы» которых идёт настоящая охота.
Но к рядовым разработчикам это ни в одной области не относится — и IT исключением не является.
Не менее принципиальный вопрос вам на засыпку: какой тип элемента списка в вашем плюсовом коде?Причём тут «тип элемента»? От этого у вас алгоритм изменится?
Не более разные, чем в первых двух вариантах, где одни единички получаются, разве нет?«Более разные». В случае с однонаправленным списком (пусть он хоть на камешках реализован с мальчиками, бегающими по острову) мы можем гарантировать, что элементов там — конечное число и, главное, можем на них ссылаться и сравнивать.
В случае с Haskel-струкртурами ни того, ни другого делать нельзя.
Любому™ адекватному™ работодателю понятно, что мне, в общем-то, куда интереснее решать интересные задачи, желательно за интересные деньги, нежели чем испытывать благоговение от самого факта работы на Гундекс/Майкругл/етц.Ну если вы так считаете — то значит вы к нам и не придёте, проблем-то.
Никто ведь не гонит вас под дулами автоматов именно в Гундекс/Майкругл/етц.
"Бесконечный" в математическом смысле — это infinite ("бесконечное множество" — infinite set). "Зацикленный" — looped.
Дело в том, что бесконечный незацикленный односвязный список вполне возможен — например, while(1) { fread(fopen('/dev/rand', 'rb'), 1); }
. То, про что пишет автор — это конечный зацикленный односвязный список.
Ну как где, берёте значение, которое вернул fread
, и складываете его куда хотите — вот Вам и список, и продолжаться он может до тепловой смерти Вселенной компьютера.
А что касается зацикленных списков — не знаю что такое «бесконечный зацикленный список», но структуру сводяющуюся примерно к описанным «спискам с циклами» я разбирал примерно месяц назад. Там, правда, списков могло быть много, цикл мог быть не один и они ещё и переплетены могли быть… но это — уже детали же, согласитесь?
Поэтому и стоит быть готовым к тому, что кандидат вам не поймёт, а когда вы дадите ему наводящий пример на питоне, выдаст вам чего-нибудь на хаскеле, и начнёт с вами обсуждать это всё, ну, в том духе, что мы тут втроём обсуждаем.Очень чувствуется отсутствие практического опыта проведения интервью, извините.
Вы проведите пару сотен интервью для начала, а потом начинайте рассуждать о том, что может случиться и когда. «Чего-нибудь на Хаскеле» выдаёт, дай бог, один кандидат из сотни (после чего его на работу, как мы знаем не берут — что и правильно, так как подобные ответы обозначают, что работа его интересует меньше, чем желание выпендрится), а написать хоть что-то вообще может, дай бог, один кандидат из трёх (если не один кандидат из десяти).
И это, наверное, даже хорошо, потому что такой человек таки с большей вероятностью осилит пустить два итератора по списку, или чего там в питоне с этим делать.Ну вот если он это на интервью сделает — молодец, получит ещё пару вопросов, а затем и предложение о работе. Если нет… ну это его выбор, в конце-то концов.
Эзотерические задачи я собираюсь решать за обедом с коллегами в качестве полезной разминки для мозгов, но я ведь нанимаюсь не команду в обед развлекать, поэтому логичнее спрашивать меня что-то более релевантное, не правда ли?Да, в общем, почти всё равно что спрашивать — важно увидеть как кандидат год писать будет.
Почему вдруг типичная задача из типичного курса по структурам данным вдруг стала «эзотерической» — мне, в общем, неведомо, но если кандидат код не напишет, то резулюция «No Hire» следует, в общем, независимо от того не умеет кандидат это делать или не хочет: вы ведь нанимаетесь чтобы «решать задачи», как вы сами написали, а не «объяснять почему конкретно вы конкретную задачу решать не будете».
Специалистов по последнему, как показывает практика, гораздо больше — но они мало кому нужны.
Несколько дополнительных вопросов, пара картинок — и, если кандидат хоть какой-то опыт имеет, формулировка в стиле Wesha — готова.
А вот написание кода для большинства кандидатов — проблема. Ещё какая. Примерно как в широко известно опусе.
Может быть вам действительно везло с кандидатами.
Поэтому edrand48 — это вполне себе односвязный список, а вот drand48 — уже нет (можно долго и упорно спорить является ли пара drand48/seed48 списком, впрочем...).
«Запоминать» в контексте хаскеля ещё меньше смысла имеет (если вы имеете ввиду ссылку/указатель).«Запоминать» в конексте Хаскеля можно, конечно. Позицию в erand48 запомнить можно, а в «списке»
/dev/rand
(который, напоминаю, получает энтропию от аппаратных источников) — нельзя. И это фундаментальная разница с которой никакой, самый модный, язык ничего поделать не сможет.Одного взгляда на сигнатуру repeatНе очень понятно как программа может бросить этот «один взгляд» получив объект. Хотя, может, через интроспекцию в каких-то реализациях?
В любом случае: либо вы можете предложить как это программно понять и тогда у списка естественным образом появится длина, либо не сможете — и тогда это не список.
@khim, Wesha, 0xd34df00d
Вы сейчас спорите об определениях, причем выдумывая их на ходу.
В контексте структур данных, список (более корректно, связный список) — это класс структур данных, основанных на идее хранения последовательности путем добавления к элементам указателей на соседей. Такие списки могут быть односвязными и многосвязными, плотными и разреженными, с заголовком и без него.
А еще они могут быть циклическими и обычными (и я ни разу до этого для не слышал чтобы обычный циклический список называли бесконечным). Разумеется, у циклических списков есть вполне определенная длина и алгоритмы ее нахождения.
В функциональном программировании, списком называется вполне конкретная структура данных, основанная на идее разбиения последовательности на голову и хвост. Эта структура данных чем-то напоминает обычный односвязный список — но все же отличается. К примеру, обычное и деструктивное получение первого элемента в односвязном списке — это две совершенно разные операции, но для списка в ФП это одно и то же.
Вот эти списки и правда бывают бесконечными — но и длина бесконечного списка также бесконечна. Точнее, она не определена — поскольку невозможно алгоритмически определить, является ли указанный список бесконечным (проблема останова).
В информатике вообще, списком называется любая структура данных, хранящая упорядоченные данные (упорядоченные — значит, что для двух элементов списка можно сказать какой идет первее другого).
Ну и в таких языках программирования как C# и Java, списком (List) называется упорядоченная коллекция, допускающая доступ по целочисленному индексу, причем в Java список — это только интерфейс, а в C# список — это и интерфейс, и его же реализация над массивом (IList<>/List<>).
Массив же — всегда был набором элементов одного типа, последовательно расположенных в адресном пространстве. Разумеется, в тех языках, в которых нет понятия адреса, требование непрерывного расположения элементов становится неактуальным, что приближает массив к списку.
Но массив всегда считался конкретной структурой данных, а не интерфейсом или классом структур данных. (Если кто-нибудь знает языки программирования где массивом считается что-то иное, пожалуйста расскажите о них).
Файл /dev/random, конечно же, не является ни массивом ни списком. Оба этих понятия подразумевают как минимум воспроизводимость результатов.
Наверное, про /dev/random можно сказать "последовательность" — но это понятие также зависит от контекста.
К примеру, многие алгоритмы нахождения наибольшей возрастающей подпоследовательности не смогут работать с /dev/random напрямую.
Вы сейчас спорите об определениях, причем выдумывая их на ходу.Вы действительно считаете, что спорящие тут этого не понимают? Да, разумеется, это спор об определениях. Для того он, в частности, и задаётся в такой формулировке — чтобы понять как кандидат будет на это реагировать.
Есть несколько вариантов:
- Кандидат офигивает от формулировки, но, подумав несколько минут, говорит: «вы имеете в виду циклический список и хотите, чтобы я две бегунка пустил?» — и пишет программу.
Вывод: хороший кандидат, скорее всего берём, но, конечно, это зависит от того, как он отвечает на другие вопросы тоже. - Кандидат долго пытается понять, чего от него хотят, через час, с горем пополам, пишет нечто слегка похожее на программу, которая, впрочем, не работает (самый популярный результат).
Вывод: отвратительный кандидат, не берём, говорить не о чем. - Кандидат уходит в спор об определениях, объясняет, что формулировка некорректа и вообще всячески показывает свою эрудированность. Кода в результате нет.
Вывод. Отличный кандат… для наших конкрентов. Не брать.
Всё просто: как я уже сказал: недоговорки и неточные определения — часть производственного процесса. Если кандидат «знает как с этим жить» и может, несмотря ни на что, выдать результат — то это «наш кандидат», с ним будет приятно работать и команда в 1000 человек не будет ждать его из-за того, что поля на техзадании оказались не по ГОСТу. Если кандидат либо не может, либо не хочет в таких условиях работать — нам он не подходит, будь он хоть трижды гений.
Вот и всё.
Это — разумеется, требования которые я применяю к кандидату. Вполне могу предствить себе компанию, где всё по другому и где люди, требующие чётких формурировок, но при этом не отличающие списка от массива будут востребованы. Но это — не у нас.
Если кто-нибудь знает языки программирования где массивом считается что-то иное, пожалуйста расскажите о них.PHP. Как уже было написано: Этот тип данных ведёт себя как список, упорядоченный хэш, упорядоченный набор, разреженный список и время от времени как их странные комбинации. Какая его эффективность? Каков будет расход памяти?(пер. анализ расхода памяти для массивов) Кто знает? У меня всё равно нет других вариантов.
Ну уже даже JavaScript имеет отдельно массивы и объекты — и массивы ведут себя как массивы, а объекты — как объекты (хотя и используют при это одинаковый синтаксис). Одна есть огромное количество разработчиков, которые понятия не имеют в чём отличие этих структур данных и когда использовать одно, а когда другое. Их вопросы сложности и расхода памяти не заботят вовсе — и, опять-таки: возможно, что существуют компании, которым такие люди подходят.
Вы действительно считаете, что спорящие тут этого не понимают? Да, разумеется, это спор об определениях. Для того он, в частности, и задаётся в такой формулировке — чтобы понять как кандидат будет на это реагировать.
Но в таком случае зачем вы тут спорите об определениях? Это ж не собеседование :)
Самых важных слов — о том, что выбранная формулировка является намеренно некорректной, вы и не сказали. Вместо этого вы почему-то начали объяснять что формулировка вполне корректна, на примере связного списка в Питоне. По крайней мере, я, прочитав все ваши комментарии, так и не понял что вы знаете разницу между бесконечным списком и циклическим. Потому-то эту разницу вам и начали объяснять.
Что же до самой идеи задать на собеседовании некорректное задание и посмотреть на реакцию — могу сказать следующее. При общении с заказчиком, ежели кто-нибудь меня до него допустит, я буду помнить, что он совсем не разбирается в программировании, и мне, возможно, придется еще "расшифровывать" его речь. Если я работаю с экспертом — мне надо вообще забыть про "свои" термины и подробно изучать предметную область. При общении с аналитиком я буду помнить, что знание структур данных для аналитика — необязательно, но буду ожидать от него наличие общих знаний по информатике. Но от своего коллеги, пусть даже начальника, я ожидаю корректного использования профессиональных терминов.
Я ожидаю слишком многого?
Я ожидаю слишком многого?Ну как вам сказать, чтобы не обидеть…
Senior Software Engineer; Software Archaeologist:
В наше время массив — это «структура данных, предоставляющая доступ к своим элементам по целочисленному индексу». Всё. Как оно хранится, как оно работает — это всё детали реализации. Это может быть обычный сишный массив — *(base + sizeof(element) * index), это может быть memory mapped file, это может быть sparse array, это может быть всё, что угодно; если возможен доступ arr[i] для любого i — то для целей дискуссии за пивом, каковую мы с Вами тут имеем, это «массив».Такие дела.
А вы говорите «корректное использование профессиональных терминов»…
Если "в наше время" понимать как "в языках программирования, достаточно абстрагированных от железа" — то я с ним даже согласен. Потому что в отсутствии в языке указателей и адресной арифметики само понятие "непрерывной области памяти" полностью теряет смысл.
При общении с заказчиком, ежели кто-нибудь меня до него допустит, я буду помнить, что он совсем не разбирается в программировании, и мне, возможно, придется еще "расшифровывать" его речь.
Вот и я тредстартеру пытаюсь объяснить это уже пятый раз: задача software developer — взять условие задачи и реализовать код, её рещающий. Причём если в условии полная хня — то и код будет такой же, либо не будет вообще: garbage in — garbage out. А "понять, что же там заказчик мямлит и корректно поставить задачу девелоперу" — это работа software consultant совсем за другие деньги.
"Поэтому я вам советую подождать специалиста, договориться с нянечкой и заплатить. Но можно этого и не делать. Если вас не интересует результат." ©
А тредстартер хочёт "два в одном флаконе" за ту же цену.
Всё просто: как я уже сказал: недоговорки и неточные определения — часть производственного процесса.
Всё с Вами понятно: хочется иметь software consultant, а платить ему как software engineer. Плавали, знаем.
"Пятница. Пришёл лесник и выгнал из лесу всех — и нас, и белых." ©
Массив же — всегда был набором элементов одного типа, последовательно расположенных в адресном пространстве. Разумеется, в тех языках, в которых нет понятия адреса, требование непрерывного расположения элементов становится неактуальным
Вот и я про то же: в наше время массив — набор однотипных элементов, доступных по индексу (требование доступности по физическому адресу из-за отсутствия таковой размывания понятия всякими виртуализациями заменяется требованием доступности по индексу — "виртуальному адресу")
Не совсем так. Если язык умеет работать с указателями и допускает арифметические операции над ними — то такие операции имеют смысл только в пределах некоторых непрерывных (в адресном пространстве процесса) блоков памяти. Такие блоки в этих языках и называют массивами.
В тех языках, где работа с памятью полностью спрятана, понятие массива "свободно" и может использоваться для любой структуры с индексатором.
непрерывных (в адресном пространстве процесса)
Ключевая фраза! В реальной физической памяти оно может располагаться как угодно, хоть на винчестере.
Как я уже написал выше, я последние 10 лет работаю на Ruby, в котором, в самом деле, "понятие массива "свободно" и может использоваться для любой структуры с индексатором." (Arrays are ordered, integer-indexed collections of any object. ) Поэтому я и произнёс по привычке фразу, с которой и проистёк весь этот спор.
С позиции опытного разработчика:
Гуглить что?
Чаще всего я гуглю тексты ошибок и куски стектрейсов
Затем — тёмные или подзабытые места фреймворков типа "hibernate declare composite key". Если мне нужно начать использовать новый фреймворк, я предпочту потратить день и прочитать официальную документацию.
И никогда — чужой код. Чужой код при решении проблем нужен только для того, чтобы изучить те API, которыми он пользуется для решения проблемы.
Исключение — это реализация достаточно сложных алгоритмов типа BCrypt, но и там не стоит брать первый попавшийся кусок.
Вкратце: гуглить надо прежде всего чужой опыт и чужие впечатления. Знания лучше по-возможности получать из документации, а код — писать самому или брать известные библиотеки.
К примеру, я сейчас по работе часто обращаюсь к документации по Unreal Engine. В 99% случаев это вбитый в гугле запрос, который ведет на страницу документации. Оставшийся процент — перекрестные ссылки.
Наверное, речь идет о С++ и документации к API? Я пишу на Java и там нет такой проблемы — документация к методу находится в исходниках непосредственно над методом и практически ко всем библиотекам есть исходники, которые автоматически подцепляются к проекту. Если же речь идет о крупном закрытом API — то я предпочитаю документацию, оформленную одним документом в html или pdf и ищу по ctrl+f. Если такой возможности нет — то да, только гугль. Почти всегда он ищет лучше, чем специализированные "поиски по онлайн документации".
Я пишу на Java и там нет такой проблемы — документация к методу находится в исходниках непосредственно над методомТак и в C++ бывает, но непонятно как это поможет писать код. Читать — да, но писать…
Как вы без поиска понимаете как должен называться метод, который «делает X»? Одно и то же действие можно называть сотней разных способой (если это не какая-нибудь базовая бибоитека, оперирующая уже давным-давно устоявшейся терминологией).
Лучше прочитать про чужие грабли, чем наступить на свои.
Так что не вижу ничего плохого (тем более, что решение проблемы, по которой не удалось нагуглить решение, поднимает ЧСВ ещё примерно на over 9000)
обновляется не так быстро
Рандомный вопрос со stackoverflow, опубликованный час назад, уже проиндексировался.
тыц тыц.
Ищу по названию StrelkiJS — ничего (хотя слово в статье есть)
Ищу по названию Strelki.js — показывает кучу ссылок
Видимо кое-что уже занеслось в индекс, но не все. Ну а Гугль, как обычно, сразу все загрузил.
Кого не устраивает выдача DDG, может использовать startpage.com — этакий прокси-поисковик, анонимно передающий запросы в Google. Поисковой линзы нет, много раз проверял, Столлман одобряет (https://stallman.org/stallman-computing.html, ищем «ixquick», это то же самое).
Вот, почитайте: https://support.google.com/websearch/answer/2466433?hl=ru
К сожалению, они выкинули оператор "+" — обязательное включение в запрос, в любой форме, не синоним. Какое-то время эту задачу кое-как выполняли кавычки (без стемминга, очевидно), но сейчас даже слова в кавычках игнорирует, правда пока хотя бы указывает, что выкинул. Скоро и это уберут наверняка.
Их можно понять, это часть неудавшейся рекламной компании. Они впихивали гугл-плюс во все сервисы, пытаясь использовать для рекламы все сайты в их власти. Но фейсбук не сломить.
Книга для research'а. Ну или научная статья. Которую нагуглил.
Для решения насущных проблем книга не подходит. Невозможно держать в голове все, что ты когда либо прочитал. Да что там прочитал — собственноручно написанный код начисто забывается через год. Я несколько раз слышал о случаях, когда человек гуглил свою проблему и находил свой же ответ на каком-то сайте, оставленный несколько лет назад.
Работа почти любого программиста связана с какой-то стандартной платформой. Уж точно 99% программистов в том же гугле. Если вы не используете фреймворк — вы все равно используете язык программирования и стандартную библиотеку, x86/arm, сетевые протоколы, и т. д.
Ну я по 100 раз на дню гуглю вещи которые 100 раз уже видел, например, методы классов String и Map (для Java — базовее не придумаешь). Всякие сниппеты, например, как сконвертировать строку из одной кодировки в другую, как прочитать содержимое из архива, и т. д. Если нет интернета (например в самолете) — конечно могу написать такие вещи сам, основываясь на API стандартной библиотеки, которое доступно в оффлайне (и по которому есть навигация в IDE). Но если есть гугл — никогда так не делаю, потому что 1) нагуглить быстрее 2) меньше вероятность что упустишь какой-то момент и сделаешь ошибку в мини-велосипеде. Сниппеты со StackOverflow обычно отполированы опытом.
100 раз это не преувеличение — вообще в определенные периоды я в среднем делал по 100-150 поисков в день, хотя не использовал никакие фреймворки. Сейчас в среднем 30-50 поисков в день.
Так?
Хороший программист прежде всего помнит что существует формула для обьема, во вторых понимает что обьем красного резинового мячика равен обьему синего, а так же не резинового и не мячика. Он понимает что единственный значимый параметр — диаметр, а вот потом уже со спокойной совестью гуглит, если данную конкретную формулу он не помнит.
Для металлического мячика — зафиксировал параллельно 2 плоскости, загнал между ними мячик, сближаешь поверхности пока мячик позволяет.
Но резиновый мячик будет сплющиваться во что-то эллипсоидное.
Подвесить мяч на резинке к потолку, под него источник света, и замерять освещенную площадь? Так проще в стакан с водой кинуть…
2. померить диаметр тени от солнца или другого источника прямых лучей, если тень эллиптическая — в самой узкой части тени
3. посыпать мячик сверху псевдослучайным потоком мелких дробинок, потом посчитать сколько из них не отскочили, а упали на поверхность (например, плотный клей), посчитать площадь методом Монте-Карло, вычислить диаметр
Если я иду по поводу рассыпавшегося рейда, то мне вряд ли придётся гуглить информацию о том, как разные его варианты устроены. Иначе я бы не шёл.
Так и с инженером. Может — решает. Не может — по таким кейсам, думаю, процедура у них описана.
В книге есть содержание и возможно предметный указатель, что является ссылкой на источник.
Google поисковик информации, интернет можно представить себе как подобие большой книги, а книгу можно представить как некоторый объем информации которая имеет определенный формат. Поисковик анализируя страницы в сети, строит свое содержание и предметный указатель.
Дело в свойствах этой информации — объективность, достоверность, полнота…
Бумажное издание часто проходит модерацию, в сети это проделать невозможно и не нужно. Но это не определяет гарантии качества по обе стороны.
Нужно и читать и гуглить, смотреть и слушать, все способы хороши, в любом случае вы получаете одно и тоже — информацию.
Решили провести тест на интеллектуальное развитие студентов, подошли поочередно к студентам 1-го, 2-го, 3-го, 4-го и 5-го курсов и спросили: «Сколько будет дважды два?»
1-й курс (быстро): «4!»
2-й курс (быстро посмотрев в шпору): «4!»
3-й курс (достав калькулятор, быстро): «4!»
4-й курс (торопясь, полистав справочник): «4!»
5-й курс (с возмущением!): «Что я, все константы должен помнить?»
Простите, у Вас туннельное зрение? Я уже осветил этот вопрос.
Мы выяснили: гуглят все. Разница в том, как.
Касается, в общем-то, не только программистов.
Здравствуйте, я админ. И я гуглю.
Вот только гуглить как я в моём окружении может 2 или 3 человека. Остальные десятки будут искать то же самое решение долго и мучительно.
Это хороший универсальный навык. Потому что занимаясь своим хобби (а это уже как раз программирование) я ищу на примерно том же уровне, что и в области моей профессиональной деятельности.
Моё личное мнение — если ты не гуглишь, то, скорее всего, ты останавливаешься в развитии. Или уступаешь другим, если не умеешь искать.
Единственное, о чем я беспокоюсь — рано или позддно гугль возьмёт нас в «оборот» и заставит заплатить за все прошлые и будущие ответы.
Не могу судить, дело в объёме проиндексированной сети, в том, что для гугл нативный язык — английский или у меня самого корявость английского лучше подходит под гугл, чем под яндекс.
1) я уже знаю ответ на вопрос, просто не помню точной формулировки (например, название параметра/класса/метода)
2) я вообще не знаю, в какую сторону искать, но есть за что зацепиться (например, сообщение об ошибке в слабо знакомой технологии)
3) необходимая срочность решения
В остальных случаях хотя бы полчаса-час решаю задачу самостоятельно (анализ сорцов либы, эксперименты, спеки). Даже получив ответ, иногда все же захожу в гугл — посмотреть чужой опыт и найти нехватающие нюансы. Полученный таким способом ответ намного лучше оседает в памяти, да и ачивка за решение — всегда приятно.
Если программист копипастит код без понимания как он работает — это халтурщик и гнать его в шею.
Это в принципе любых профессий касается.
Владение профессиональными терминами и правильное их употребление в контексте, с моей т.з. достаточный тест на профпригодность. Человек не знакомый с типографией будет говорить «расстояние между строк» а знакомый — «интерлиньяж», и найдет более качественную информацию. Кроме того сразу видно как человек владеет языком. Сравните: «как сделать интервал между строк другим» и «как изменить межстрочный пробел».
Гуглить почему-то считается моветоном, хотя он экономит время а значит и деньги. Думаю Гуглу надо просто открыть новый сервис: Google Pro — все то же самое, но с обязательной регистрацией, за деньги, и без рекламы. (Для тех кому для имиджа нужно пользоваться только самыми профессиональными инструментами :)
Одна конечная цель и не столь важно каким способом ее достигать, а если я могу тратить меньше времени на поиск решения, а выполнять больший объем работы, то нет смысла противиться прогрессу.
Еще один немаловажный факт заключается в самооценке, многие себя переоценивают или напротив, недооценивают, но даже отличный программист может оказаться профаном в чуждой ему области или плохой программист может дать отличные советы по частному вопросу.
В самом начале своего пути приходилось изобретать сортировки, какие то списки, а сейчас нет нужды тратить часы жизни на придумывание давно созданного и отлаженного.
Тем не менее, на практике получается так, что наработки кем — то сделанные и публикуемые на Интернет использую нечасто, чаще использую свои систематизированные наработки — это и быстрее и надежнее, в части ожидаемого результата
Google-oriented programming