Kotlin | Вопросы собесов
2.56K subscribers
30 photos
971 links
Download Telegram
Forwarded from easyoffer
Финальный отсчёт:
3 часа до конца краудфандинга easyoffer 2.0!


Это не просто скидка. Это шанс поддержать проект, который поможет и вам и тысячам айтишников готовиться к собеседованиям быстрее, эффективнее и увереннее.

За последние недели:
💥 Нас поддержали уже больше 1450 человек;
🔥 Вместе собрали больше 4,5 млн. рублей на запуск проекта;

Но сейчас важнее другое.

Через 3 часа всё закончится.
– Больше не будет подписки за 3 200 руб. на целый год!
– Не будет шанса первыми воспользоваться EasyOffer 2.0 на бета-тестировании

Если вы:

+ Планируете менять работу в этом или следующем году;
+ Хотите иметь под рукой 40,000+ вопросов собеседований с разборами, видео-ответами и тренажёрами;
+ Хотите зафиксировать лучшую цену на целый год… (потом будет в 12 раз дороже)

👉 Тогда просто переходите и поддержите нас сейчас:
https://planeta.ru/campaigns/easyoffer

📢 Три часа — и всё.
Не откладывайте на потом.

Спасибо всем, кто уже с нами! 💙
💊1
Forwarded from easyoffer
🚨 60 минут до финала

Через час мы закроем краудфандинг easyoffer 2.0
Это последний шанс вписаться в самые выгодные условия.

👉 https://planeta.ru/campaigns/easyoffer
Please open Telegram to view this post
VIEW IN TELEGRAM
💊2
Forwarded from Идущий к IT
Я смотрю на эту цифру и до сих пор не верю.

Когда я запускал этот проект, мне реально было страшно. Страшно, что ничего не получится. Что я и мой проект никому не нужен. Страшно, что все увидят, как я публично обосрался.

Я ставил планку в 300т рублей. В самом позитивном сценарии 1млн. Но про 5 миллионов… даже мысли не было. Уже в первые часы стало понятно, что кампания идет не по плану. Сайт краудфандинга не выдержал нашей нагрузки и лег 😁

Особенно в последние три дня — просто какой-то разрыв! Я ощущал, как будто ловлю попутный ветер. В последний час не хватало 50к до 5 млн, и я уже думал сам их докинуть, чтобы красиво закрыть 😁

Но финальная сумма это не так важно. Самое главное это как мы её собрали. Это не инвестиции, не чьи-то деньги под условия и контроль, не кредит. Это вы поверили и поддержали меня напрямую. Вы дали мне возможность оставить за собой полный контроль над easyoffer.

Я чувствую огромную ответственность и нервничаю из-за высоких ожиданий. А вдруг что-то пойдёт не так? А вдруг на релизе кому-то что-то не понравится? Именно поэтому я рад, что могу честно выйти на новый этап и без давления от левых инвесторов.

В такие моменты вспоминаю, с чего всё начиналось. Как 2 года назад я писал свои первые посты на 500 человек о том, как учу программирование. Как записывал первое видео на YouTube про поиск работы. Как пилил первую версию easyoffer, вообще без понимания, что из этого выйдет.

И сейчас я думаю — может, эта история вдохновит кого-то из вас. Может, кто-то запустит свой айтишный проект, найдёт поддержку и соберёт бабки на развитие. Было бы круто

Спасибо за невероятную и колосальную поддержку ❤️
О такой аудитории как вы я не мог мечтать
💊6
🤔 Как решить проблему утечек памяти в RxJava?

RxJava может вызывать утечки памяти, если подписки (Disposable) не очищаются правильно.
Утечки памяти происходят, когда RxJava-события продолжают выполняться после уничтожения Activity/Fragment, удерживая ссылки на View или Context.

🚩Используем `CompositeDisposable`

CompositeDisposable собирает все подписки и очищает их при onDestroy().
class MainActivity : AppCompatActivity() {
private val disposables = CompositeDisposable() // Собираем подписки

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val disposable = Observable.interval(1, TimeUnit.SECONDS)
.subscribe { println("Tick: $it") }

disposables.add(disposable) // Добавляем подписку
}

override fun onDestroy() {
super.onDestroy()
disposables.clear() // Очищаем подписки, предотвращая утечку памяти
}
}


🚩Используем `autoDispose` (для Jetpack Lifecycle)

Если используем Jetpack ViewModel или LifecycleOwner, можно автоматически отвязывать подписки.
class MyFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Observable.interval(1, TimeUnit.SECONDS)
.autoDispose(viewLifecycleOwner) // Автоочистка при `onDestroyView()`
.subscribe { println("Tick: $it") }
}
}


🚩Используем `Disposable.dispose()` вручную

Если подписка не в CompositeDisposable, её можно очистить вручную.
private var disposable: Disposable? = null

fun startObserving() {
disposable = Observable.interval(1, TimeUnit.SECONDS)
.subscribe { println("Tick: $it") }
}

fun stopObserving() {
disposable?.dispose() // Очищаем подписку
}


🚩Используем `ViewModel` + `LiveData` вместо RxJava

RxJava может удерживать Activity/Fragment, вызывая утечки памяти.
Лучше использовать ViewModel + LiveData!
class MyViewModel : ViewModel() {
private val _timer = MutableLiveData<Long>()
val timer: LiveData<Long> = _timer

init {
Observable.interval(1, TimeUnit.SECONDS)
.subscribe { _timer.postValue(it) }
}
}


Подписка в Activity (без утечек!)
viewModel.timer.observe(this) { println("Tick: $it") }


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что такое desugaring?

Desugaring — это процесс, при котором синтаксические "сладости" языка (например, лямбды, методы по умолчанию в интерфейсах) преобразуются в более простой код, понятный старым версиям Java или Android. Это позволяет использовать современные возможности языка даже на устройствах с устаревшей средой выполнения.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 Какие в базовом классе Kotlin есть методы и что они делают?

В Kotlin все классы неявно наследуются от Any (аналог Object в Java).
Это значит, что любой класс в Kotlin имеет 3 базовых метода:

🚩`equals()` – сравнение объектов

По умолчанию сравнивает ссылки (как ===)
class Person(val name: String)

fun main() {
val p1 = Person("Alice")
val p2 = Person("Alice")

println(p1 == p2) // false (разные объекты)
}


Как переопределить equals() для сравнения по значениям?
class Person(val name: String) {
override fun equals(other: Any?): Boolean {
return other is Person && this.name == other.name
}
}

fun main() {
val p1 = Person("Alice")
val p2 = Person("Alice")

println(p1 == p2) // true (теперь сравниваются значения)
}


🚩`hashCode()` – хеш-код объекта

По умолчанию генерируется на основе ссылки
val p = Person("Alice")
println(p.hashCode()) // Разный для каждого объекта


Как переопределить hashCode()?
class Person(val name: String) {
override fun hashCode(): Int {
return name.hashCode() // Генерируем хеш-код на основе имени
}
}


🚩`toString()` – строковое представление объекта

По умолчанию печатает ClassName@hashCode
val p = Person("Alice")
println(p.toString()) // Person@4e25154f (неудобный вывод)


Как сделать красивый вывод?
class Person(val name: String) {
override fun toString(): String {
return "Person(name=$name)"
}
}

val p = Person("Alice")
println(p.toString()) // Person(name=Alice)


🚩Data-классы автоматически переопределяют `equals()`, `hashCode()`, `toString()`

data class User(val name: String)

fun main() {
val u1 = User("Alice")
val u2 = User("Alice")

println(u1 == u2) // true (по значениям)
println(u1.hashCode()) // Одинаковый для объектов с одинаковыми данными
println(u1.toString()) // User(name=Alice)
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1
🤔 Что такое сущность Observable?

Это объект, который может производить данные (события) и передавать их подписчикам (Observer). Он используется для работы с асинхронными потоками данных. Основные возможности:
1. Генерация данных.
2. Обработка данных через операторы.
3. Управление подпиской и отпиской.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
🤔 Почему могут быть проблемы со списками в data class?

В data class могут возникнуть проблемы со списками при использовании:
Методов copy() – список не копируется, а передаётся по ссылке.
Методов equals() и hashCode()List сравнивается по элементам, что может быть медленно.
Mutable списков (MutableList) – изменения внутри списка изменяют все копии объекта.

🚩Проблема `copy()` – список не клонируется

data class User(val name: String, val tags: List<String>)

fun main() {
val original = User("Alice", listOf("Admin", "Editor"))
val copy = original.copy() // Поверхностное копирование

println(original.tags === copy.tags) // true (один и тот же объект)
}


Используем toList(), чтобы создать новый неизменяемый список:
fun main() {
val original = User("Alice", listOf("Admin", "Editor"))
val copy = original.copy(tags = original.tags.toList())

println(original.tags === copy.tags) // false (разные объекты)
}


🚩`equals()` и `hashCode()` могут работать медленно

data class Message(val id: Int, val content: String, val tags: List<String>)

fun main() {
val message1 = Message(1, "Привет", listOf("important", "urgent"))
val message2 = Message(1, "Привет", listOf("important", "urgent"))

println(message1 == message2) // true (сравнивает элементы списка)
}


Если идентификатор (id) уникален, сравнивать только его
data class Message(val id: Int, val content: String, val tags: List<String>) {
override fun equals(other: Any?) = other is Message && this.id == other.id
override fun hashCode() = id.hashCode()
}


🚩`MutableList` в `data class` – неожиданные изменения

data class Task(val name: String, val subtasks: MutableList<String>)

fun main() {
val original = Task("Купить продукты", mutableListOf("Хлеб", "Молоко"))
val copy = original.copy() // Поверхностная копия

copy.subtasks.add("Яйца") // Меняет список в обоих объектах!

println(original.subtasks) // [Хлеб, Молоко, Яйца]
println(copy.subtasks) // [Хлеб, Молоко, Яйца]
}


Создаём новый MutableList внутри copy()
data class Task(val name: String, val subtasks: List<String>) {
fun deepCopy() = Task(name, subtasks.toMutableList())
}

fun main() {
val original = Task("Купить продукты", mutableListOf("Хлеб", "Молоко"))
val copy = original.deepCopy()

copy.subtasks.toMutableList().add("Яйца") // Теперь изменения не влияют на оригинал

println(original.subtasks) // [Хлеб, Молоко]
println(copy.subtasks) // [Хлеб, Молоко, Яйца]
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6💊1
🤔 Что происходит, когда вызывается новое Activity? Освобождается ли память от старого?

Нет, старая Activity:
- Переходит в паузу, затем в onStop().
- Остаётся в стеке задач.
- Может быть уничтожена системой при нехватке памяти.
Если используешь finish() — она будет удалена немедленно.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🤔 Как сказать адаптеру перерисовать список, если какой-то элемент удалился?

Если удалился элемент из списка, нужно:
Удалить его из списка данных.
Сообщить Adapter, чтобы он перерисовал только изменённые элементы.

🚩Используем `notifyItemRemoved()` (лучший вариант)

Этот метод обновляет только удалённый элемент, сохраняя анимации.
fun removeItem(position: Int) {
itemList.removeAt(position) // Удаляем из списка данных
notifyItemRemoved(position) // Сообщаем адаптеру
notifyItemRangeChanged(position, itemList.size) // Обновляем индексы
}


🚩Если изменился весь список – `DiffUtil`

Если изменился несколько элементов, лучше использовать DiffUtil, чтобы обновить только нужные элементы.
class MyAdapter : ListAdapter<Item, MyViewHolder>(DIFF_CALLBACK) {

companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.id == newItem.id
}

override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
}
}
}


Обновляем список через submitList()
fun removeItem(item: Item) {
val newList = currentList.toMutableList()
newList.remove(item)
submitList(newList) // `DiffUtil` сам вычислит, что обновить
}


🚩Полное обновление списка (`notifyDataSetChanged()`)

Использовать только если изменился весь список!
fun removeItem(position: Int) {
itemList.removeAt(position)
notifyDataSetChanged() // Перерисовывает весь список (медленно)
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 API медленно работает, поэтому ваша команда решила сделать prefetch данных. Как это реализовать?

Prefetch — это проактивная загрузка данных до того, как они понадобятся.
Реализация может быть следующей:
- Загрузка на старте экрана: при запуске фрагмента/экрана уже начинать сетевой запрос.
- Фоновая загрузка при idle-состоянии: использовать WorkManager или CoroutineScope для подгрузки ночью, в фоне и т.п.
- RecyclerView prefetch: через RecyclerView.setItemViewCacheSize() и PrefetchingLayoutManager заранее подгружаются карточки.
- Кеширование: сохранить данные в БД или памяти при первом получении, и отображать в UI до завершения запроса.
Цель — снизить видимое пользователю ожидание.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 Расскажи все типы данных в Java/Kotlin?

В Java и Kotlin существуют различные типы данных, которые можно разделить на две основные категории:
Примитивные типы данных (primitive types)
Ссылочные типы данных (reference types)

🚩Типы данных в Java

🟠Ссылочные типы данных (Reference Types)
Ссылочные типы данных указывают на объекты. Они хранятся в куче (heap) и содержат ссылку (адрес) на объект.
Примеры ссылочных типов

🟠Строки (`String`)
String str = "Hello";

🟠Классы и объекты
MyClass obj = new MyClass();

🟠Массивы
int[] arr = {1, 2, 3};

🟠Интерфейсы
List<Integer> list = new ArrayList<>();

🚩Типы данных в Kotlin

В Kotlin типы данных делятся на nullable и non-nullable (значения, которые могут быть null, и те, которые не могут). Kotlin избегает примитивных типов напрямую, но на уровне JVM использует их для оптимизации.

🟠Примитивные типы данных (на уровне JVM)
Kotlin предоставляет высокоуровневые обёртки для примитивных типов. Например:
Int вместо int
Double вместо double

🟠Ссылочные типы данных (Reference Types)
В Kotlin все данные — объекты.
Сюда входят:
Строки (String): val str: String = "Hello"
Коллекции: val list: List<Int> = listOf(1, 2, 3)
Классы: val obj = MyClass()
Nullable-типизация: В Kotlin можно указать, что переменная может быть null. Для этого используется ?.
  val nullableString: String? = null
val nonNullableString: String = "Hello"


Интерфейсы и абстракции: Kotlin поддерживает классы, интерфейсы и их реализации, например
  interface Animal {
fun makeSound()
}

class Dog : Animal {
override fun makeSound() {
println("Woof!")
}
}


🟠Тип Unit и Nothing
Kotlin добавляет уникальные типы, которые отсутствуют в Java:
Unit
Эквивалент void в Java, но является объектом.
Используется, когда функция ничего не возвращает:
  fun printMessage(message: String): Unit {
println(message)
}


Nothing
Представляет значение, которое никогда не будет существовать (например, функция всегда бросает исключение):
  fun fail(message: String): Nothing {
throw IllegalArgumentException(message)
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 В чём разница между функциями коллекций associateWith() и associateBy()?

associateBy создаёт Map, где ключи берутся из заданной логики, а значениями становятся элементы коллекции. associateWith наоборот — элемент становится ключом, а значение задаётся отдельно.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2
🤔 Как бороться с тем что из-за deeplink активити может открыться много раз?

Когда используется deeplink, может возникнуть проблема, что одно и то же Activity может быть открыто несколько раз в стеке задач. Это происходит, если приложение запускается из внешнего источника (например, из браузера или другого приложения), и Android создает новую задачу или новую копию Activity вместо использования уже существующей. Чтобы справиться с этим, нужно правильно настроить launchMode, интенты и флаги.

🚩Причина проблемы

При запуске приложения через deep link, система Android может:
1. Создать новый экземпляр вашего Activity (даже если оно уже существует в стеке задач).
2. Поместить новую задачу в стек задач.
Если это не контролировать, пользователь может увидеть много дубликатов одного и того же Activity, что плохо для UX и может вызвать утечку памяти.

🚩Решения

🟠Использование launchMode в манифесте
В файле AndroidManifest.xml можно настроить поведение Activity с помощью атрибута launchMode:
singleTop: Если Activity уже находится на вершине стека, система не будет создавать новый экземпляр.
singleTask: Убедитесь, что только один экземпляр Activity существует в задаче. Если Activity уже существует, система передаст интент в метод onNewIntent().
singleInstance: Подходит для случаев, когда Activity должно быть абсолютно уникальным (используется редко).
<activity
android:name=".MyActivity"
android:launchMode="singleTop" />


🟠Использование флагов в интенте
Если вы используете deep link или запускаете Activity вручную, можно добавить флаги, чтобы управлять созданием экземпляров:

   val intent = Intent(this, MyActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
startActivity(intent)


🟠Обработка метода onNewIntent()
Если используется singleTop или singleTask, система вызывает метод onNewIntent(Intent intent) вместо создания нового экземпляра Activity. Этот метод можно переопределить для обработки новых данных из интента

   override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Обработка нового интента
val data = intent?.data
// Используйте данные deeplink
}


🟠Использование taskAffinity
Если требуется, чтобы разные deep link открывали одну и ту же задачу, можно настроить taskAffinity. Это нужно реже, но полезно, если нужно обрабатывать ссылки с разными контекстами.

🟠Проверка состояния Activity
Дополнительно можно вручную проверять, существует ли нужное Activity в текущем состоянии приложения, например, используя LiveData или ViewModel.

Файл AndroidManifest.xml
<activity
android:name=".MyActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="example.com"
android:path="/deeplink" />
</intent-filter>
</activity>


Файл MyActivity.kt
class MyActivity : AppCompatActivity() {

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Обработка данных из нового интента (deeplink)
val uri = intent?.data
uri?.let {
// Например, получить параметры из ссылки
val param = it.getQueryParameter("id")
Log.d("Deeplink", "Parameter id: $param")
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
🤔 Для чего data-классы и sealed-классы используются?

- data class — для хранения и работы с данными, удобны при копировании, логическом сравнении, сериализации.
- sealed class — для ограниченного набора подтипов. Удобны при использовании when, так как все случаи должны быть обработаны — это повышает безопасность и читаемость.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 Что используешь, если нужно получить элемент или список элементов?

В Kotlin есть множество удобных функций для получения одного элемента или списка элементов из коллекций (List, Set, Map). Какую функцию использовать — зависит от задачи.

🚩Получение одного элемента

🟠`get(index)` и `getOrNull(index)`
получение по индексу
Если индекс может выйти за границы массива, лучше использовать getOrNull().
val list = listOf("A", "B", "C")

println(list[1]) // "B"
println(list.getOrNull(5)) // null


🟠`first()` и `last()`
первый и последний элементы
println(list.first())  // "A"
println(list.last()) // "C"

Используйте firstOrNull() или lastOrNull(), если список может быть пустым
println(emptyList<String>().firstOrNull())  // null


🟠`find {}` и `findLast {}`
поиск по условию Возвращает первый или последний элемент, удовлетворяющий условию.
val numbers = listOf(10, 20, 30, 40)

println(numbers.find { it > 15 }) // 20
println(numbers.findLast { it > 15 }) // 40
println(numbers.find { it > 50 }) // null


🟠`single()` и `singleOrNull()`
если ожидается только один элемент
val oneElementList = listOf(42)
println(oneElementList.single()) // 42
println(oneElementList.singleOrNull()) // 42

val emptyList = emptyList<Int>()
println(emptyList.singleOrNull()) // null

single() бросает исключение, если элементов нет или их больше одного.

🚩Получение нескольких элементов (списка)

filter {} – фильтрация элементов по условию
val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // [2, 4]


take(n) и takeLast(n) – первые/последние n элементов
val items = listOf("a", "b", "c", "d", "e")

println(items.take(3)) // [a, b, c]
println(items.takeLast(2)) // [d, e]


slice(indices) – получение элементов по индексам
val sliced = items.slice(listOf(0, 2, 4))
println(sliced) // [a, c, e]


map {} – преобразование списка
val squared = numbers.map { it * it }
println(squared) // [1, 4, 9, 16, 25]


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💊1
🤔 Что означает в Android-разработке подход Single Activity?

Подход Single Activity в Android-разработке предполагает использование одной активности (Activity) как контейнера для всего пользовательского интерфейса приложения, при этом различные части интерфейса реализуются через фрагменты. Этот подход позволяет упростить управление состоянием UI, улучшить производительность и облегчить навигацию по приложению, так как необходимо управлять только одним стеком активностей.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
🤔 Можно ли после by вызвать функцию или конструктор?

Нет, после by нельзя вызывать функции или конструкторы. by ожидает готовый объект, который реализует интерфейс или делегирует свойство.

🚩Что такое `by`?

В Kotlin by используется в двух случаях:
Делегирование интерфейсов (class A : Interface by obj)
Делегирование свойств (val x by lazy {})
Но by не может вызывать функции или конструкторы – ему нужен уже созданный объект.

🟠`by` и делегирование интерфейсов
Правильный код (делегируем готовый объект)
interface Printer {
fun printMessage()
}

class RealPrinter : Printer {
override fun printMessage() = println("Печать...")
}

// Делегируем готовый объект `RealPrinter()`
class MyClass : Printer by RealPrinter()

fun main() {
MyClass().printMessage() // Печать...
}


Ошибка, если после by вызвать конструктор
class MyClass : Printer by RealPrinter() //  Работает
class MyClass2 : Printer by RealPrinter() { } // Ошибка!


🟠`by` и делегирование свойств
Правильный код (by lazy)
val message: String by lazy { "Привет, мир!" }
println(message) // Привет, мир!


Ошибка, если после by вызвать функцию
val message: String by getMessage() //  Ошибка!

fun getMessage() = "Привет, мир!"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊8👍2
🤔 Как сравниваются объекты в Java?

- По умолчанию через == — сравнение ссылок (адресов).
- Через .equals() — логическое сравнение содержимого.
- При переопределении .equals() рекомендуется также переопределить .hashCode().


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1💊1
🤔 От какого объекта наследуются все классы в Java?

В Java все классы неявно наследуются от класса Object, если явно не указано другое наследование.
class MyClass {
// Неявно наследуется от Object
}

class MyClass2 extends Object {
// То же самое, просто указано явно
}


🚩Методы, унаследованные от `Object`

Класс Object содержит основные методы, доступные во всех классах:
class Person {
String name;

Person(String name) {
this.name = name;
}

@Override
public String toString() {
return "Person{name='" + name + "'}";
}
}

public class Main {
public static void main(String[] args) {
Person p = new Person("Alice");

System.out.println(p.toString()); // Person{name='Alice'}
System.out.println(p.hashCode()); // Хеш-код объекта
System.out.println(p.getClass()); // class Person
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Как программно запретить создание объекта класса?

- Сделать приватный конструктор, чтобы запретить внешнее создание объекта.
- Используется в паттерне Singleton или Utility-классах (например, Math).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1💊1