Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Автоматическое обнаружение проблем с отрисовкой в Android-приложениях может быть выполнено с использованием различных инструментов и техник.
Choreographer - это класс, который позволяет получить информацию о времени отрисовки кадра. Вы можете использовать его для отслеживания задержек в отрисовке.Android Studio предоставляет встроенные инструменты профилирования, которые могут помочь обнаружить проблемы с производительностью, включая задержки в отрисовке.
Откройте Android Studio и запустите свое приложение. Перейдите в раздел
View -> Tool Windows -> Profiler.Выберите ваше устройство и процесс. Нажмите на вкладку
CPU для профилирования использования процессора. Нажмите на вкладку Graphics для мониторинга отрисовки и обновления экрана.Просмотрите данные, чтобы определить, какие части вашего кода вызывают задержки в отрисовке. Обратите внимание на длинные фреймы (кадры), которые могут указывать на проблемы.
Вы можете использовать
adb shell dumpsys gfxinfo для получения информации о времени отрисовки кадров.adb shell dumpsys gfxinfo <your-package-name> framestats
Команда предоставляет информацию о каждом кадре, включая время его отрисовки. Вы можете анализировать вывод, чтобы найти кадры, которые заняли больше времени, чем ожидается (больше 16.67 мс).
Начиная с API 24 (Android 7.0), вы можете использовать
FrameMetrics API для получения подробной информации о производительности отрисовки.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍4
Запрос данных из двух таблиц обычно выполняется с помощью операции объединения (JOIN) в SQL. Алгоритм и его сложность зависят от типа объединения, структуры данных и используемой базы данных.
Предположим, у нас есть две таблицы:
employees и departments. Мы хотим получить список сотрудников вместе с их отделами.SELECT employees.name, departments.name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;
Для каждой строки из первой таблицы выполняется поиск соответствующих строк во второй таблице.
for each row in employees:
for each row in departments:
if row.employees.department_id == row.departments.id:
yield (row.employees.name, row.departments.name)
Создается хеш-таблица для одной из таблиц на основе ключа соединения. Для каждой строки из другой таблицы проверяется наличие соответствующего ключа в хеш-таблице.
hash_table = {}
for each row in departments:
hash_table[row.id] = row.name
for each row in employees:
if row.department_id in hash_table:
yield (row.name, hash_table[row.department_id])Обе таблицы сортируются по ключу соединения, затем выполняется слияние отсортированных списков.
sorted_employees = sort(employees, key=lambda x: x.department_id)
sorted_departments = sort(departments, key=lambda x: x.id)
i, j = 0, 0
while i < len(sorted_employees) and j < len(sorted_departments):
if sorted_employees[i].department_id == sorted_departments[j].id:
yield (sorted_employees[i].name, sorted_departments[j].name)
i += 1
j += 1
elif sorted_employees[i].department_id < sorted_departments[j].id:
i += 1
else:
j += 1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁2👍1💊1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Для оптимизации запросов к базам данных можно использовать различные структуры данных и индексы, которые ускоряют операции поиска и соединения.
B-деревья и их модификация, B+-деревья, являются сбалансированными деревьями поиска, которые широко используются для построения индексов в базах данных.
Быстрый поиск, вставка и удаление: Операции поиска, вставки и удаления выполняются за O(log n).
Эффективное использование дискового пространства: B-деревья хорошо подходят для хранения на диске, так как минимизируют количество операций ввода-вывода.
Хеш-таблицы используются для быстрого доступа к данным по ключу. В базах данных часто используются хеш-индексы.
Мгновенный доступ: Операции поиска, вставки и удаления выполняются в среднем за O(1).
Подходят для равенств: Эффективны для запросов с условием равенства (например, WHERE id = 123).Неэффективны для диапазонов: Хеш-индексы не подходят для запросов с диапазонами (например, WHERE age BETWEEN 20 AND 30).
Bitmap индексы используют битовые карты для представления данных и часто используются для столбцов с низкой кардинальностью (небольшое количество уникальных значений).
Эффективное хранение: Особенно эффективны для столбцов с низкой кардинальностью.
Быстрые логические операции: Позволяют быстро выполнять логические
Неэффективны для частых обновлений: Не подходят для таблиц с частыми операциями вставки и обновления.
Реверсные индексы используются для полнотекстового поиска. Они хранят сопоставления терминов и документов, в которых эти термины встречаются.
Быстрый полнотекстовый поиск: Позволяют эффективно выполнять поиск по текстовым данным.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤯1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3🤯1👀1👾1
Для сохранения уникальной информации для каждого элемента в реляционной таблице используются уникальные ключи и различные типы ограничений. В реляционных базах данных уникальные ключи обеспечивают уникальность данных в столбцах, предотвращая дублирование.
Первичный ключ уникально идентифицирует каждую строку в таблице. Таблица может иметь только один первичный ключ, состоящий из одного или нескольких столбцов.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT
);
Уникальные ограничения гарантируют, что значения в одном или нескольких столбцах будут уникальными.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
email VARCHAR(100) UNIQUE,
name VARCHAR(100),
department_id INT
);
Автоинкрементирование используется для автоматической генерации уникальных значений для столбца. Обычно используется для первичных ключей.
CREATE TABLE employees (
employee_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
department_id INT
);
Индексы помогают ускорить поиск и обеспечивают уникальность данных в столбцах, когда используется уникальный индекс.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT
);
CREATE UNIQUE INDEX idx_email ON employees(email);
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Виртуальные таблицы, такие как те, что используются в SQLite с помощью
CREATE VIRTUAL TABLE, предлагают мощные возможности для работы с данными. Однако они также имеют некоторые недостатки. Виртуальные таблицы могут не поддерживать все стандартные функции и возможности SQL, такие как ограничения (constraints), триггеры и определенные типы индексов. Это связано с тем, что их функциональность определяется модулем, который реализует виртуальную таблицу.
CREATE VIRTUAL TABLE my_virtual_table USING fts4(content TEXT);
Виртуальные таблицы могут иметь производительность ниже, чем обычные таблицы, особенно если они не оптимизированы должным образом. Производительность может пострадать из-за дополнительных накладных расходов, связанных с обработкой виртуальных таблиц на уровне приложения или расширений.
Использование виртуальных таблиц требует дополнительных знаний и опыта в разработке и обслуживании. Например, вам может потребоваться написать и поддерживать специализированные модули или расширения для реализации виртуальных таблиц, что увеличивает сложность кода и потенциальные затраты на поддержку.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥4
На текущем месте работы количество разработчиков моего уровня может варьироваться в зависимости от конкретной организации и структуры команды. Обычно команды разработчиков включают специалистов разных уровней, таких как Junior, Middle и Senior, чтобы обеспечить эффективное распределение задач и наставничество.
Если говорить о типичных сценариях, то в среднем команда разработки может включать от 2 до 5 разработчиков одного уровня, особенно в крупных проектах или компаниях с большим штатом сотрудников. В небольших компаниях или стартапах это число может быть меньше, а иногда и только один разработчик каждого уровня.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Создание утилиты для библиотеки в Java включает несколько шагов: проектирование, реализацию, тестирование и документирование. Рассмотрим процесс создания утилиты на примере простой библиотеки для работы со строками.
Перед началом реализации необходимо определить функциональность, которую будет предоставлять утилита. Допустим, мы создаем библиотеку для работы со строками, включающую следующие функции:
Проверка, является ли строка палиндромом.
Обратный порядок символов в строке.
Подсчет количества слов в строке.
Создадим проект с простой структурой.
Создадим тесты для проверки функциональности утилиты.
Документирование кода помогает другим разработчикам понять, как использовать вашу библиотеку.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁2👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
Да, в Kotlin возможно получить
NullPointerException (NPE), несмотря на его сильную систему типов, которая стремится избежать null-значений. Kotlin делает много для предотвращения NullPointerException, но есть определенные случаи, когда NPE все еще может возникнуть.При вызове методов из Java, которые могут возвращать
null без соответствующей аннотации, Kotlin не может гарантировать отсутствие null.val list = java.util.ArrayList<String>()
list.add("Hello")
val size = list.size // Java-код, возвращающий потенциальный null
Оператор
!! явно указывает компилятору, что переменная не может быть null, но если она все же null, будет выброшено NullPointerException.val name: String? = null
val length = name!!.length // NPE если name == null
Переменные, помеченные как
lateinit, должны быть инициализированы перед использованием. Если переменная не была инициализирована и используется, будет выброшено UninitializedPropertyAccessException, что является подтипом RuntimeException.lateinit var name: String
fun initializeName() {
name = "Kotlin"
}
fun useName() {
println(name.length) // NPE если name не инициализирован
}
Статические инициализаторы могут быть источником
NullPointerException в случае неправильного порядка инициализации.object Example {
val name: String? = null
val length = name!!.length // NPE при инициализации объекта
}Kotlin-коррутины и потоки могут привести к NPE, если происходят необработанные исключения, особенно при работе с
ThreadLocal переменными.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2
Для обеспечения безопасности при работе с Java-кодом в Kotlin можно применять несколько стратегий и подходов, которые помогут избежать
NullPointerException (NPE) и других потенциальных проблем. Использование аннотаций в Java-коде помогает Kotlin понять, какие значения могут быть
null, а какие — нет. Наиболее распространенные аннотации включают @Nullable и @NotNull.Java-код
import org.jetbrains.annotations.Nullable;
public class JavaExample {
@Nullable
public static String getNullableString() {
return null;
}
}
Kotlin-код
val result: String? = JavaExample.getNullableString()
result?.let {
println(it.length)
}
Безопасный вызов и оператор Элвиса помогают обрабатывать потенциально
null значения безопасно.val result: String? = JavaExample.getNullableString()
val length = result?.length ?: 0
println("Length: $length")
Перед использованием значений, полученных из Java-кода, можно проверять их на
null.val result: String? = JavaExample.getNullableString()
if (result != null) {
println(result.length)
} else {
println("Result is null")
}
Обработка исключений помогает избежать непредвиденных ситуаций, когда Java-код может бросить исключение.
try {
val result = JavaExample.getNullableString()
println(result!!.length)
} catch (e: NullPointerException) {
println("Caught a NullPointerException")
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Anonymous Quiz
25%
httpClient.get()
9%
httpRequest.send()
46%
httpClient.request()
20%
httpRequest.execute()
Переменные по умолчанию не могут быть
null, что предотвращает NullPointerException.var a: String = "abc"
var b: String? = "abc"
b = null // Допустимо
Разделение на изменяемые и неизменяемые коллекции.
val list: List<String> = listOf("a", "b", "c") // Неизменяемый список
val mutableList: MutableList<String> = mutableListOf("a", "b", "c") // Изменяемый список Автоматическое создание методов
equals(), hashCode(), и toString().data class User(val name: String, val age: Int)
Автоматическое приведение типа после проверки с помощью
is.fun demo(x: Any) {
if (x is String) {
println(x.length)
}
} Упрощают обработку ограниченных иерархий классов.
sealed class Expr
data class Const(val number: Double) : Expr()
Kotlin автоматически определяет тип переменной.
val x = 10 // Int
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
2. Bundle: сохранение состояния через onSaveInstanceState() и восстановление в onCreate() или onViewStateRestored().
3. SharedPreferences: для сохранения небольших данных между запусками приложения.
4. Базы данных или файлы: для долгосрочного хранения больших объёмов данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1