JavaRush /Blog Java /Random-FR /Noyau Java. Questions d'entretien, partie 1
Andrey
Niveau 26

Noyau Java. Questions d'entretien, partie 1

Publié dans le groupe Random-FR
Pour ceux qui entendent le mot Java Core pour la première fois, ce sont les fondements fondamentaux du langage. Avec ces connaissances, vous pouvez partir en toute sécurité pour un stage/stage. Noyau Java.  Questions d'entretien, parties 1 à 1Ces questions vous aideront à rafraîchir vos connaissances avant l'entretien ou à apprendre quelque chose de nouveau par vous-même. Pour acquérir des compétences pratiques, étudiez à JavaRush .
  1. Comment créer un objet immuable en Java ? Énumérez tous les avantages

    Une classe immuable est une classe dont l'état ne peut pas être modifié après la création. Ici, l'état d'un objet est essentiellement considéré comme les valeurs stockées dans une instance d'une classe, qu'il s'agisse de types primitifs ou de types référence.

    Afin de rendre une classe immuable, les conditions suivantes doivent être remplies :

    1. Ne fournissez pas de paramètres ou de méthodes qui modifient les champs ou les objets faisant référence aux champs. Les setters impliquent de changer l'état d'un objet, ce que nous voulons éviter ici.
    2. Créez tous les champs finalet private. Les champs marqués privatene seront pas accessibles de l'extérieur de la classe, et les marquer finalgarantit que vous ne les modifierez pas, même par accident.
    3. N'autorisez pas les sous-classes à remplacer les méthodes. Le moyen le plus simple de procéder est de déclarer la classe comme final. Les classes finalisées en Java ne peuvent pas être remplacées.
    4. N'oubliez jamais que vos instances de variables peuvent être mutables ou immuables. Définissez-les et renvoyez de nouveaux objets avec du contenu copié pour tous les objets mutables (types de référence). Les variables immuables (types primitifs) peuvent être renvoyées en toute sécurité sans aucun effort supplémentaire.

    Vous devez également vous rappeler les avantages ultérieurs des classes immuables. Vous pourriez en avoir besoin lors d’un entretien. Classes immuables :

    • facile à concevoir, tester et utiliser
    • automatiquement thread-safe et n'a aucun problème de synchronisation
    • ne nécessite pas de constructeur de copie
    • vous permettre d'initialiser paresseusement un hashcode et de mettre en cache la valeur de retour
    • ne nécessitent pas de copie sécurisée lorsqu'ils sont utilisés comme champ
    • créer de bonnes Mapclés et Setéléments (ces objets ne doivent pas changer d'état lorsqu'ils sont dans la collection)
    • rendez votre classe permanente en la créant une fois, et elle n'a pas besoin d'être vérifiée à nouveau
    • avoir toujours une « atomicité d'échec » (un terme inventé par Joshua Bloch) : si un objet immuable lève une exception, il ne restera jamais dans un état indésirable ou indéfini.

    Regardez l'exemple écrit dans cet article .

  2. En Java, passer par valeur ou par référence ?

    La spécification Java indique que tout en Java est transmis par valeur. Il n'existe pas de "passage par référence" en Java. Ces conditions sont associées à l'appel de méthodes et à la transmission de variables comme paramètres de méthode. D'accord, les types primitifs sont toujours transmis par valeur sans aucune confusion. Mais le concept doit être clair dans le contexte d’un paramètre de méthode de types complexes.

    En Java, lorsque nous transmettons une référence de type complexe comme paramètre de méthode, l'adresse mémoire est toujours copiée étape par étape dans une nouvelle variable de référence. Regardez l'image :

    Noyau Java.  Questions d'entretien, parties 1 à 2

    Dans l'exemple ci-dessus, les bits d'adresse de la première instance sont copiés par une autre variable de référence, ce qui fait que les deux références pointent vers le même emplacement mémoire où l'objet est stocké. N'oubliez pas qu'en attribuant null au deuxième lien, vous n'attribuerez pas null au premier lien. Mais un changement d'état d'un objet avec une variable de référencement sera reflété dans un autre lien.

    Voir les détails ici .

  3. A quoi sert le bloc finally? Ce bloc garantit-il l’exécution de son code ? Quand finallyun bloc n’est-il pas appelé ?

    Un bloc finallyest toujours appelé s'il tryexiste. Cela garantit que le bloc finallyest appelé même si une exception inattendue se produit. Mais finallyil est plus utile que simplement pour gérer les exceptions - ce bloc vous permet de nettoyer le code qui a été accidentellement contourné par return, continueou break. Placer du code de nettoyage dans un bloc finallyest toujours une bonne pratique, même lorsqu'aucune exception n'est attendue.

    Если виртуальная машина завершает работу во время выполнения блока try or catch, тогда блок finally не будет выполнен. Аналогично, если нить, выполняя блок try or catch, будет прервана or убита, блок finally не будет выполнен, даже не смотря на то, что приложение продолжает работать.

  4. Почему существует два класса Date, один в java.util package а другой в java.sql?

    java.util.Date представляет date и время, а java.sql.Date представляет только date. Дополнением к java.sql.Date является класс java.sql.Time, который представляет только время.

    Класс java.sql.Date является субклассом (расширением) класса java.util.Date. Итак, что изменилось в java.sql.Date:

    • toString() формирует другое представление строки: yyyy-mm-dd
    • статический метод valueOf(String) создает date из строки с вышеуказанным представлением
    • исключены геттеры и сеттеры для часов, minutes и секунд

    Класс java.sql.Date используется в JDBC и предназначен, чтобы не иметь составляющую времени, то есть часы, minutesы, секунды и миллисекунды должны быть нулю… но это не является обязательным для класса.

  5. Разъясните интерфейсы-маркеры.

    Шаблон интерфейса-маркера – это шаблон проектирования в компьютерных науках, используемый языками программирования, которые предоставляют информацию об an objectх во время выполнения. Это предоставляет способ ассоциации метаданных класса, где язык не имеет явной поддержки таких метаданных. В Java для этого используются интерфейсы без указания методов.

    Хорошим примером применения интерфейса-маркера в Java является интерфейс Serializable. Класс реализует этот интерфейс для указания, что его не transient данные могут быть записаны в поток byteов or на файловую систему.

    Главной проблемой интерфейса-маркера является то, что интерфейс определяет соглашение для реализующих его классов, и это соглашение наследуется всеми субклассами. Это значит, что вы не сможете «де-реализовать» маркер. В приведенном примере, если вы создадите субкласс, который вы бы не хотели сериализовать (возможно потому, что он находится в преходящем (transient) состоянии), вы должны прибегнуть к явному бросанию NotSerializableException.

  6. Почему метод main() объявлен How public static void?

    Почему public? Метод main имеет модификатор доступа public, поэтому он может быть доступен везде и для любого an object, который захочет использовать этот метод для запуска applications. Тут я не говорю, что JDK/JRE имеют подобный повод, поскольку java.exe or javaw.exe (для windows) используют Java Native Interface (JNI) вызов для запуска метода, поэтому они могут вызвать его в любом случае, независимо от модификатора доступа.

    Почему static? Давайте предположим, что у нас метод main не статический. Теперь, для вызова любого метода вам необходим экземпляр класса. Верно? Java разрешает иметь перегруженные конструкторы, это мы все знаем. Тогда который из них должен быть использован, и откуда возьмутся параметры для перегруженного конструктора?

    Почему void? Нет применения для возвращаемого значения в виртуальной машине, которая фактически вызывает этот метод. Единственное, что приложение захочет сообщить вызвавшему процессу – это нормальное or ненормальное завершение. Это уже возможно используя System.exit(int). Не нулевое meaning подразумевает ненормальное завершение, иначе все в порядке.

  7. В чем разница между созданием строки How new() и литералом (при помощи двойных кавычек)?

    Когда мы создаем строку используя new(), она создается в хипе и также добавляется в пул строк, в то же время строка, созданная при помощи литерала, создается только в пуле строк.

    Вам необходимо ознакомиться с понятием пула строк глубже, чтобы ответить на этот or подобные вопросы. Мой совет – How следует выучите класс String и пул строк.

    У нас в переводах уже есть хорошая статья о строках и строковом пуле: Часть 1, Часть 2.
  8. Как работает метод substring() класса String?

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

    /** The value is used for character storage. */
    /** Значение используется для хранения символов */
    private final char value[];
    Для доступа к этому массиву в различных сценариях используются следующие переменные/** The offset is the first index of the storage that is used. */
    /** Смещение – это первый индекс используемого хранorща. */
    private final int offset;
    
    /** The count is the number of characters in the String. */
    /** Счет – это количество символов в строке. */
    private final int count;

    Каждый раз, когда мы создаем подстроку от существующего экземпляра строки, метод substring() только устанавливает новые значения переменных offset и count. Внутренний массив символов не изменяется. Это возможный источник утечки памяти, если метод substring() использовать неосторожно:

    Первоначальное meaning value[] не изменяется. Поэтому если вы создадите строку длиной 10000 символов и создадите 100 подстрок с 5-10 символами в каждой, все 101 an objectы будут содержать один и тот же символьный массив длиной 10000 символов. Это без сомнения расточительство памяти.

    Этого можно избежать, изменив code следующим образом:

    заменить original.substring(beginIndex) на new String(original.substring(beginIndex)), где original – исходная строка.

    Примечание переводчика: я затрудняюсь сказать к Howой версии Java это применимо, но на данный момент в Java 7 этот пункт статьи не актуален. Метод substring() вызывает конструктор класса new String(value, beginIndex, subLen), который в свою очередь обращается к методу Arrays.copyOfRange(value, offset, offset+count). Это значит, что у нас будет каждый раз новое meaning переменной value[], содержащее наше новое количество символов.
  9. Объясните работу HashMap. Как решена проблема дубликатов?

    Большинство из вас наверняка согласится, что HashMap наиболее любимая тема для дискуссий на интервью в настоящее время. Если кто-нибудь попросит меня рассказать «Как работает HashMap?», я просто отвечу: «По принципу хэширования». Так просто, How это есть.

    Итак, хеширование по сути является способом назначить уникальный code для любой переменной/an object после применения любой формулы/алгоритма к своим свойствам.

    Определение карты (Map) таково: «Объект, который привязывает ключи к значениям». Очень просто, верно? Итак, HashMap содержит собственный внутренний класс Entry, который имеет вид:

    static class Entry implements Map.Entry
    {
    final K key;
    V value;
    Entry next;
    final int hash;//More code goes here
    }

    Когда кто-либо пытается поместить пару ключ-meaning в HashMap, происходит следующее:

    • В первую очередь, an object ключа проверяется на null. Если ключ null, meaning сохраняется в позицию table[0]. Потому что хэшcode для null всегда 0.
    • Затем, следующим шагом вычисляется хэш meaning вызывая у переменной-ключа свой метод hashCode(). Этот хэш используется для вычисления индекса в массиве для хранение an object Entry. Разработчики JDK прекрасно понимали, что метод hashCode() может быть плохо написан и может возвращать очень большое or очень маленькое meaning. Для решения этой проблемы они ввели другой hash() метод, и передают хэшcode an object этому методу для приведения этого значения к диапазону размера индекса массива.
    • Теперь вызывается метод indexFor(hash, table.length) для вычисления точной позиции для хранения an object Entry.
    • Теперь главная часть. Как мы знаем, два неодинаковых an object могут иметь одинаковое meaning хэшcodeа, How два разных an object будет храниться в одинаковом расположении в архиве [называется корзиной]?

    Ответ – LinkedList. Если вы помните, класс Entry имеет свойство “next”. Это свойство всегда указывает на следующий an object в цепи. Такое поведение очень похоже на LinkedList.

    Итак, в случае совпадений хэшcodeов, an objectы Entry хранятся в форме LinkedList. Когда an object Entry необходимо разместить на конкретном индексе, HashMap проверяет, существует ли на этом месте другой an object Entry? Если там нет записи, наш an object сохранится в этом месте.

    Если на нашем индексе уже находится другой an object, проверяется его поле next. Если оно равно null, наш an object становится следующим узлом в LinkedList. Если next не равно null, эта proceduresа повторяется, пока не будет найдено поле next равное null.

    Que se passe-t-il si nous ajoutons une autre valeur clé égale à celle que nous avons ajoutée précédemment ? Il est logique qu'elle remplace l'ancienne valeur. Comment cela peut-il arriver? Après avoir déterminé l'index de position de l'objet Entry, itérer sur la position LinkedListsituée à notre index HashMapappelle une méthode equals()sur la valeur clé de chaque objet Entry. Tous ces objets Entryont LinkedListla même valeur de hashcode, mais la méthode equals()vérifiera la véritable égalité. Si la clé. equals(k)sera vrai , alors les deux seront traités comme le même objet. Cela entraînera uniquement le remplacement de l'objet value dans le fichier Entry.

    Ainsi, HashMapil garantit l’unicité des clés.

  10. Différences entre les interfaces et les classes abstraites ?

    C'est une question très courante si vous passez un entretien pour un programmeur de niveau junior. Les différences les plus significatives sont énumérées ci-dessous :

    • Dans les interfaces Java, les variables sont a priori final. Les classes abstraites peuvent contenir des non- finalvariables.
    • Une interface en Java ne peut absolument pas avoir d'implémentation. Une classe abstraite peut avoir des instances de méthode qui implémentent un comportement de base.
    • Les composants de l'interface doivent être public. Une classe abstraite peut avoir des modificateurs d'accès adaptés à vos goûts.
    • L'interface doit être implémentée par le mot-clé implements. Une classe abstraite doit être étendue à l'aide du mot clé extends .
    • En Java, une classe peut implémenter de nombreuses interfaces, mais ne peut hériter que d'une seule classe abstraite.
    • Une interface est complètement abstraite et ne peut pas avoir d'instances. Une classe abstraite ne peut pas non plus avoir d'instances de la classe, mais peut être appelée si une méthode existe main().
    • Une classe abstraite est légèrement plus rapide qu'une interface car celle-ci attend une recherche avant d'appeler une méthode remplacée en Java. Dans la plupart des cas, il s'agit d'une différence mineure, mais si vous écrivez une application urgente, vous devez en tenir compte.
  11. Quand remplacez-vous les méthodes hashCode()et equals()?

    Les méthodes hashCode()et equals()sont définies dans la classe Object, qui est la classe parent de tous les objets Java. Pour cette raison, tous les objets Java héritent de l'implémentation sous-jacente de ces méthodes.

    La méthode hashCode()est utilisée pour obtenir une valeur entière unique pour un objet donné. Cette valeur est utilisée pour déterminer l'emplacement de la corbeille lorsque l'objet doit être stocké dans une structure de données telle que HashTable. Par défaut, la méthode hashCode()renvoie une représentation entière de l'adresse mémoire où l'objet est stocké.

    La méthode equals(), comme son nom l'indique, est utilisée pour l'équivalence d'objets simples. L'implémentation de base de la méthode consiste à vérifier les références de deux objets pour vérifier si elles sont équivalentes.

    Notez qu'il est généralement nécessaire de surcharger une méthode hashCode()chaque fois qu'une méthode est surchargée equals(). Ceci est nécessaire pour prendre en charge la convention générale de la méthode hashCode, qui stipule que les objets égaux doivent avoir des codes de hachage égaux.

    La méthode equals() doit déterminer l'égalité entre les relations (elle doit être récurrente, symétrique et transitive). De plus, il doit être persistant (si l'objet n'a pas changé, la méthode doit renvoyer la même valeur). De plus, o.equals(null)il doit toujours renvoyer false .

    hashCode()doit également être persistant (si l'objet n'a pas changé dans les conditions de la méthode equals(), il doit continuer à renvoyer la même valeur.

    La relation entre les deux méthodes est la suivante : toujours, si a.equals(b), alors a.hashCode()doit être identique à b.hashCode().

Bonne chance dans tes études !! Auteur de l'article Lokesh Gupta Article original Liens vers d'autres parties : Java Core. Questions d'entretien, partie 2 Java Core. Questions pour un entretien, partie 3
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION