Разгребая и фильтруя древнюю почту, наткнулся на письмо содержащее несколько вопросиков, которые мне задавались на первой заочной стадии интервью на позицию Senior Java Developer (я там не сильно ещё надоел этими Java interview?).
Сразу хочу заметить что вопросов будет всего-то ничего, и заданы они были по е-майл и тем самым использовались как механизм базовой фильтрации кандидатов.
А вот в какую компанию было собеседование – хоть убей не помню, да и сейчас это уже не столь важно.
Task 1 – Literature
Tell us about your top three books that have made you a better software developer.
Task 2 – Monetary calculations
If you have $200 in your pocket, and you see a shelf with a long row of foobars priced at $1, $1.2, $1.44, $1.728 and so forth. Every foobar cost 20% more than the previous one. You buy one of each foobar, starting with the one that costs $1, until you can’t afford the next foobar on the self (the foobars are ordered by price). How many foobars can you buy, and how much change will you get? Your task is to write a small routine to solve this problem, and then demonstrate the correctness of your routine by writing a test for it.
Task 3 – Static factories
Give us at least two advantages with static factory methods compared to constructors, and at least one disadvantage.
Task 4 – Declarations
If you see this line in a method that you are going to modify: ArrayList testList = new ArrayList();
Is there anything that you would like change in this statement?
Task 5 – J2SE
Construct a list containing all weekdays for an arbitrary period in an arbitrary year. No saturdays nor sundays is supposed to be in this list. Write a class containing the methods that you need for constructing such a list. Take into account that the content in this list may be presented in more than one way. You can assume that your class’ only task is to return this list.
Конечно же для полноценной оценки знаний и опыта кандидата этого совершенно не достаточно, но вполне хватит чтоб не тратить время на кандидатов близких к “абсолютному нулю”.
Принимайте на вооружение!
А как бы вы ответили на вопросы 1, 3 и 4?
Tweet
1: В порядке полезности
a. Паттерны ГoФ
b. “Архитектура програмного обеспечения” Л. Басс, П. Клементис, Р. Кацман
c. SICP (http://mitpress.mit.edu/sicp/full-text/book/book.html)
:)
Владимир,
В моем варианте Шаблоны GoF были на втором месте вслед за Refactoring Фаулера
Вадим,
В своём варианте я просто постарался выбрать книги из 3-х ортогональных областей в программировании.
Я рефакторинг и паттерны всё-же отношу к одной плоскости, поэтому включил сюда только одну из этих двух книг. Выбирая между рефакторингом и паттернами я выбрал паттерны :)
А что было 3-м в вашем варианте?
1.1. Design Patterns
1.2. Refactoring to Patterns
1.3. Patterns of EAA
фаулеровский рефакторинг пока не читал. :(
3. Могу разве что предположить, что одно из достоинств, это то, что static-методы могут иметь имя, не зависящее от имени класса, которое более точно отражает их суть. Больше что-то ничего в голову не приходит?
4. List testList = new ArrayList(), но это реально зависит от контекста.
Владимир,
По третьему вопросу:
Advantages:
3.1. Ability to control the object creating/initializing
3.2. It`s easy to substitute object with another with same type & without client code changes
Disadvantage:
– see 3.1 & 3.2
По 4-му, кроме как добавить добавить параметризацию generic-типа ArrayList и указать initial capacity – больше ничего не придумал.
А что бы вы ответили?
По третьему
Advantages:
1 Ability to control exact type of produced object.
2 Ability to reduce dependence of users code from exact type of produced object.
Disadvantage:
In general case disability of users code to control exact count of created objects.
По четвертому вопросу, можно ещё вспомнить про Arrays.asList.
1.1 Дональд Кнут “Искусство программирования”
1.2 Design Patterns
1.3 Thnking in Java
2. согласен с предыдущими ораторами. Disadvantages: потеря производительности, пусть не значительная, но все же.
3.1 меняем ArrayList testList = new ArrayList() на List testList = new ArrayList(). можно на Collection, но там нет метов, доступных в List.
3.2 добавляем дженерики, если речь о 5/6 джавае
Антон,
Ты прочитал Кнута??? Всего??? :-0
По поводу ArrayList => List полностью согласен. Жаль только что самому это в голову не прийшло.
И с чего бы это FactoryMethod снижает производительность? Дополнительный вызов метода?
Вадим, ну не то чтобы всего. но первые три части читал, правда давно и пришел к выводу, что все-таки Кнут это больше справочник, особенно третий том. но если уж говорить о книгах по программированию, которые оставили в моей жизни след — то Кнут первый среди равных :)
именно дополнительный вызов. я же говорю, потеря микроскопическая, но она есть :)
А нас в универе на втором курсе по Кнуту гоняли – IMHO немного рано, вот если бы на 4м – так самое ОНО.
Как говорил мой бывший коллега (Паша, привет!)
“Кнут – это книга must have, но не must read” :)
не, нас не гоняли. нам вообще в универе программирование преподавали странно. может потому я Кнута и читал :) услышал, что есть такая книга, у товарища была. я ее тогда — тоже курсе на втором-третьем — осиливал по полгода том. цитировать уже не смогу, все-таки давно это было, но тогда я высшую математику знал не плохо и материал лег в хорошо удобренную почву. таки да, must have. я вот никак не выберусь купить.
Стосовно третього питання: забули вказати таку перевагу як зрозумілість. Іншими словами назва фабричного метода може вказувати як сворюється об”єкт
наприклад
getDefaultUserAccessor() – вказує, що ми отримаємо інстанст типу UserAccessor з дефолтовою імплементацією
getActionCommandSingleton() – вказує, що сворений об”єкт буде сінгельтоном
P.S. може наведені приклади не дуже добрі, але ідея я думаю зрозуміла
да, и возвращаясь к топику — initial capasity для ArrayList тоже хороший прием. но тут нужно представлять сколько у тебя будет элементов в массиве, хотябы приблизительно. а случайные знанчения бессмысленны сами-по-себе. если нужна оптимизация по памяти, то можно заменить ArrayList на LinkedList. но тут потереям в быстродействии на множественном добавлении элементов за рамками initial capacity. с другой стороны в высоконагрузочных системах часто используют именно LinkedList.
Якщо потрібно багато добавляти даних в ліст, то як на мене не погана ось ця імплементація http://commons.apache.org/collections/api-release/org/apache/commons/collections/list/TreeList.html
1. a. Thinking in Java.
b. Какая то книжка про паттерны в джава. Там были и обычные ГоФ и Энтерпрайз паттерны.
с. Некая книга Introduction to Algorithms. Именно оттуда я узнал что числа нужно сортировать за линейное время :).
Еще хотелось бы добавить Таненбаума про операционные системы и еще читал какую то огромную книжку про сети, протоколы и т.д.
Ну а Кнут как мне кажется уже устаревшая штука. И еще наблюдаю за собой тенденцию что большинство программистской инфы и идей черпаю давным давно не из книг а из различных мэнюалов.
3. а. + Позволяет контролировать тип возвращаемого обьекта.
б. + позволяет навешывать некоторые дополнительные сервисы без изменения клиентского кода: например кеширование обьектов или синглтонизацию.
в.+ отделяет логику создания(а она может быть очень большая) от логики обьекта
г. – — новая сущность, усложняющая систему.
4. Я бы тоже написал: List l = new ArrayList();
2. Как раз когда много данных в лист добавлять то этот класс лудше не юзать так как сложность добавления элемента в дерево O(ln(n)) а скажем в LinkedList O(1). А класс TreeList юзается если нужно иметь отсортированный лист.
Про TreeList это я corsair-у адрессовал. :)
2corsair, стосовно зрозумілості коду дозволю собі не погодитись. як на мене, то більш зрозумілої конструкції ніж Foo f = new Foo() годі й шукати. а що до зрозумілості методів factory, то це суто питання дизайну коду. якщо дизайн коду є, то всі методи всіх класів будуть зрозуміли, якщо дизайну нема…
що стосується apache-commons, по-перше, як зазначив шановний Андрей, вартість операцій із деревом набагато перевищує вартість операцій зі списком. по-друге, це є third-party library. я для себе вивів не гласне правило, якщо я можу зробити щось засобами SDK, я буду робити це засобами SDK. усім гарні third-party libraries, одним погані — не є частиною SDK, тому їх завжди потрібно десь брати, десь зберігати і якось долучати до проекту. тим більш, що гарного рішення задля “executable” jar не існує out of the box.
2Андрей, не знаю, не знаю, я бы поспорил насчет утверждения “Кнут устарел”. у Кнута как-раз описаны фундаментальные знания, основы программирования. они не могут устареть, как не может устареть теорема Пифагора. эти знания можно лишь корректировать со временем, как теорию Ньютона.
Ну по поводу TreeList, то на самом деле это нужный класс очень. В LinkedList & ArrayList например линейны операции удаления. Ну а стандартный TreeSet не может быть заменой TreeList по причине того что он не имплементирует List, что проявляется в том что нету методов прямого доступа к элементам.
Все же остаюсь на своем что Кнут устарел. Там много устаревшего материала. Большинство материала не обязательно к прочтению. Кнутовский псевдоассемблер и машина с регистрами далеко не вершина читабельности. Тем более после книг кнута было сделано куча всяких других замечательных открытий например по теории графов, которые по понятным причинам не могут войти в книгу кнута. То есть мой вывод: если человек хочет разобраться в базовых понятиях алгоритмов я бы порекомендовал ему другую книгу. Для того что бы освежить память вердикт аналогичен.
2Андрей, дык весь ASF очень полезен и хорошо, ктож спорит. вопрос в том, что если нам не нужно хранить дерево, то нам незачем тащить за собой лишнюю библиотеку. только и всего. ну в данном случае дерево, а вообще — если нам достаточно стандартных средств SDK, то third-party libraries нам не нужны. собственно в этом суть моего коммента, не в том, что TreeList плох.
ответы на впросы 3, 4, 5 есть в книге Effective Java от J.Bloch. Авторы, скорее всего, составляли их на основе лучших рпактиик, используемых в этой книге.
Тем, кто не читал, предлагаю ознакомится, весьма занимательная книга. На данный момент есть и второе издание, значительное расширенное по сравнению с первым.
Прочитал все ответы и не нашел одного из основных преимуществ статических нициализаторов: создание инициализаторов с идентичной сигнатурой.
MyClass.createSimpleObject(int id, String name);
MyClass.createComplexObject(int id, String name);
5 вопрос, несмотря на свою простоту, ставить очень важный вопрос: реализовать список через делегирование или наследование?
Ответ в указанной книге :)
2Андрей
Ну для початку чим відрізняється List від Set? В List елемент завжи добавляється в кінець, і тому він, якщо ти не добавляєш завчасно відсортовані дані, буде не відсортований. А якщо ще сходиш по тому лінку що я привів – то побачиш. що він не реалізує жодного інтерфейсу для сортування, а також в описі не містить жодного слова про те що данні які в нього добавляються будуть відсортовані.
Я так розуміющо, що просто спутали з TreeSet
2Anton Naumov
Давай приклад Foo f = new Foo() трішки ускладним
Foo f = new Foo(1,2,3,4,5,6,7,8)
і скажімо комбінація 2,5,1,6,2,4,7,5 це комбінаця з якою найчастіше приходить створювати об”єкти. Ну нехайти таких комбінацій буде ще 3. І того ми маємо 4 комбінації параметрів які часто використовуються. Невже краще кожен раз їх забивати руками ніж створити фабричний метод?
2corsair, якщо метод має більш ніж три параметри, то це вже lack of design. і тут потрібно не фабрику створювати (хоча можливо й вона не зашкодить), а робити рефакторінг коду.
Один из немногих случаев, в которых я не согласен с Фаулером и GoF.
If you see this line in a method that you are going to modify: ArrayList testList = new ArrayList();
Is there anything that you would like change in this statement?
Переименовать testList в iAmJustAnotherStupidNamedVariable.
2Vadim Voituk, а почему не согласен? мне правда интересно. я видел довольно много кода и когда параметров больше 5ти, то ориентироваться довольно сложно. нес-па?
Антон,
С тем что много параметров – это зло, – согласен.
Не согласен с тем, как Фаулер предлагает решать подобную проблему – введение обьекта-параметра или же дополнительной связи. В результате получаем сущности, которые не представляют из себя бизнес-обьекты, а также туеву хучу лишних связей, которые затрудняют code reuse.
Мне же больше по душе вариант с factory-методом, предложенный Пашей (corsair).
2Vadim Voituk, ну воспринимай объек-параметр как еще один Bean, почему нет? дополнительные связи это не всегда зло, хотя лучше их избегать. можно также сделать редизайн кода, если это возможно. убрать не обязательные параметры в сеттеры, использовать наследование… масса вариантов, один из них действительно фабрика. но мне как-то объекты-параметры не мешают. наоборот.
В ідеальних умовах – проект пишеш ти з самого початку, або хтось інший але під твоїм пильним керівництвом – так часто і буває, що методи немають багато параметрів. Але в житті приходиться стикатися коли код вже написаний і його потрібно використовувати.
А взагалі – навіть якщо і один параметр, то приклад
Foo foo=new Foo(“Hello”);
приємніше виглядає як
Foo foo=Foo.createDefaultFoo();
але тільки при умові, що значення параметра “Hello” є дефолтовим, часто використовується і що в майбутньому в конструктор можуть добавити ще параметрів, щоб задати дефолтовий стан об”єкту.
Без останньої умови можна поюзати і просто константи.