Это объекты в памяти, которые:
1. Больше не используются.
2. Недостижимы из корневых объектов (root references). Сборщик мусора освобождает эти объекты, чтобы уменьшить использование памяти.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
ArrayList реализован на основе массива. Амортизированное O(1). Если массив не заполнен, элемент добавляется в конец списка. В случае, если массив заполнен, требуется выделение нового массива и копирование элементов, что занимает O(n) времени.
val arrayList = ArrayList<Int>()
arrayList.add(1) // Быстрая вставка в конец
O(n). Необходимо сдвинуть все элементы, начиная с позиции вставки, чтобы освободить место для нового элемента. Это требует времени, пропорционального количеству элементов после позиции вставки.
arrayList.add(0, 2) // Медленная вставка в начало
arrayList.add(1, 3) // Медленная вставка в середину
LinkedList реализован на основе узлов, где каждый узел содержит ссылку на следующий и/или предыдущий узел (в случае двусвязного списка).val linkedList = LinkedList<Int>()
linkedList.addFirst(1) // Быстрая вставка в начало
O(1) (если есть ссылка на последний узел) или O(n) (если необходимо пройти весь список). Если список двусвязный и хранится ссылка на последний элемент, вставка в конец осуществляется за O(1). В противном случае, требуется пройти весь список до конца.
linkedList.addLast(2) // Быстрая вставка в конец, если есть ссылка на последний узел
O(n). Необходимо пройти список до нужной позиции и изменить ссылки узлов.
linkedList.add(1, 3) // Медленная вставка в середину
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
В Android при нажатии пользователя на экран вызывается событие ACTION_DOWN.
Android использует систему обработки касаний через MotionEvent. Когда пользователь касается экрана, система генерирует разные типы событий:
ACTION_DOWN – вызывается в момент первого касания.
ACTION_MOVE – вызывается, когда пользователь двигает палец по экрану.
ACTION_UP – вызывается, когда пользователь убирает палец с экрана.
ACTION_CANCEL – вызывается, если система прерывает касание (например, из-за входящего звонка).
Для обработки событий касания нужно переопределить метод
onTouchEvent() в View или использовать setOnTouchListener(). override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("TouchEvent", "Палец коснулся экрана")
return true
}
MotionEvent.ACTION_UP -> {
Log.d("TouchEvent", "Палец отпущен")
}
}
return super.onTouchEvent(event)
}Можно также назначить слушатель
view.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
Log.d("TouchEvent", "Нажатие зафиксировано")
true
} else {
false
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Данные из разных источников нужно объединить, преобразовать в единый формат и отфильтровать, чтобы привести их к структуре, удобной для отображения. Например, если данные о продуктах поступают из API и локальной базы данных, их нужно объединить, исключить дублирующиеся записи и сохранить в state. Это делается для обеспечения консистентности и удобства использования в UI.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
В Kotlin инициализаторы используются для выполнения кода при создании экземпляра класса.
Первичный (primary) конструктор
Вторичные (secondary) конструкторы
Инициализационный блок (
init) Это основной способ инициализации класса в Kotlin. Он объявляется в заголовке класса.
class User(val name: String, val age: Int)
Если нужно выполнить дополнительную логику во время создания объекта, используют блок
init: class User(val name: String, val age: Int) {
init {
println("Создан пользователь: $name, возраст: $age")
}
}Они объявляются с помощью
constructor и нужны, если:Нужно несколько способов создания объекта.
Надо вызвать другой конструктор (
this(...)). class User {
var name: String
var age: Int
constructor(name: String) {
this.name = name
this.age = 18 // Значение по умолчанию
}
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
}Можно создать объект так
val user1 = User("Алекс") // возраст будет 18
val user2 = User("Иван", 25) Если есть первичный конструктор, вторичный должен его вызывать через
this(...)class User(val name: String, val age: Int) {
constructor(name: String) : this(name, 18)
}init выполняется всегда при вызове первичного конструктора. Вторичный конструктор создаёт альтернативный способ создания объекта.
class User(val name: String, val age: Int) {
init {
println("Создан пользователь: $name, возраст: $age")
}
constructor(name: String) : this(name, 18) {
println("Вызван вторичный конструктор")
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Да, Android Framework активно использует паттерн Factory в различных API. Один из самых известных примеров —
LayoutInflater. В Android для создания (инстанцирования) UI-компонентов из XML используется
LayoutInflater, который реализует паттерн Factory Method. Вместо того чтобы вручную создавать объекты View, система предоставляет фабричный метод inflate(), который "производит" экземпляры View. В XML описан интерфейс.
LayoutInflater загружает XML и создает соответствующие объекты View.Это абстрагирует создание UI-компонентов от разработчика.
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.custom_layout, parent, false)
Вместо
MediaPlayer() напрямую используется MediaPlayer.create(context, R.raw.sound), который автоматически создаёт и настраивает объект.Позволяет получить
SharedPreferences без необходимости вручную создавать экземпляр.Фабричный метод для создания
Fragment без явного вызова конструктора.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Для отображения Toast можно использовать Toast.makeText(context, "Message", LENGTH).show(), а для Snackbar – Snackbar.make(view, "Message", LENGTH).show(). Toast чаще используется для кратких уведомлений, а Snackbar – для сообщений с действиями, например, кнопкой "Отменить". Snackbar также требует привязки к определённому view.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥4
При пересоздании
Activity (например, при повороте экрана) состояние ScrollView или RecyclerView сбрасывается. Чтобы этого избежать, можно сохранить и восстановить позицию скролла. Android позволяет сохранять данные в
Bundle перед уничтожением Activity, а затем восстанавливать их. class MainActivity : AppCompatActivity() {
private lateinit var scrollView: ScrollView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
scrollView = findViewById(R.id.scrollView)
// Восстанавливаем позицию скролла
savedInstanceState?.let {
val scrollY = it.getInt("scroll_position", 0)
scrollView.post { scrollView.scrollTo(0, scrollY) }
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("scroll_position", scrollView.scrollY)
}
}У
RecyclerView уже есть встроенный механизм сохранения состояния через LinearLayoutManager. class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var layoutManager: LinearLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
layoutManager = LinearLayoutManager(this)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = MyAdapter()
// Восстанавливаем позицию скролла
savedInstanceState?.let {
val scrollPosition = it.getInt("recycler_position", 0)
recyclerView.post { layoutManager.scrollToPosition(scrollPosition) }
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("recycler_position", layoutManager.findFirstVisibleItemPosition())
}
}Если
EditText находится внутри ScrollView, можно включить android:freezesText="true", чтобы автоматически сохранять данные. <EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:freezesText="true"/>
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3🤔3
Map – это коллекция пар ключ-значение. Каждый ключ уникален, а значения могут повторяться. В Kotlin Map не наследуется от Collection, но является частью стандартных коллекций.В Kotlin есть два основных типа
Map: Map (неизменяемая) – нельзя добавлять/удалять элементы после создания. MutableMap (изменяемая) – можно добавлять, удалять и изменять элементы. Создаётся с помощью
mapOf()val users = mapOf(1 to "Alice", 2 to "Bob", 3 to "Charlie")
println(users[1]) // Выведет: Alice
Создаётся с помощью
mutableMapOf()val users = mutableMapOf(1 to "Alice", 2 to "Bob")
users[3] = "Charlie" // Добавляем элемент
users[1] = "Alex" // Изменяем значение по ключу
users.remove(2) // Удаляем элемент
println(users) // {1=Alex, 3=Charlie}
map[key] – получить значение (или null, если ключа нет). map.getValue(key) – получить значение (или исключение, если ключа нет). map.getOrDefault(key, defaultValue) – вернуть значение или defaultValue, если ключа нет. map.getOrElse(key) { default } – если ключа нет, выполнить лямбда-выражение. val users = mapOf(1 to "Alice", 2 to "Bob")
println(users[1]) // Alice
println(users.getOrDefault(3, "Unknown")) // Unknown
map.containsKey(key) – есть ли ключ? map.containsValue(value) – есть ли значение? println(users.containsKey(2)) // true
println(users.containsValue("Charlie")) // false
Перебор элементов
for ((key, value) in users) {
println("ID: $key, Name: $value")
}Фильтрация
Mapval filtered = users.filter { (key, value) -> key % 2 == 0 }
println(filtered) // {2=Bob}mapOf() – не гарантирует порядок. linkedMapOf() – сохраняет порядок добавления. Обычный
HashMap (mutableMapOf()) – O(1) для поиска по ключу. TreeMap – O(log n), но поддерживает сортировку по ключам. val sortedUsers = sortedMapOf(3 to "Charlie", 1 to "Alice", 2 to "Bob")
println(sortedUsers) // {1=Alice, 2=Bob, 3=Charlie}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
В Kotlin для работы с многопоточностью можно использовать
atomic переменные или synchronized блоки. Они помогают избежать гонок данных (race conditions), когда несколько потоков одновременно изменяют одну и ту же переменную. Atomic переменные (AtomicInteger, AtomicLong, AtomicReference и др.) используются, когда нужно быстро и безопасно обновлять одно значение без блокировки потока. Высокая производительность – атомарные операции работают быстрее, чем
synchronized. Потокобезопасность – операции выполняются без блокировок (lock-free).
Удобство – простые методы
incrementAndGet(), compareAndSet() и т. д. Работает только с одним значением – не подходит для сложных операций.
Не подходит для зависимых изменений (например, если изменение одной переменной зависит от другой).
import java.util.concurrent.atomic.AtomicInteger
val counter = AtomicInteger(0)
fun increment() {
counter.incrementAndGet() // Увеличиваем значение безопасно
}
Используется, когда нужно защитить сразу несколько связанных операций от одновременного выполнения в нескольких потоках.
Подходит для сложных операций с несколькими переменными.
Работает с любыми типами данных.
Снижает производительность – потоки ждут, пока один поток закончит работу.
Может вызывать deadlock (взаимную блокировку).
val lock = Any()
var count = 0
fun increment() {
synchronized(lock) {
count++ // Только один поток может изменять `count` одновременно
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤯1🎉1
Это небольшое окно для взаимодействия с пользователем (например, подтверждение действия), которое закрывается после выполнения задачи. Фрагмент – это независимый компонент интерфейса, который может содержать сложные элементы и использоваться для создания динамических экранов, заменяя их в активности.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
В Kotlin есть множество удобных функций для получения одного элемента или списка элементов из коллекций (
List, Set, Map). Какую функцию использовать — зависит от задачи. получение по индексу
Если индекс может выйти за границы массива, лучше использовать
getOrNull(). val list = listOf("A", "B", "C")
println(list[1]) // "B"
println(list.getOrNull(5)) // nullпервый и последний элементы
println(list.first()) // "A"
println(list.last()) // "C"
Используйте
firstOrNull() или lastOrNull(), если список может быть пустымprintln(emptyList<String>().firstOrNull()) // null
поиск по условию Возвращает первый или последний элемент, удовлетворяющий условию.
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
если ожидается только один элемент
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
Forwarded from easyoffer
💡 В EasyOffer 2.0 появится фильтрация вопросов по грейдам и типам интервью!
📊 Например, вот вероятности ТОП-30 вопросов, которые задают на HR-скрининге Python-разработчику уровня Middle/Senior. Данные основаны на 53 реальных интервью.
97% Какие у тебя зарплатные ожидания
73% Какие у тебя есть вопросы
44% Какие критерии при выборе будущей работы
41% Расскажи о себе
38% Почему ищешь работу
35% Расскажи про свой опыт
35% Расскажи про проект на предыдущей работе
32% Почему уволился с предыдущей работы
29% Где территориально сейчас живешь/находишься
23% Есть ли другие предложения по работе
17% Есть ли военный билет
17% Почему хочешь сменить работу
17% Как проводишь свободное время
17% Расскажи про задачи на предыдущей работе
17% Сколько коммерческого опыта работы с Python
17% С какими БД работал
14% Находишься ли в активном поиске работы
14% С каким стеком работаешь
14% Почему решил откликнуться на нашу вакансию
14% Какой текущий статус поиска работы
11% Почему решил стать программистом
11% С какими фреймворками работал
11% Какую зарплату получал на предыдущей работе
11% Работаешь ли в настоящий момент
11% На какой грейд себя оцениваешь
11% Как быстро можешь приступить к работе после получения офера
11% Расскажи про свои pet-проекты
8% Какие знаешь типы данных в Python
8% Что такое декоратор в Python
8% Что ищешь на новой работе
🚀 Скоро стартует краудфандинговая кампания, которая поможет ускорить разработку EasyOffer 2.0.
Первые спонсоры получат уникальные лимитированные награды!
📢 Если вам это интересно, подписывайтесь на канал 👉 этот телеграм канал
📊 Например, вот вероятности ТОП-30 вопросов, которые задают на HR-скрининге Python-разработчику уровня Middle/Senior. Данные основаны на 53 реальных интервью.
97% Какие у тебя зарплатные ожидания
73% Какие у тебя есть вопросы
44% Какие критерии при выборе будущей работы
41% Расскажи о себе
38% Почему ищешь работу
35% Расскажи про свой опыт
35% Расскажи про проект на предыдущей работе
32% Почему уволился с предыдущей работы
29% Где территориально сейчас живешь/находишься
23% Есть ли другие предложения по работе
17% Есть ли военный билет
17% Почему хочешь сменить работу
17% Как проводишь свободное время
17% Расскажи про задачи на предыдущей работе
17% Сколько коммерческого опыта работы с Python
17% С какими БД работал
14% Находишься ли в активном поиске работы
14% С каким стеком работаешь
14% Почему решил откликнуться на нашу вакансию
14% Какой текущий статус поиска работы
11% Почему решил стать программистом
11% С какими фреймворками работал
11% Какую зарплату получал на предыдущей работе
11% Работаешь ли в настоящий момент
11% На какой грейд себя оцениваешь
11% Как быстро можешь приступить к работе после получения офера
11% Расскажи про свои pet-проекты
8% Какие знаешь типы данных в Python
8% Что такое декоратор в Python
8% Что ищешь на новой работе
🚀 Скоро стартует краудфандинговая кампания, которая поможет ускорить разработку EasyOffer 2.0.
Первые спонсоры получат уникальные лимитированные награды!
📢 Если вам это интересно, подписывайтесь на канал 👉 этот телеграм канал
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Методы
equals() и hashCode() используются для сравнения объектов и их корректной работы в коллекциях (Set, Map). Метод
equals() должен:Рефлексивность:
a.equals(a) → true (объект равен самому себе). Симметричность:
a.equals(b) == b.equals(a). Транзитивность: если
a == b и b == c, то a == c. Согласованность: если
a == b, то a.equals(b) всегда возвращает одно и то же, пока объект не изменится. Сравнение с
null всегда даёт false: a.equals(null) == false. class User(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true // Проверка на ссылочное равенство
if (other !is User) return false // Проверка типа
return name == other.name && age == other.age // Сравнение полей
}
}val user1 = User("Alice", 25)
val user2 = User("Alice", 25)
println(user1 == user2) // true (потому что переопределён equals)Метод
hashCode() должен:Согласованность с
equals(): если a == b, то a.hashCode() == b.hashCode(). Но обратное не обязательно: два разных объекта могут иметь одинаковый
hashCode(). Хеш-код не должен меняться, если объект не изменился.
class User(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is User) return false
return name == other.name && age == other.age
}
override fun hashCode(): Int {
return name.hashCode() * 31 + age // 31 - стандартный коэффициент
}
}val userSet = HashSet<User>()
userSet.add(User("Alice", 25))
println(userSet.contains(User("Alice", 25))) // true
Чтобы не писать
equals() и hashCode() вручную, можно использовать data class: data class User(val name: String, val age: Int)
data class автоматически создаёт equals(), hashCode(), а также copy() и toString(). val user1 = User("Alice", 25)
val user2 = User("Alice", 25)
println(user1 == user2) // true (equals)
println(user1.hashCode() == user2.hashCode()) // trueСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1