Автор Тема: Проверка на не логику.  (Прочитано 9044 раз)

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Проверка на не логику.
« : Август 14, 2012, 09:46:27 am »
На хабре появилась статья про то как на собеседованиях (на php программиста, но это не важно) проверяют людей на умение думать и на логику.

Цитировать
Как известно, большинство тонкостей логически выводятся из понимания более общих вещей. Я считаю, что хорошего программиста от плохенького кодера отличает желание и умение применять логику. Именно поэтому меня не так сильно интересует, знает ли кандидат ответ на мой вопрос. Меня больше впечатляет его умение вывести правильный ответ логически или логически объяснить то, что он знает.

Посыл хороший, но вот как это выглядит на практике:
Цитировать
Первый вопрос

— Можем ли мы отнаследоваться от абстрактного класса и не реализовать некоторые из его абстрактных методов?

Кажется, ответ лежит на поверхности. Но тем не менее, правильный ответ мы получаем очень редко, поэтому за вопросом обычно следуют наводящие вопросы:
— Давайте рассмотрим родительский класс, из чего он состоит?
— Свойства, реализация методов, абстрактные методы.
— Правильно, теперь представим, что в дочернем классе мы не реализовали какие-то из абстрактных методов. Из чего он состоит?
— Мы не можем этого сделать.
— Давайте представим, что можем. Тем более, я уверяю Вас, что мы можем.
— Из свойств, реализации методов и… Нет, здесь будет ошибка.
— Дочерний класс отнаследует абстрактные методы родительского, но не реализует их. Значит, какие это будут методы?
— Абстрактные.
— Правильно. Значит, дочерний класс у нас какой?
— Будет ошибка.

Максимум на этом месте (зависит от нашего настроения и наличия свободного времени) кандидат получает от нас правильный ответ, а первая проверка работы логики заканчивается провалом.

Впрочем, тут еще можно было догадаться что хочет услышать собеседующий, но второй вопрос...

Цитировать
Второй вопрос

— Можем ли мы в классе реализовать интерфейс и не реализовать какие-то из описанных в нём методов?

Как ни странно, чаще всего ситуация повторяется. И снова следуют наводящие вопросы:
— Давайте вспомним прошлый вопрос.
— Так с интерфейсами всё по-другому.
— Почему?
— Мы не можем это сделать, потому что они не классы и мы изначально говорим, что мы их реализуем. Будет ошибка.
— Давайте представим, что можем. Тем более, я уверяю Вас, что мы можем.
— Я Вас не понимаю.

Вторая проверка работы логики заканчивается провалом.
Внимание вопрос - где тут та самая логическая цепочка по которой можно было бы вывести, что не реализовав один из методов мы обязаны объявить класс как абстрактный? Ну вот возьмем ObjC - там это делать не нужно. Smalltalk? Аналогично. typeclass'ы в haskell'e? Или реализуешь все, или ничего (хотя могу ошибаться, давно хаскеля в руках не держал).

Ну и третий вопрос:
Цитировать
— Класс синглтон. Сможете сходу сказать, какие элементы должен содержать класс, чтобы мы могли его считать синглтоном?

Тут часто отвечают правильно про то, что нужен метод получения экземпляра класса, переменная, в которую мы будем сохранять этот экземпляр и содержимое которой мы будем проверять при попытке получить экземпляр класса. При этом безбожно путают статические методы и свойства и методы и свойства объекта. Но сейчас не об этом.

— Хорошо, таким образом мы предоставляем возможность получать один и тот же экземпляр класса из любого места в приложении. Теперь нам нужно убедиться, что экземпляр класса будет только один.
— Ммм.
— Проще говоря, нам нужно убедиться, что экземпляр класса будут получать только через этот метод. Что нам нужно для этого сделать?
— В смысле?
— Какие у нас есть способы создания объекта?
— New.
— Правильно, а ещё?
— Не знаю.
— Ну ладно, не суть важно, ещё существует клонирование объектов.
— Что-то слышал, но не использовал.
— Так что нам нужно сделать, чтобы мы не могли создавать объект в обход статического метода получения экземпляра?
— Это Вы сейчас new имеете ввиду?
— Да, именно его.
— Нужно в конструкторе вызывать статический метод получения класса.

Дальше идёт такая каша, что до модификаторов доступа на конструктор и магический метод клонирования добраться удаётся не всегда. И эта проверка работы логики также не увенчалась успехом.
Как логически тут можно вывести эти знания? Это ведь нужно ЗНАТЬ, что конструктор можно запихнуть в приватную секцию, что есть понятие клонирования объекта и как его запретить.

Да, кроме того, синглетон - это поведение. А как именно оно будет реализовано - не важно абсолютно. Например класс-синглетон может банально иметь только статические члены (создавать таких "объектов" можно сколько угодно, но вести они будут себя как единый синглетон), либо может свое состояние держать в базе данных (то есть быть тупо проксей). Автор же статьи подталкивает к "единственно верному" решению не включая собственную логику.

Похоже под логикой подразумевается умение угадать тот ответ который хочет услышать собеседующий. Печально.

Да, а оригинал статьи тут: http://habrahabr.ru/post/148509/
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #1 : Август 14, 2012, 10:41:09 am »
Цитировать
typeclass'ы в haskell'e? Или реализуешь все, или ничего (хотя могу ошибаться, давно хаскеля в руках не держал).
Это необязательно. Кроме того, в описании класса типов можно сразу указать реализацию, например:
class Eq a where
    x == y = not (x /= y)
    x /= y = not (x == y)
затем, при инстанцировании этого класса каким-то типом, достаточно будет реализовать только один из этих методов и второй будет уже готов.

А проблемы с синглтонами вообще высосаны из пальца из-за того, что используются немодульные языки -- были бы модули, и синглтоны были бы не нужны автоматически...
« Последнее редактирование: Август 14, 2012, 11:26:51 am от valexey »
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #2 : Август 14, 2012, 11:29:43 am »
Цитировать
typeclass'ы в haskell'e? Или реализуешь все, или ничего (хотя могу ошибаться, давно хаскеля в руках не держал).
Это необязательно. Кроме того, в описании класса типов можно сразу указать реализацию, например:
class Eq a where
    x == y = not (x /= y)
    x /= y = not (x == y)
затем, при инстанцировании этого класса каким-то типом, достаточно будет реализовать только один из этих методов и второй будет уже готов.
Речь не об этом. Допустим у нас в описании типа класса нет реализации по умолчанию всех функций (и == и /=), допустим также при инстанцировании мы не реализовали ==, но реализовали /=. Внимание вопрос - что будет?

А проблемы с синглтонами вообще высосаны из пальца из-за того, что используются немодульные языки -- были бы модули, и синглтоны были бы не нужны автоматически...
Чем java-класс не модуль? :-) (в рассматриваемом аспекте)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #3 : Август 14, 2012, 02:03:49 pm »
Речь не об этом. Допустим у нас в описании типа класса нет реализации по умолчанию всех функций (и == и /=), допустим также при инстанцировании мы не реализовали ==, но реализовали /=. Внимание вопрос - что будет?

Я понял, о чём речь, поэтому и ответил: "Это необязательно."
А конкретно будет вот что. Допустим такой код:
module Main where

class (Show a) => TestClass a where
    foo :: a -> String
    foo x = show x ++ " is here"

    bar :: a -> String
    bar x = foo x ++ " and " ++ baz x

    baz :: a -> String

instance TestClass Int where
    foo x = "This is " ++ show x

main = do
    putStrLn $ foo (5 :: Int)
    putStrLn $ bar (5 :: Int)
    putStrLn $ baz (5 :: Int)

WinHUGS принял этот код без возражений, но при выполнении выдал исключение:
Main> :main
This is 5
This is 5 and
Program error: undefined member: baz
GHC и GHCi выдали предупреждение об ошибке:
The Glorious Glasgow Haskell Compilation System, version 7.4.1
[1 of 1] Compiling Main             ( TestClass.hs, TestClass.o )

TestClass.hs:12:10:
    Warning: No explicit method nor default method for `baz'
    In the instance declaration for `TestClass Int'
но код приняли, при выполнении ошибка:
*Main> main
This is 5
This is 5 and *** Exception: TestClass.hs:12:10-22: No instance nor default method for class operation Main.baz
D:\Prj\Haskell>TestClass.hs.exe
This is 5
TestClass.hs.exe: TestClass.hs:12:10-22: No instance nor default method for class operation Main.baz

Если не вызывать нереализованные методы, то ничего плохого не будет, разве что компилятор предупреждением поругает. Но если вызвать, то произойдёт ошибка времени исполнения.

Вообще, на этом трюке основан очень простой алгоритм самого эффективного вычисления чисел Фибоначчи -- возведением в степень матрицы (Gosper-Salamin):
{-# OPTIONS_GHC -XTypeSynonymInstances -XFlexibleInstances #-}

type GS = (Integer, Integer)
instance Num GS where
    (a,b) * (c,d) = (a*(c+d) + b*c, a*c + b*d)

fib n = fst (x^n)
  where x = (1,0) :: GS
Здесь реализован метод умножения матриц, который потом подхватывается дефолтным методом возведения в степень. Получается очень быстро и очень компактно.

Конечно, это потенциальная уязвимость -- возможность вызова нереализованных методов, но компилятор об этой проблеме предупреждает (например, в случае с этим вариантом чисел Фибоначчи компилятор предупреждает, что программист не реализовал методы (+), abs, signum, fromInteger).
Ну, тут авторы языка сделали уступку удобству...

Чем java-класс не модуль? :-) (в рассматриваемом аспекте)
java-класс может быть систанцирован в несколько экземпляров -- в этом и есть проблема.
Приходится идти на ухищрения -- скрывать конструктор класса, обеспечивать возможность использования всего лишь одного экземпляра класса...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #4 : Август 14, 2012, 02:11:23 pm »
Речь не об этом. Допустим у нас в описании типа класса нет реализации по умолчанию всех функций (и == и /=), допустим также при инстанцировании мы не реализовали ==, но реализовали /=. Внимание вопрос - что будет?

Я понял, о чём речь, поэтому и ответил: "Это необязательно."
А конкретно будет вот что. Допустим такой код:
...
Если не вызывать нереализованные методы, то ничего плохого не будет, разве что компилятор предупреждением поругает. Но если вызвать, то произойдёт ошибка времени исполнения.
То есть так же как в ObjC. И, подозреваю, в smalltalk.

Чем java-класс не модуль? :-) (в рассматриваемом аспекте)
java-класс может быть систанцирован в несколько экземпляров -- в этом и есть проблема.
Приходится идти на ухищрения -- скрывать конструктор класса, обеспечивать возможность использования всего лишь одного экземпляра класса...
Я говорю не про java-объект, а про java-class :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Проверка на не логику.
« Ответ #5 : Август 14, 2012, 02:16:05 pm »
А проблемы с синглтонами вообще высосаны из пальца из-за того, что используются немодульные языки -- были бы модули, и синглтоны были бы не нужны автоматически...
Это не так. Иногда нужны полиморфные синглетонистые объекты. Типичный пример -- фабрики. Объект фабрики обычно синглетонистый, но в то же самое время полиморфный, его класс отнаследован от класса абстрактной фабрики. В Блэкбоксе это обычно какие-нибудь там StdDirectory отнаследованные от Directory.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #6 : Август 14, 2012, 05:32:24 pm »
Если не вызывать нереализованные методы, то ничего плохого не будет, разве что компилятор предупреждением поругает. Но если вызвать, то произойдёт ошибка времени исполнения.
То есть так же как в ObjC. И, подозреваю, в smalltalk.
Не знаю, как там в ObjC, а в смоллтоке так из-за позднего связывания. В хаскелле же это не так -- никакого позднего связывания в хаскелле нет, и конкретно этот момент -- просто безалаберность авторов языка.

Я говорю не про java-объект, а про java-class :-)
Объект -- это экземпляр класса, по крайней мере так было всегда.
В чём же схожесть класса в java с модулями того же оберона?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #7 : Август 14, 2012, 05:41:47 pm »
Объект -- это экземпляр класса, по крайней мере так было всегда.
В чём же схожесть класса в java с модулями того же оберона?
Схожесть в том, что class в java это единца которую можно загрузить, выгрузить, которая имеет собственные глобальные переменные (которые инициализируются в момент загрузки класса).
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #8 : Август 14, 2012, 05:52:29 pm »
Но модули оберона инстанцировать-то нельзя.
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #9 : Август 14, 2012, 06:01:06 pm »
Но модули оберона инстанцировать-то нельзя.
Это мелкая частность не имеющая отношения к рассматриваемой задаче (ибо это НИКАК не мешает).

Вот скажи, какая мне разница будет кто-то создавать объекты такого класса, или нет:
class Singleton {
    static int a = 0;
    static int b = 42;
    public static int  getA()       {return a;             }
    public static void setA(int _a) {a=_a;                 }
    public static void talkWithMe() {System.out.println(b);}
}
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #10 : Август 14, 2012, 06:18:37 pm »
Много синтаксического мусора со всем этими static и final...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #11 : Август 14, 2012, 07:05:02 pm »
Много синтаксического мусора со всем этими static и final...
А где там final?
Но вообще java славится отсутствием регионных модификаторов, следовательно приходится повторять.

Но вообще, мы ж не про синтаксис, а про семантику говорили :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #12 : Август 17, 2012, 08:26:11 am »
Много синтаксического мусора со всем этими static и final...
А где там final?

По логике такие классы-модули следует делать финальными, наверное?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #13 : Август 17, 2012, 09:29:03 am »
Много синтаксического мусора со всем этими static и final...
А где там final?

По логике такие классы-модули следует делать финальными, наверное?
А смысл?
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Проверка на не логику.
« Ответ #14 : Август 17, 2012, 11:00:35 am »
Ну что бы их нельзя было расширять, ибо какой смысл в расширении модуля?

Хотя может и есть такой смысл?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…