TGViewer
Channel Public Channel
C# | Вопросы собесов

C# | Вопросы собесов

@easy_c_sharp

Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy

Контакт для рекламы: @sendme_ads
Subscribers
5.01K
Photos
40
Videos
0
Links
1.6K

Showing posts older than #1975 · Back to latest

Older Posts 20 shown
Post #1974 984
🤔 Что такое предикат?

Это делегат, представляющий метод, который принимает один или несколько аргументов и возвращает логическое значение (true или false). Предикаты часто используются для фильтрации коллекций, поиска элементов и других операций, связанных с условными проверками.

🚩Особенности

🟠Тип делегата
В C# предикат представлен делегатом Predicate<T>, который принимает один аргумент типа T и возвращает bool.

🟠Использование
Предикаты обычно используются в методах стандартных коллекций, таких как List<T>, для поиска, удаления и фильтрации элементов.

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

Определение предиката
public static bool IsEven(int number)
{
return number % 2 == 0;
}


Использование предиката с методом коллекции
using System;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// Использование предиката для поиска первого четного числа
int firstEven = numbers.Find(IsEven);
Console.WriteLine("First even number: " + firstEven);

// Использование предиката для удаления всех четных чисел
numbers.RemoveAll(IsEven);
Console.WriteLine("Numbers after removing evens: " + string.Join(", ", numbers));
}

public static bool IsEven(int number)
{
return number % 2 == 0;
}
}


🚩Лямбда-выражения как предикаты

Лямбда-выражения часто используются для определения предикатов непосредственно в месте вызова метода. Это делает код более компактным и удобочитаемым.

Пример использования лямбда-выражений
using System;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// Использование лямбда-выражения для поиска первого четного числа
int firstEven = numbers.Find(n => n % 2 == 0);
Console.WriteLine("First even number: " + firstEven);

// Использование лямбда-выражения для удаления всех четных чисел
numbers.RemoveAll(n => n % 2 == 0);
Console.WriteLine("Numbers after removing evens: " + string.Join(", ", numbers));
}
}


🚩Сценарии использования предикатов


🟠Фильтрация коллекций
Предикаты используются для определения условий фильтрации элементов в коллекциях.
List<int> evenNumbers = numbers.FindAll(IsEven);   


🟠Поиск элементов
Предикаты помогают находить элементы, соответствующие определенному условию.
int firstEven = numbers.Find(IsEven);   


🟠Удаление элементов
Предикаты используются для удаления элементов, соответствующих определенному условию.
numbers.RemoveAll(IsEven);


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 2
Post #1973 951
🤔 Как работает async/await?

async/await — это механизм для асинхронного программирования, позволяющий писать асинхронный код, который выглядит как синхронный. Ключевое слово async указывает, что метод может содержать await, который приостанавливает выполнение до завершения задачи. Во время ожидания поток освобождается для других операций, что повышает производительность. После завершения задачи выполнение метода возобновляется с того же места.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 👍 1
  • 💊 1
Post #1972 987
🤔 Что делает new 'имя объекта'()?

Оператор new в C# создаёт новый экземпляр объекта и выделяет для него память в куче (Heap) или стеке (Stack), в зависимости от типа.

🚩Как работает `new`?

Для классов (class) – выделяет память в куче (Heap) и возвращает ссылку на объект.
Для структур (struct) – если структура создаётся без new, её поля остаются неинициализированными, но если использовать new, она получает значения по умолчанию.
Для массивов (T[]) – выделяет память в куче, даже если T – это struct.
Для делегатов – создаёт экземпляр делегата.

Пример: new с классом (class)
class Person
{
public string Name;

public Person(string name)
{
Name = name;
}
}

class Program
{
static void Main()
{
Person p1 = new Person("Alice"); // Создаём новый объект в куче
Console.WriteLine(p1.Name); // Alice
}
}


Пример: new со структурой (struct)
struct Point
{
public int X;
public int Y;

public Point(int x, int y)
{
X = x;
Y = y;
}
}

class Program
{
static void Main()
{
Point p1 = new Point(5, 10); // Создаёт структуру в стеке
Console.WriteLine(p1.X); // 5
}
}


Пример: new с массивом
int[] numbers = new int[5]; // Создаёт массив в куче
numbers[0] = 10;
Console.WriteLine(numbers[0]); // 10


🚩Что делает `new` за кулисами?

Выделение памяти в куче (для классов) или в стеке (для структур).
Вызов конструктора класса или структуры.
Возвращение ссылки на объект (для классов) или самого объекта (для структур).

Ставь 👍 и забирай 📚 Базу знаний
  • 👍 2
Post #1970 964
🤔 В чём разница между var и dynamic?

- var — тип определяется на этапе компиляции. После компиляции он получает конкретный тип. Статическая типизация.
- dynamic — тип определяется во время выполнения. Ошибки типа могут проявиться только в рантайме.
var безопаснее, dynamic гибче, но требует осторожности.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 👍 2
  • 🔥 1
Post #1969 1.15K
🤔 Что такое аутентификация?

Когда человек вводит логин и пароль, система аутентифицирует его, проверяя, действительно ли это тот, за кого он себя выдаёт.

🚩Как работает аутентификация?

Пользователь вводит данные (например, логин и пароль).
Система проверяет их в базе данных.
Если данные верны → доступ разрешён.
Если данные неверны → отказ в доступе.

public async Task<IActionResult> Login(string username, string password)
{
var user = await _userManager.FindByNameAsync(username);
if (user != null && await _userManager.CheckPasswordAsync(user, password))
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
ModelState.AddModelError("", "Неверный логин или пароль");
return View();
}


🚩Виды аутентификации

🟠По паролю
Самый распространённый вариант. Минус: если пароль украден – доступ открыт.
🟠Двухфакторная (2FA)
Например, SMS-код + пароль. Усложняет взлом аккаунта.
🟠Биометрическая
Отпечаток пальца, Face ID. Удобно, но требует спецоборудования.
🟠OAuth (Google, Facebook, GitHub)
Вход через соцсети. Удобно, не нужно запоминать пароль.
🟠Аутентификация по токену (JWT)
Используется в API и микросервисах. Позволяет работать без сохранения сессий.

Ставь 👍 и забирай 📚 Базу знаний
  • 👍 2
  • 🔥 1
Post #1968 1K
🤔 Что такое инкапсуляция?

Инкапсуляция в объектно-ориентированном программировании — это механизм упаковки данных (переменных) и кода, работающего с данными (методов), в один объект и ограничение доступа к некоторым компонентам объекта, что способствует безопасности и упрощению интерфейса.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #1966 1.03K
🤔 Когда можно использовать using?

Ключевое слово using используется в двух основных контекстах: для управления областью видимости объектов, реализующих интерфейс IDisposable, и для включения пространств имён.

🟠Управление областью видимости объектов (IDisposable)
Можно использовать для создания блока кода, внутри которого объекты, реализующие интерфейс IDisposable, автоматически освобождаются по завершении блока. Это удобно для управления ресурсами, такими как файловые потоки, базы данных или другие ресурсы системы, которые требуют явного освобождения.
using (StreamWriter writer = new StreamWriter("example.txt"))
{
writer.WriteLine("Hello, world!");
}
// Здесь объект writer уже автоматически закрыт и освобожден.


🟠Включение пространств имён
Также используется для объявления пространств имен, которые будут использоваться в коде, позволяя обращаться к классам внутри этих пространств без полного указания их имён.
using System;
using System.IO;
using System.Text;

// Теперь можно использовать классы из System, System.IO и System.Text без полного указания имени.


🟠using для статических классов (C# 6.0 и выше)
Для включения статических классов, что позволяет обращаться к статическим членам класса напрямую без указания имени класса.
using static System.Console;
using static System.Math;

class Program
{
static void Main()
{
WriteLine(Sqrt(144)); // Использование метода WriteLine и Sqrt без указания классов Console и Math
}
}


Ставь 👍 и забирай 📚 Базу знаний
Post #1962 886
🤔 Что такое многопоточность и библиотека TPL?

Это способность приложения выполнять несколько операций одновременно с использованием потоков.
• TPL (Task Parallel Library) — библиотека в .NET для упрощения работы с асинхронным и параллельным программированием.
• Она предоставляет классы, такие как Task и Parallel, которые позволяют управлять потоками, синхронизацией и обработкой задач.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #1961 900
🤔 Как сделать связь один к одному?

В реляционных базах данных связь "один к одному" (one-to-one) подразумевает, что каждая запись в одной таблице соответствует ровно одной записи в другой таблице. Для реализации связи "один к одному" в SQL можно использовать несколько подходов, в зависимости от требований и архитектуры базы данных.

🚩Основные подходы

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

🚩Уникальные внешние ключи

Таблицы
Users (пользователи)
UserId (Primary Key)
UserName
Profiles (профили)
ProfileId (Primary Key)
UserId (Foreign Key, Unique)
ProfileData
Создание таблиц
CREATE TABLE Users (
UserId INT PRIMARY KEY,
UserName VARCHAR(100)
);

CREATE TABLE Profiles (
ProfileId INT PRIMARY KEY,
UserId INT UNIQUE,
ProfileData VARCHAR(255),
FOREIGN KEY (UserId) REFERENCES Users(UserId)
);


Вставка данных
INSERT INTO Users (UserId, UserName) VALUES (1, 'John Doe');
INSERT INTO Profiles (ProfileId, UserId, ProfileData) VALUES (1, 1, 'Profile data for John Doe');


Запрос данных
SELECT Users.UserName, Profiles.ProfileData
FROM Users
JOIN Profiles ON Users.UserId = Profiles.UserId;


🚩Одинаковые первичные ключи

Таблицы
Users (пользователи)
UserId (Primary Key)
UserName
Profiles (профили)
UserId (Primary Key, Foreign Key)
ProfileData
Создание таблиц
CREATE TABLE Users (
UserId INT PRIMARY KEY,
UserName VARCHAR(100)
);

CREATE TABLE Profiles (
UserId INT PRIMARY KEY,
ProfileData VARCHAR(255),
FOREIGN KEY (UserId) REFERENCES Users(UserId)
);


Вставка данных
INSERT INTO Users (UserId, UserName) VALUES (1, 'John Doe');
INSERT INTO Profiles (UserId, ProfileData) VALUES (1, 'Profile data for John Doe');


Запрос данных
SELECT Users.UserName, Profiles.ProfileData
FROM Users
JOIN Profiles ON Users.UserId = Profiles.UserId;


🚩Плюсы и минусы

🟠Уникальные внешние ключи
➕Четкая семантика внешнего ключа.
➕Легкость добавления дополнительных данных в связанную таблицу.
➖Необходимо следить за уникальностью внешнего ключа.

🟠Одинаковые первичные ключи
➕Единый идентификатор для связанных данных.
➕Простота конструкции при обеспечении связи.
➖Необходимость синхронизации идентификаторов в обеих таблицах.

Ставь 👍 и забирай 📚 Базу знаний
Post #1959 941
🤔 Как работает ThreadPool?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #1958 1.03K
🤔 Если в двух переменных хранится одинаковое значение, то будут ли они равны?

Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения.

🟠Примитивные типы (Value Types)
Для примитивных типов (например, int, float, char, bool) значение хранятся непосредственно в переменных, и их сравнение выполняется по значению.
int a = 5;
int b = 5;

bool areEqual = (a == b); // True


🟠Ссылочные типы (Reference Types)
Для ссылочных типов (например, классы, строки) переменные содержат ссылки на объекты в куче. Сравнение ссылочных типов по умолчанию выполняется по ссылке, а не по значению.
class Person
{
public string Name { get; set; }
}

Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };

bool areEqual = (person1 == person2); // False, потому что сравниваются ссылки


🟠Строки (Strings)
Строки являются ссылочными типами, но переопределяют операторы сравнения == и Equals для сравнения по значению.
string str1 = "Hello";
string str2 = "Hello";

bool areEqual = (str1 == str2); // True, строки сравниваются по значению


🟠Кастомные классы
Для кастомных классов можно переопределить методы Equals и GetHashCode, чтобы сравнивать объекты по значению.
class Person
{
public string Name { get; set; }

public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;

Person other = (Person)obj;
return Name == other.Name;
}

public override int GetHashCode()
{
return Name.GetHashCode();
}
}

Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };

bool areEqual = person1.Equals(person2); // True


Ставь 👍 и забирай 📚 Базу знаний
Post #1956 991
🤔 Какие есть базовые методы object?

Каждый тип в .NET наследует от базового класса object, который содержит:
- ToString — преобразует объект в строку.
- Equals — сравнивает два объекта на равенство.
- GetHashCode — возвращает числовой хэш объекта.
- GetType — возвращает информацию о типе.
- ReferenceEquals — сравнение ссылок, а не содержимого.
Эти методы можно переопределять для добавления нужного поведения.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #1955 1.01K
🤔 Как по ключу получить значение?

Для получения значения по ключу в словаре (Dictionary<TKey, TValue>) используются методы и свойства, такие как индексатор [], метод TryGetValue, и метод ContainsKey.

🟠Индексатор `[]`
Индексатор позволяет получить значение по ключу напрямую. Если ключ отсутствует в словаре, будет выброшено исключение KeyNotFoundException.
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};

try
{
string value = dictionary[2]; // Получение значения по ключу 2
Console.WriteLine(value); // Выведет "Two"
}
catch (KeyNotFoundException)
{
Console.WriteLine("Key not found");
}


🟠Метод `TryGetValue`
Метод TryGetValue позволяет безопасно получить значение по ключу. Он возвращает true, если ключ найден, и false, если ключ отсутствует. При этом значение записывается в выходной параметр.
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};

if (dictionary.TryGetValue(2, out string value))
{
Console.WriteLine(value); // Выведет "Two"
}
else
{
Console.WriteLine("Key not found");
}


🟠Метод `ContainsKey`
Метод ContainsKey проверяет наличие ключа в словаре. Его можно использовать в сочетании с индексатором для получения значения.
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};

if (dictionary.ContainsKey(2))
{
string value = dictionary[2];
Console.WriteLine(value); // Выведет "Two"
}
else
{
Console.WriteLine("Key not found");
}


Ставь 👍 и забирай 📚 Базу знаний
Post #1954 990
🤔 В чём разница между FirstOrDefault и SingleOrDefault?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 💊 1
Post #1953 970
🤔 Что такое unsafe?

Используется для объявления небезопасного контекста кода, который позволяет выполнять низкоуровневые операции, такие как манипуляции с указателями. Эти операции обычно не разрешены в безопасном управляемом коде, но могут быть необходимы для взаимодействия с неуправляемым кодом, оптимизации производительности или доступа к определенным системным ресурсам.

🚩Характеристики

🟠Объявление небезопасного контекста
Чтобы использовать указатели и выполнять небезопасные операции, нужно объявить метод, блок кода или тип как unsafe.
unsafe void UnsafeMethod()
{
int a = 10;
int* p = &a; // Использование указателя
Console.WriteLine(*p); // Разыменование указателя
}


🟠Компиляция с поддержкой `unsafe`
Для компиляции кода с unsafe необходимо включить поддержку небезопасного кода в настройках проекта. В Visual Studio это делается через свойства проекта:
1⃣Откройте свойства проекта.
2⃣Перейдите на вкладку "Сборка".
3⃣Установите флажок "Разрешить небезопасный код".

🟠Использование указателей
Указатели позволяют напрямую работать с адресами памяти, что может быть полезно для некоторых оптимизаций или взаимодействия с низкоуровневым кодом, написанным на C или C++.
unsafe void PointerExample()
{
int a = 5;
int* p = &a; // p указывает на адрес переменной a
Console.WriteLine((int)p); // Вывод адреса переменной a
Console.WriteLine(*p); // Вывод значения переменной a через указатель
}


🟠Небезопасные структуры
Вы можете объявлять структуры с указателями и использовать их в небезопасном контексте.
unsafe struct UnsafeStruct
{
public int* Pointer;
}


🟠Стековые указатели (stackalloc)
stackalloc позволяет выделять память в стеке для массива в небезопасном контексте. Это может быть быстрее, чем выделение памяти в куче.
unsafe void StackAllocExample()
{
int* array = stackalloc int[10]; // Выделение массива из 10 целых чисел в стеке
for (int i = 0; i < 10; i++)
{
array[i] = i;
}
}


🟠Взаимодействие с неуправляемым кодом
Небезопасный код часто используется для взаимодействия с API, написанными на других языках, такими как C или C++.
[DllImport("user32.dll")]
extern static unsafe int MessageBox(IntPtr hWnd, char* text, char* caption, int options);

unsafe void CallUnmanagedCode()
{
char* text = "Hello, World!";
char* caption = "My Message Box";
MessageBox(IntPtr.Zero, text, caption, 0);
}


🚩Плюсы

➕Производительность

Позволяет выполнять высокоэффективные операции с памятью.
➕Взаимодействие с неуправляемым кодом
Необходим для вызова функций из библиотек, написанных на других языках.
➕Низкоуровневый контроль
Предоставляет возможность прямого управления памятью и аппаратными ресурсами.

Ставь 👍 и забирай 📚 Базу знаний
  • 👍 2
Post #1952 856
🤔 В чём отличие решения задачи через рекурсию и цикл?

- Рекурсия:
- Решение разбивается на подзадачи.
- Удобна для алгоритмов с вложенной логикой (деревья, обходы).
- Может привести к переполнению стека при глубокой рекурсии.
- Цикл:
- Экономичен по памяти.
- Лучше для итеративных, линейных задач.
- Может быть сложнее читаем в рекурсивных задачах.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #1951 977
🤔 Может ли абстрактный метод быть вне абстрактного класса?

Нет, абстрактный метод не может существовать вне абстрактного класса. В C# это ограничение встроено в язык, чтобы поддерживать строгую логику наследования и полиморфизма.

🚩Почему абстрактный метод требует абстрактного класса?

Абстрактный метод — это метод, который объявлен, но не имеет реализации. Он выступает как "контракт", который обязан быть реализован в производном классе.
public abstract class Shape
{
public abstract double CalculateArea();
}


Абстрактные методы имеют следующие особенности:
Они не могут содержать тело (реализацию).
Их цель — заставить производные классы реализовать конкретную функциональность.
Они всегда принадлежат абстрактным классам.

🚩Пример ошибки

Если попытаться объявить абстрактный метод в обычном классе, компилятор выдаст ошибку
public class RegularClass
{
public abstract void SomeMethod(); // Ошибка: абстрактный метод может быть только в абстрактном классе
}


🚩Логика дизайна

C# требует, чтобы абстрактные методы находились только в абстрактных классах, потому что:
Абстрактные классы могут содержать как абстрактные, так и обычные методы. Это позволяет определять базовое поведение в абстрактном классе и оставлять специфическую реализацию производным классам.
Обычные классы не могут содержать абстрактные методы, так как они предназначены для создания объектов, а объект не может содержать "незавершённый" метод.

Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #1950 941
🤔 Как работает сборка мусора на платформе .NET?

Сборщик мусора в .NET автоматически управляет выделением и освобождением памяти для приложений. Он отслеживает объекты, выделенные в управляемой куче, и освобождает те, которые больше не доступны, выполняя такие задачи, как компактизация памяти для улучшения производительности.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #1949 950
🤔 Какие типы данных можно использовать у Dictionary в качестве ключа?

В C# ключ (TKey) в Dictionary<TKey, TValue> должен быть уникальным и поддерживать сравнение.
Лучше всего использовать неизменяемые (immutable) типы, такие как:
Примитивные типы (int, string, char, bool, Guid, enum)
Кортежи (Tuple, ValueTuple)
Неизменяемые структуры (struct, если переопределён Equals и GetHashCode)

🚩Какие типы подходят в качестве ключа?

Числовые типы (int, double, long)
var dict = new Dictionary<int, string>
{
{1, "Один"},
{2, "Два"}
};
Console.WriteLine(dict[1]); // Вывод: Один


string (лучший выбор)
var dict = new Dictionary<string, int>
{
{"apple", 10},
{"banana", 5}
};
Console.WriteLine(dict["apple"]); // 10


Guid (уникальные идентификаторы)
var dict = new Dictionary<Guid, string>
{
{Guid.NewGuid(), "User1"},
{Guid.NewGuid(), "User2"}
};


enum (хороший вариант)
enum Status { New, Processing, Completed }

var dict = new Dictionary<Status, string>
{
{Status.New, "Заказ создан"},
{Status.Processing, "Заказ в обработке"}
};


Можно использовать несколько значений в качестве ключа:
var dict = new Dictionary<(int, string), string>
{
{(1, "apple"), "Красное яблоко"},
{(2, "banana"), "Жёлтый банан"}
};
Console.WriteLine(dict[(1, "apple")]); // Красное яблоко


🚩Какие типы нельзя использовать в качестве ключа?

List<T> (и другие изменяемые коллекции)
var dict = new Dictionary<List<int>, string>(); // Ошибка при использовании в качестве ключа!


class, если не переопределён Equals и GetHashCode
class Person { public string Name; }
var dict = new Dictionary<Person, string>(); // Плохо!


Нужно переопределить Equals и GetHashCode
class Person
{
public string Name { get; }

public Person(string name) => Name = name;

public override bool Equals(object? obj)
{
return obj is Person other && Name == other.Name;
}

public override int GetHashCode() => Name.GetHashCode();
}


Ставь 👍 и забирай 📚 Базу знаний
Post #1947 954
🤔 Как реализовать Dictionary, чтобы не использовать ConcurrentDictionary?

Если ConcurrentDictionary по каким-то причинам не подходит, можно использовать обычный Dictionary, но при этом:
- Оборачивать доступ в lock (монитор), чтобы обеспечить потокобезопасность.
- Использовать ReaderWriterLockSlim для более гибкой блокировки чтения/записи. Такой подход требует ручной синхронизации, что сложнее и менее эффективно, чем готовое решение.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →