Ответ
lateinit используется для не-null переменных, которые инициализируются позже (например, в onCreate()). Подходит только для var и не работает с примитивами.
lazy — это делегат, который инициализирует переменную при первом доступе. Подходит для val, потокобезопасен по умолчанию.
Пример:
lateinit var name: String // инициализируем позже
val lazyValue: String by lazy { "Hello" } // инициализируется при первом вызове
lateinit — ручная инициализация, lazy — отложенная с ленивым вычислением.