- a == b → true (распаковка и сравнение значений)
- a1 == b1 → true (аналогично)
Но: Integer a = 128; Integer a1 = 128; a == a1 → false, т.к. кэширование Integer до 127.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊9👍1🔥1
Forwarded from easyoffer
🎉 Easyoffer 2.0 — самый успешный краудфандинг в истории рунета в категории "Технологии"!
Мы это сделали! За считанные часы после старта, благодаря вашей поддержке, проект не просто стартовал — он взлетел.
💸 Собрано: 2 276 840 рублей
Это не просто цифра — это ваше доверие, ваша вера в идею, и ваша инвестиция в будущее карьеры сотен (а скоро — тысяч) специалистов.
💼 Благодаря этой сумме мы уже:
— Наняли ещё пару разработчиков и аналитиков
— Запустили активный сбор и разметку новых данных
— Ускорили разработку и подняли планку качества
Спасибо каждому, кто поверил в нас на старте! Дальше — только масштабирование и развитие. Мы строим сервис, который станет must-have для всех, кто ищет работу в IT.
👉 Присоединяйтесь сейчас — это только начало.
Мы это сделали! За считанные часы после старта, благодаря вашей поддержке, проект не просто стартовал — он взлетел.
💸 Собрано: 2 276 840 рублей
Это не просто цифра — это ваше доверие, ваша вера в идею, и ваша инвестиция в будущее карьеры сотен (а скоро — тысяч) специалистов.
💼 Благодаря этой сумме мы уже:
— Наняли ещё пару разработчиков и аналитиков
— Запустили активный сбор и разметку новых данных
— Ускорили разработку и подняли планку качества
Спасибо каждому, кто поверил в нас на старте! Дальше — только масштабирование и развитие. Мы строим сервис, который станет must-have для всех, кто ищет работу в IT.
👉 Присоединяйтесь сейчас — это только начало.
В многомодульных проектах каждый модуль может иметь свой
AndroidManifest.xml, чтобы: Задавать зависимости (
uses-permission, uses-feature) для конкретного модуля. Определять компоненты (
Activity, Service, BroadcastReceiver) для каждого модуля. Автоматически объединять манифесты всех модулей в
AndroidManifest.xml главного (app) модуля. При сборке Gradle автоматически сливает (
merge) все AndroidManifest.xml в один итоговый файл. app/
├── src/main/AndroidManifest.xml ← Главный манифест
├── java/com/example/MainActivity.kt
├── res/
├── build.gradle
feature_login/
├── src/main/AndroidManifest.xml ← Манифест модуля `login`
├── java/com/example/login/LoginActivity.kt
├── res/
├── build.gradle
feature_chat/
├── src/main/AndroidManifest.xml ← Манифест модуля `chat`
├── java/com/example/chat/ChatActivity.kt
├── res/
├── build.gradle
При сборке манифесты модулей сливаются в манифест главного модуля.
<manifest package="com.example.app">
<application>
<activity android:name=".MainActivity" />
</application>
</manifest>
feature_login (feature_login/src/main/AndroidManifest.xml) <manifest>
<application>
<activity android:name=".login.LoginActivity" />
</application>
</manifest>
feature_chat (feature_chat/src/main/AndroidManifest.xml) <manifest>
<application>
<activity android:name=".chat.ChatActivity" />
</application>
</manifest>
После объединения итоговый
AndroidManifest.xml выглядит так <manifest package="com.example.app">
<application>
<activity android:name=".MainActivity" />
<activity android:name=".login.LoginActivity" />
<activity android:name=".chat.ChatActivity" />
</application>
</manifest>
Например, модуль
camera требует CAMERA, но другие модули — нет. <uses-permission android:name="android.permission.CAMERA" />
Каждый модуль добавляет только свои компоненты (например,
LoginActivity в feature_login). Например, модуль
feature_map использует Google Maps, но feature_login — нет. <uses-library android:name="com.google.android.maps" />
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
- Обобщённые классы (class Box<T>)
- Обобщённые методы (<T> void print(T t))
- Ограничения (extends, super) — для указания границ типов
- Сырые типы (List без параметра — deprecated)
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3🔥1
Разделение UI и бизнес-логики делает код понятнее, тестируемее и проще в поддержке.
Это ключевой принцип чистой архитектуры (Clean Architecture) и паттернов MVP, MVVM, MVI.
Плохой код (UI + логика в
Activity) class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
val result = fetchData() // ❌ Логика в UI
button.text = result
}
}
fun fetchData(): String {
return "Данные с сервера" // ❌ Тут должна быть ViewModel
}
}Разделим код на
Activity + ViewModel MainActivity (только UI) class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById<Button>(R.id.button)
viewModel.text.observe(this) { text ->
button.text = text // ✅ UI обновляется из ViewModel
}
button.setOnClickListener {
viewModel.loadData() // ✅ Вызываем бизнес-логику
}
}
}MainViewModel (бизнес-логика) class MainViewModel : ViewModel() {
private val _text = MutableLiveData<String>()
val text: LiveData<String> = _text
fun loadData() {
_text.value = "Данные с сервера" // ✅ UI не знает, откуда данные
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Forwarded from easyoffer
Что такое PRO-подписка на easyoffer 2.0?
easyoffer PRO — это не просто доступ к базе, а полноценный инструмент для получения оффера.
🧠 База вопросов с собеседований
+ Анализ на основе 4,000 собеседований
+ Вероятность встречи каждого вопроса
+ Фильтрация по грейдам, компаниям, типам интервью
+ Примеры ответов: текстовые и видео
+ Готовьтесь к собеседованию в конкретную компанию
🛠 Тренажер "Проработка вопросов"
+ Флеш-карточки + интервальные повторения
+ Персональная система показа карточек в зависимости от ваших ответов
+ Упор на наиболее частые вопросы
+ Фокус на слабые места и быстрый прогресс
🎭 Тренажер "Реальное собеседование"
+ Сценарии на основе реальных интервью
+ Подготовка к конкретным компаниям
+ Итоговая статистика: прошёл/не прошёл
🧩 База задач с собеседований
+ Live-coding и System Design задачи
+ Оценка вероятности встречи задачи
+ Подготовка к задачам по конкретным компаниям
📋 База тестовых заданий
+ Задания из реальных вакансий
+ Фильтрация по технологиям и грейдам
+ Лучшие решения в доступе
📈 Тренды технологий в вакансиях
+ Топ-100 навыков, которые требуют компании
+ Динамика популярности технологий
+ Фильтрация по грейдам
🎁 Специальная цена до релиза:
3200 руб. за целый год
Сейчас PRO на 1 год стоит как будет стоить 1 месяц после релиза. Покупка также открывает доступ к закрытому бета-тестированию.
+ Вы можете активировать подписку в любой момент, например, когда начнете искать работу.
Предзаказ здесь: https://planeta.ru/campaigns/easyoffer
📌 Цена поднимется сразу после запуска.
Если вы хотите перестать угадывать, что спросят на собеседовании, и начать точечно готовиться на основе реальных данных — easyoffer PRO именно для вас.
Экономьте время. Получайте оффер легко.
easyoffer PRO — это не просто доступ к базе, а полноценный инструмент для получения оффера.
🧠 База вопросов с собеседований
+ Анализ на основе 4,000 собеседований
+ Вероятность встречи каждого вопроса
+ Фильтрация по грейдам, компаниям, типам интервью
+ Примеры ответов: текстовые и видео
+ Готовьтесь к собеседованию в конкретную компанию
🛠 Тренажер "Проработка вопросов"
+ Флеш-карточки + интервальные повторения
+ Персональная система показа карточек в зависимости от ваших ответов
+ Упор на наиболее частые вопросы
+ Фокус на слабые места и быстрый прогресс
🎭 Тренажер "Реальное собеседование"
+ Сценарии на основе реальных интервью
+ Подготовка к конкретным компаниям
+ Итоговая статистика: прошёл/не прошёл
🧩 База задач с собеседований
+ Live-coding и System Design задачи
+ Оценка вероятности встречи задачи
+ Подготовка к задачам по конкретным компаниям
📋 База тестовых заданий
+ Задания из реальных вакансий
+ Фильтрация по технологиям и грейдам
+ Лучшие решения в доступе
📈 Тренды технологий в вакансиях
+ Топ-100 навыков, которые требуют компании
+ Динамика популярности технологий
+ Фильтрация по грейдам
🎁 Специальная цена до релиза:
3200 руб. за целый год
Сейчас PRO на 1 год стоит как будет стоить 1 месяц после релиза. Покупка также открывает доступ к закрытому бета-тестированию.
+ Вы можете активировать подписку в любой момент, например, когда начнете искать работу.
Предзаказ здесь: https://planeta.ru/campaigns/easyoffer
📌 Цена поднимется сразу после запуска.
Если вы хотите перестать угадывать, что спросят на собеседовании, и начать точечно готовиться на основе реальных данных — easyoffer PRO именно для вас.
Экономьте время. Получайте оффер легко.
BroadcastReceiver принимает сообщения (интенты) от системы или приложений — например, при смене сети или получения SMS. ContentProvider предоставляет структурированный способ доступа к данным, используется для обмена данными между приложениями (например, контакты, галерея).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
В
data class могут возникнуть проблемы со списками при использовании: Методов
copy() – список не копируется, а передаётся по ссылке. Методов
equals() и hashCode() – List сравнивается по элементам, что может быть медленно. Mutable списков (
MutableList) – изменения внутри списка изменяют все копии объекта. 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 (разные объекты)
}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()
}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
👍1🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2🤔1💊1
Основные компоненты Android-приложения:
Activity – экран пользовательского интерфейса.
Fragment – часть UI внутри
Activity. Service – выполняет фоновые задачи.
BroadcastReceiver – реагирует на системные события.
ContentProvider – управляет доступом к данным между приложениями.
Все компоненты наследуют
Context или получают его через getContext(). -
Activity и Service наследуют Context. -
Fragment, BroadcastReceiver и ContentProvider получают Context через getContext(). fun showToast(context: Context) {
Toast.makeText(context, "Привет!", Toast.LENGTH_SHORT).show()
}Все компоненты объявляются в
AndroidManifest.xml, чтобы система знала о них. <manifest>
<application>
<activity android:name=".MainActivity"/>
<service android:name=".MyService"/>
<receiver android:name=".MyReceiver"/>
<provider android:name=".MyContentProvider"/>
</application>
</manifest>
Все компоненты могут общаться друг с другом через
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 восстанавливается.
Можно управлять Task через Intent-флаги, affinity, launchMode.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍1
Передача больших данных (например, изображений, видео, 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)
Сохраняем изображение во
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), передаём ID записи, а не сам файл. val intent = Intent(this, ImageActivity::class.java)
intent.putExtra("image_id", imageId) // Передаём только ID
startActivity(intent)
Сохраняем путь
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, и мы найдём удобный способ
Мы на финишной прямой!
Если ты планировал присоединиться, но ещё не успел, сейчас идеальный момент.
Вознаграждения за поддержку:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу.
➕ Приглашение на закрытое бета-тестирование
👉 Поддержать easyoffer 2.0
Не откладывай на последний момент
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
👍1
Intents нужны для взаимодействия компонентов приложения: запуска Activity, Service, передачи данных или отправки Broadcast. Они являются основным способом коммуникации между модулями и приложениями в Android.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Модификаторы доступа (Access Modifiers) — это ключевые слова, которые определяют, кто может видеть и использовать класс, переменную или метод.
Они помогают инкапсулировать данные и защищать код от неправильного использования.
Пример Java
public class Example {
private int a = 10; // ❌ Только внутри класса
int b = 20; // ✅ Видно внутри пакета (package-private)
protected int c = 30; // ✅ Видно в пакете и наследниках
public int d = 40; // ✅ Доступно везде
}В 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 и onRestoreInstanceStateclass 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 в ViewModelclass 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
Используется LazyColumn или LazyRow. Они создают и отображают элементы по мере необходимости, экономя ресурсы и обеспечивая плавную прокрутку.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥2
XML — это eXtensible Markup Language (Расширяемый язык разметки).
eXtensible → Расширяемый (можно создавать свои теги).
Markup → Разметка (использует теги
<tag> для структурирования данных). Language → Язык (формат хранения и передачи данных).
В 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 — это ведь мой первый сайт. Учебный, пет-проект, просто для портфолио. И вот что из него вышло. Просто офигеть.
Я не зря ушёл с работы, чтобы заниматься только им.
Я поверил в этот проект — и сейчас вижу, что вы тоже в него верите. Для меня это очень многое значит.
Огромное спасибо за вашу поддержку! ❤️
Скажу честно: когда я планировал запуск краудфандинговой кампании, в голове были разные варианты развития событий. Думал — ну, наверное, получится собрать 300 тысяч. В самом идеальном сценарии — может быть, миллион.
Но больше всего я боялся, что запущу кампанию, и не получится собрать даже 300 т. Это был бы провал. Так много усилий, времени и денег вложено в проект… и если бы всё закончилось ничем — это бы сильно демотивировало.
Но, ребята, мы превысили изначальную цель в 10 раз —
3 031 040 рублей! 🤯
Вся эта кампания — это одна большая проверка бизнес-модели на прочность. И я супер рад, что запустил всё публично. Люди видят, что EasyOffer реально нужен. Теперь нет сомнений — проект актуален, он будет прибыльным и будет развиваться.
Мне приходит огромное количество сообщений в личку: кто-то когда-то давно пользовался сайтом, он помог с трудоустройством, и сейчас они уже не ищут работу — но всё равно поддержали.
Это прям очень круто и трогательно.
Никак не могу отделаться от мысли, что easyoffer — это ведь мой первый сайт. Учебный, пет-проект, просто для портфолио. И вот что из него вышло. Просто офигеть.
Я не зря ушёл с работы, чтобы заниматься только им.
Я поверил в этот проект — и сейчас вижу, что вы тоже в него верите. Для меня это очень многое значит.
Огромное спасибо за вашу поддержку! ❤️