Kotlin | Вопросы собесов
2.56K subscribers
30 photos
970 links
Download Telegram
🤔 Расскажи для чего нужен Dagger?

Dagger — это библиотека для внедрения зависимостей, упрощающая создание, управление и тестирование объектов. Она генерирует код для автоматического предоставления зависимостей, что делает приложение модульным и устойчивым к изменениям.

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

Основные компоненты Android-приложения:
Activity – экран пользовательского интерфейса.
Fragment – часть UI внутри Activity.
Service – выполняет фоновые задачи.
BroadcastReceiver – реагирует на системные события.
ContentProvider – управляет доступом к данным между приложениями.

🚩`Context` – доступ к ресурсам и системным сервисам

Все компоненты наследуют Context или получают его через getContext().
- Activity и Service наследуют Context.
- Fragment, BroadcastReceiver и ContentProvider получают Context через getContext().
fun showToast(context: Context) {
Toast.makeText(context, "Привет!", Toast.LENGTH_SHORT).show()
}


🚩`AndroidManifest.xml` – регистрация компонентов

Все компоненты объявляются в AndroidManifest.xml, чтобы система знала о них.
<manifest>
<application>
<activity android:name=".MainActivity"/>
<service android:name=".MyService"/>
<receiver android:name=".MyReceiver"/>
<provider android:name=".MyContentProvider"/>
</application>
</manifest>


🚩`Intent` – механизм взаимодействия компонентов

Все компоненты могут общаться друг с другом через Intent. Пример: Запуск `Activity` из `Service` через `Intent`
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3👍2
🤔 Что такое Task и где это используется?

Task в Android — это стек активити, связанных логически (обычно из одного приложения).
- Управляется системой.
- Пример: пользователь от крывает ссылку → новая Task (браузер), возвращается назад — старая Task восстанавливается.
Можно управлять Task через Intent-флаги, affinity, launchMode.


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

Передача больших данных (например, изображений, видео, JSON) между Activity требует оптимального подхода, потому что:
Intent.putExtra() имеет ограничение по размеру (~1MB).
Передача Bitmap в Intent может вызвать TransactionTooLargeException.
Большие данные лучше передавать через Uri, БД или FileProvider.

Неправильный способ (НЕ ДЕЛАТЬ!) – Bitmap через Intent
val bitmap: Bitmap = getBitmap()
val intent = Intent(this, ImageActivity::class.java)
intent.putExtra("image", bitmap) // ОПАСНО! Может вызвать Exception
startActivity(intent)


🚩Лучший способ – передача через `Uri` (`FileProvider`)

Сохраняем изображение во File и получаем Uri
fun saveBitmapToFile(context: Context, bitmap: Bitmap): Uri {
val file = File(context.cacheDir, "image.png")
file.outputStream().use {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
}
return FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
}


Передаём Uri через Intent
val uri = saveBitmapToFile(this, bitmap)
val intent = Intent(this, ImageActivity::class.java).apply {
putExtra("image_uri", uri.toString())
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // Даем доступ другому Activity
}
startActivity(intent)


Получаем Uri в ImageActivity и загружаем изображение
val uriString = intent.getStringExtra("image_uri")
val uri = Uri.parse(uriString)

val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(uri))
imageView.setImageBitmap(bitmap)


🚩Альтернативный способ – через Базу Данных (`Room`)

Если изображение уже хранится в базе данных (Room), передаём ID записи, а не сам файл.
val intent = Intent(this, ImageActivity::class.java)
intent.putExtra("image_id", imageId) // Передаём только ID
startActivity(intent)


🚩Альтернативный способ – через `SharedPreferences` (только путь к файлу!)
Сохраняем путь
val filePath = saveBitmapToFile(this, bitmap).toString()
getSharedPreferences("app_prefs", MODE_PRIVATE).edit()
.putString("last_image", filePath)
.apply()


Читаем путь в Activity
val filePath = getSharedPreferences("app_prefs", MODE_PRIVATE)
.getString("last_image", null)
val bitmap = BitmapFactory.decodeFile(filePath)
imageView.setImageBitmap(bitmap)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊1
Forwarded from easyoffer
📅 Осталось 7 дней до конца краудфандинга

Мы на финишной прямой!

Если ты планировал присоединиться, но ещё не успел, сейчас идеальный момент.

Вознаграждения за поддержку:

🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу.
Приглашение на закрытое бета-тестирование

👉 Поддержать easyoffer 2.0

Не откладывай на последний момент

📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
👍1
🤔 Зачем нужны Intents?

Intents нужны для взаимодействия компонентов приложения: запуска Activity, Service, передачи данных или отправки Broadcast. Они являются основным способом коммуникации между модулями и приложениями в Android.


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

Модификаторы доступа (Access Modifiers) — это ключевые слова, которые определяют, кто может видеть и использовать класс, переменную или метод.
Они помогают инкапсулировать данные и защищать код от неправильного использования.

🚩Модификаторы доступа в Java

Пример Java
public class Example {
private int a = 10; // Только внутри класса
int b = 20; // Видно внутри пакета (package-private)
protected int c = 30; // Видно в пакете и наследниках
public int d = 40; // Доступно везде
}


🚩Модификаторы доступа в Kotlin

В Kotlin есть почти такие же модификаторы, но package-private заменён на internal.
Пример Kotlin
class Example {
private val a = 10 // Только в этом классе
internal val b = 20 // Видно в модуле
protected val c = 30 // Видно в наследниках
public val d = 40 // Видно везде (по умолчанию)
}


🚩Где используются модификаторы доступа?

Для полей (переменных класса)
public class User {
private String name; // Скрыто от других классов

public User(String name) {
this.name = name;
}

public String getName() { // Доступ через метод
return name;
}
}


Для методов
class Animal {
protected void makeSound() { // Доступен только в наследниках
System.out.println("Животное издаёт звук");
}
}
class Dog extends Animal {
public void bark() {
makeSound(); // Разрешено, потому что `protected`
System.out.println("Гав-гав!");
}
}


Для классов
public class Car { } //  Доступен везде
class Engine { } // Только в этом пакете


В Kotlin можно делать private class, но только внутри другого класса.
class Car {
private class Engine // Только в этом классе
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Стратегии бранчинга. Их плюсы и минусы.

1. Git Flow: отлично подходит для сложных проектов с чётким управлением версиями, но может быть избыточен для небольших проектов.
2. Feature Branching: позволяет изолировать работу над фичами, упрощая код-ревью, но усложняет синхронизацию.
3. Trunk-Based Development: быстрый и простой подход, особенно для Agile-команд, но может создавать конфликты из-за частого коммита в основную ветку.


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

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

🚩Причины пропадания данных при повороте экрана

🟠Пересоздание активности
🟠Неправильное управление состоянием

🚩Способы предотвращения потери данных

Сохранение состояния с помощью onSaveInstanceState и onRestoreInstanceState
class MainActivity : AppCompatActivity() {

private var userData: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

if (savedInstanceState != null) {
userData = savedInstanceState.getString("USER_DATA_KEY")
// Восстановите данные в пользовательском интерфейсе
}
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("USER_DATA_KEY", userData)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
userData = savedInstanceState.getString("USER_DATA_KEY")
// Восстановите данные в пользовательском интерфейсе
}
}


Использование Retain Fragment. Этот метод сохраняет данные, используя фрагмент, который сохраняет своё состояние при пересоздании активности.
class RetainFragment : Fragment() {
var userData: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
}
}

class MainActivity : AppCompatActivity() {

private lateinit var retainFragment: RetainFragment

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val fragmentManager = supportFragmentManager
retainFragment = fragmentManager.findFragmentByTag("RETAIN_FRAGMENT") as RetainFragment?
?: RetainFragment().also {
fragmentManager.beginTransaction().add(it, "RETAIN_FRAGMENT").commit()
}

// Используйте данные из RetainFragment
val userData = retainFragment.userData
}
}


Использование SavedStateHandle в ViewModel
class UserViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
var userData: String?
get() = savedStateHandle.get("USER_DATA_KEY")
set(value) = savedStateHandle.set("USER_DATA_KEY", value)
}

class MainActivity : AppCompatActivity() {

private lateinit var viewModel: UserViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(UserViewModel::class.java)

// Используйте данные из ViewModel
val userData = viewModel.userData
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Как в Jetpack Compose создать список, аналогичный RecyclerView?

Используется LazyColumn или LazyRow. Они создают и отображают элементы по мере необходимости, экономя ресурсы и обеспечивая плавную прокрутку.


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

XML — это eXtensible Markup Language (Расширяемый язык разметки).

🚩Что означает расшифровка?

eXtensible → Расширяемый (можно создавать свои теги).
Markup → Разметка (использует теги <tag> для структурирования данных).
Language → Язык (формат хранения и передачи данных).

🚩Где используется XML?

В Android:
Разметка UI (activity_main.xml).
Конфигурация (AndroidManifest.xml).
Ресурсы (strings.xml, colors.xml).

В веб-разработке:
Конфигурации (.xml файлы в серверных приложениях).
Форматы обмена данными (SOAP, RSS, SVG).

Пример XML-кода
<user>
<name>Алиса</name>
<age>25</age>
</user>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Forwarded from easyoffer
Офигеть, вот это поддержка! 🔥

Скажу честно: когда я планировал запуск краудфандинговой кампании, в голове были разные варианты развития событий. Думал — ну, наверное, получится собрать 300 тысяч. В самом идеальном сценарии — может быть, миллион.

Но больше всего я боялся, что запущу кампанию, и не получится собрать даже 300 т. Это был бы провал. Так много усилий, времени и денег вложено в проект… и если бы всё закончилось ничем — это бы сильно демотивировало.

Но, ребята, мы превысили изначальную цель в 10 раз —
3 031 040 рублей! 🤯

Вся эта кампания — это одна большая проверка бизнес-модели на прочность. И я супер рад, что запустил всё публично. Люди видят, что EasyOffer реально нужен. Теперь нет сомнений — проект актуален, он будет прибыльным и будет развиваться.

Мне приходит огромное количество сообщений в личку: кто-то когда-то давно пользовался сайтом, он помог с трудоустройством, и сейчас они уже не ищут работу — но всё равно поддержали.
Это прям очень круто и трогательно.

Никак не могу отделаться от мысли, что easyoffer — это ведь мой первый сайт. Учебный, пет-проект, просто для портфолио. И вот что из него вышло. Просто офигеть.

Я не зря ушёл с работы, чтобы заниматься только им.
Я поверил в этот проект — и сейчас вижу, что вы тоже в него верите. Для меня это очень многое значит.

Огромное спасибо за вашу поддержку! ❤️
🤔 Почему запрещено множественное наследование и как этот запрет обойти?

В Java множественное наследование классов запрещено из-за проблемы "алмаза" (двусмысленность при унаследованных методах с одинаковым именем из разных суперклассов).
Решение:
- Использование интерфейсов — Java поддерживает множественную реализацию интерфейсов.
- Использование композиции — включение нужного объекта как поля.


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

В Android существует несколько способов запуска асинхронных операций. Наиболее распространённые из них включают использование AsyncTask (хотя он уже устарел), HandlerThread, AsyncTaskLoader, ExecutorService и современные подходы с использованием Kotlin Coroutines и библиотеки WorkManager.

🟠AsyncTask (устаревший)
AsyncTask был одним из первых инструментов для выполнения асинхронных задач, однако его использование сейчас не рекомендуется из-за проблем с управлением жизненным циклом и утечками памяти.
private class MyAsyncTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... voids) {
// Выполнение длительной операции
return "Result";
}

@Override
protected void onPostExecute(String result) {
// Обновление UI после завершения операции
}
}

// Запуск
new MyAsyncTask().execute();


🟠HandlerThread
HandlerThread — это удобный способ создания фонового потока с циклом обработки сообщений.
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());

handler.post(new Runnable() {
@Override
public void run() {
// Выполнение длительной операции
}
});


🟠ExecutorService
ExecutorService из стандартной библиотеки Java предоставляет более гибкий способ управления потоками.
ExecutorService executor = Executors.newSingleThreadExecutor();

executor.submit(new Runnable() {
@Override
public void run() {
// Выполнение длительной операции
}
});


🟠Kotlin Coroutines
Корутины в Kotlin — это современный и мощный инструмент для асинхронного программирования. Они упрощают работу с асинхронными задачами и обеспечивают безопасность работы с UI.
import kotlinx.coroutines.*

fun performAsyncTask() {
GlobalScope.launch(Dispatchers.IO) {
// Выполнение длительной операции
val result = longRunningTask()

withContext(Dispatchers.Main) {
// Обновление UI после завершения операции
}
}
}

suspend fun longRunningTask(): String {
delay(1000) // Симуляция длительной операции
return "Result"
}


🟠WorkManager
WorkManager — это библиотека для выполнения фоновых задач, которая обеспечивает выполнение задач даже после закрытия приложения или перезагрузки устройства.
public class MyWorker extends Worker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}

@NonNull
@Override
public Result doWork() {
// Выполнение длительной операции
return Result.success();
}
}

// Запуск Worker
WorkManager workManager = WorkManager.getInstance(context);
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(MyWorker.class).build();
workManager.enqueue(request);


🟠RxJava
RxJava — это библиотека для реактивного программирования, которая также может быть использована для выполнения асинхронных задач.
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.schedulers.Schedulers;

Observable.fromCallable(() -> {
// Выполнение длительной операции
return "Result";
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
// Обновление UI после завершения операции
});


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1💊1
Forwarded from easyoffer
Осталось 3 дня!

Финальный отсчёт пошёл — осталось всего 3 дня до окончания краудфандинга easyoffer 2.0

Сейчас можно получить максимум пользы за минимальные деньги. После окончания кампании цены вырастут и вознаграждения станут недоступны.

👉 Поддержи easyoffer 2.0 и получи:

🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. Приглашение на закрытое бета-тестирование

Поддержи проект сейчас, чтобы не забыть!

📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
🤔 В чем разница между coroutineScope и supervisorScope?

Оба создают новый scope, но различие в обработке ошибок:
- coroutineScope {} – если одна дочерняя корутина упадет, отменяются все остальные.
- supervisorScope {} – если одна корутина упадет, остальные продолжают работу.


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

Это компонент приложения, который предоставляет пользовательский интерфейс (UI), с которым пользователи могут взаимодействовать для выполнения различных действий, таких как набор номера телефона, просмотр фотографий, отправка электронной почты и т. д. Каждая активность представляет собой один экран с пользовательским интерфейсом. Если представить приложение как книгу, то активность будет одной страницей этой книги.

🚩Основное назначение

🟠Предоставление интерфейса пользователя
Основная задача — предоставить макет (layout), который будет содержать все элементы пользовательского интерфейса, такие как кнопки, текстовые поля, изображения и прочее, с которыми пользователь может взаимодействовать.

🟠Взаимодействие с пользователем
Служит в качестве "лица" приложения для взаимодействия с пользователем, обрабатывая пользовательские входные данные, такие как нажатие кнопок, ввод текста и т. д.

🟠Управление жизненным циклом
Android управляет активностями через заданный жизненный цикл, который определяет, как активность создается, запускается, останавливается и уничтожается. Разработчики могут переопределять методы жизненного цикла, чтобы добавить свою логику обработки для разных состояний активности.

🟠Переход между экранами
В приложении обычно есть несколько активностей, и он используется для перехода от одного экрана к другому. Для перехода между активностями используются интенты (Intents), которые не только помогают открыть новую активность, но и могут передавать данные между активностями.

🟠Взаимодействие с другими компонентами приложения
М
ожет взаимодействовать с другими компонентами приложения, такими как Services, BroadcastReceivers, и ContentProviders, используя интенты и другие механизмы Android для межкомпонентного взаимодействия.

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔1
Forwarded from easyoffer
Завтра последний день!

Краудфандинг заканчивается уже завтра, и второй попытки не будет.

👉 Поддержи easyoffer 2.0 и получи:

🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. Приглашение на закрытое бета-тестирование

📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
🤔 Что нужно сделать, чтобы описать GET-запрос?

Для описания GET-запроса нужно указать:
- метод запроса — GET;
- URL или эндпоинт;
- заголовки (например, авторизация, тип ответа);
- параметры запроса (в URL-строке);
- ожидаемый ответ — его структура, формат (например, JSON).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Forwarded from easyoffer
🚨 Последний шанс!

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

Если ты хотел, но откладывал — СЕЙЧАС самое время. Займёт 2 минуты, но изменит твой подход к собеседованиям надолго.

Поддержи easyoffer 2.0 и получи:

🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. Приглашение на закрытое бета-тестирование

PRO подписка к easyoffer 2.0:

Доступ к списку вопросов, которые задаются на собеседованиях + вероятность встречи этих вопросов + их фильтрация по грейдам, типам интервью, компаниям

Доступ к лучшим ответам на вопросы

Список самых частых задач, которые задаются на собеседовании + их фильтрация по грейдам и компаниям

Доступ к лучшим ответам на задачи

Список тестовых заданий компаний + лучшее решение

Доступ к тренажеру "Проработка вопросов", который позволит очень быстро подготовиться к самым частым вопросам

Доступ к тренажеру "Реальное собеседование", который позволит тренироваться проходить собеседование в конкретную компанию

До конца кампании — остались часы.
Поддержать: https://planeta.ru/campaigns/easyoffer

📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ