Swift | Вопросы собесов
2.13K subscribers
28 photos
955 links
Download Telegram
🤔 За счёт чего стек быстрее кучи?

Стек быстрее кучи, потому что операции в стеке, такие как добавление и удаление, имеют фиксированную сложность O(1), благодаря строгому порядку (LIFO). Стек управляется автоматически, без необходимости выделения и освобождения памяти вручную. Куча, напротив, требует больше времени из-за динамического управления памятью и возможных операций фрагментации.

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

🟠Простые приложения
Минимальная логика и количество экранов. Одностраничные приложения. Быстрая разработка.

🟠Быстрое прототипирование
Быстрое создание прототипов. Демонстрация идей заказчику. Легкость реализации.

🟠Минимальная сложность
Приложения с простой функциональностью. Калькуляторы, справочники. Простота поддержки.

🟠Обучение
Изучение основ iOS-разработки. Учебные проекты. Понятность для новичков.

🟠Поддержка старых проектов
Работа с существующими проектами на MVC. Доработка старого кода. Сохранение целостности архитектуры.

🚩Компоненты MVC

🟠Model
Данные и бизнес-логика.
struct User {
let name: String
}


🟠View
Отображение данных (Storyboards, xibs).
@IBOutlet weak var nameLabel: UILabel!   


🟠Controller
Управление взаимодействием между Model и View.
class ViewController: UIViewController {
var user: User?

override func viewDidLoad() {
super.viewDidLoad()
user = User(name: "Alice")
updateView()
}

func updateView() {
nameLabel.text = user?.name
}
}


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

Простота и ясность.
Четкое разделение ответственности.
Подходит для небольших проектов.
Сложность масштабирования.
Возможная перегрузка контроллеров.
Тесная связь между компонентами.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Чем отличается rebase от merge?

rebase переписывает историю, применяя изменения вашей ветки поверх целевой ветки, создавая линейную историю. merge объединяет две ветки, сохраняя историю обеих, что может привести к дополнительным коммитам при конфликте.

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

Это классификация различных видов данных, которые могут быть использованы и манипулированы в программе. Они определяют, какие операции можно выполнять с данными и как они хранятся в памяти.

🤔 Основные типы данных

🟠Примитивные типы данных
Представляют целые числа. Int, UIn
       let age: Int = 25


Представляют дробные числа. Float, Double
       let pi: Double = 3.14159


Представляют логические значения true или false. Bool
       let isActive: Bool = true


Представляют отдельные символы. Character
       let letter: Character = "A"


🟠Составные типы данных (Composite data types)
Представляют последовательности символов. String
       let greeting: String = "Hello, World!"


Представляют упорядоченные коллекции элементов одного типа. Array<T>
       let numbers: [Int] = [1, 2, 3, 4, 5]


Представляют коллекции пар ключ-значение. Dictionary<Key, Value>
       let user: [String: String] = ["name": "Alice", "age": "30"]


Представляют коллекции уникальных элементов. Set<T>
       let uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5]


🟠Пользовательские типы данных (User-defined data types)
Представляют тип данных с набором связанных значений. enum
       enum CompassPoint {
case north
case south
case east
case west
}


Представляют группы связанных значений. struct
       struct Person {
var name: String
var age: Int
}
let person = Person(name: "Alice", age: 30)


Представляют объекты с состоянием и поведением. class
       class Car {
var model: String
var year: Int

init(model: String, year: Int) {
self.model = model
self.year = year
}
}
let car = Car(model: "Tesla", year: 2021)


🟠Специальные типы данных
Представляют группы нескольких значений различных типов. (Type1, Type2, ...)
       let coordinates: (Int, Int) = (10, 20)


Представляют значение, которое может быть либо некоторым значением, либо nil. Optional<T>
       var optionalName: String? = "Alice"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31
🤔 Какой оператор используется для проверки на `nil` и предоставления значения по умолчанию в Swift?
Anonymous Quiz
18%
?
1%
!
81%
??
0%
&&
🤔 В чем отличие классов и структур?

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

🚩Основные отличия

🟠Тип данных
Классы: Ссылочный тип.
Структуры: Значимый тип.

🟠Передача по значению и по ссылке
Классы: Передаются по ссылке. При присваивании переменной другого объекта, оба объекта указывают на одну и ту же область памяти.
Структуры: Передаются по значению. При присваивании переменной другой структуры, создается копия структуры.
   // Класс
class PersonClass {
var name: String
init(name: String) {
self.name = name
}
}

let person1 = PersonClass(name: "Alice")
let person2 = person1
person2.name = "Bob"
print(person1.name) // "Bob" (оба объекта указывают на одну и ту же память)

// Структура
struct PersonStruct {
var name: String
}

var person3 = PersonStruct(name: "Alice")
var person4 = person3
person4.name = "Bob"
print(person3.name) // "Alice" (создана копия структуры)


🟠Наследование
Классы: Поддерживают наследование, то есть один класс может наследовать свойства и методы другого класса.
Структуры: Не поддерживают наследование.
   // Класс с наследованием
class Vehicle {
var speed: Int = 0
func description() -> String {
return "Moving at \(speed) km/h"
}
}

class Car: Vehicle {
var hasSunroof: Bool = false
}

let myCar = Car()
myCar.speed = 120
myCar.hasSunroof = true
print(myCar.description()) // "Moving at 120 km/h"


🟠Деинициализаторы
Классы: Могут иметь деинициализаторы (deinitializers), которые вызываются перед освобождением экземпляра класса.
Структуры: Не имеют деинициализаторов.
   class MyClass {
deinit {
print("MyClass is being deinitialized")
}
}


🟠Сборка мусора и управление памятью
Классы: Используют автоматическое управление памятью с подсчетом ссылок (ARC). Объекты удаляются, когда на них больше нет сильных ссылок.
Структуры: Удаляются автоматически, когда выходят из области видимости.

🟠Расширяемость (Extensions)
Оба: Поддерживают расширения (extensions), что позволяет добавлять новые функциональности к существующим классам или структурам.

🟠Протоколы (Protocols)
Оба: Поддерживают соответствие протоколам.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
🤔 Можно ли имитировать множественное наследование?

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

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

Структуры в Swift являются значимыми типами, что означает, что они передаются и копируются по значению. Это означает, что каждая копия структуры является независимой от других копий.

🚩Основные аспекты

🟠Передача по значению
Когда вы присваиваете одну структуру другой или передаете структуру функции, создается копия всей структуры, а не передается ссылка на исходную структуру.
     struct Person {
var name: String
var age: Int
}

var person1 = Person(name: "Alice", age: 30)
var person2 = person1 // Создается копия person1
person2.name = "Bob"

print(person1.name) // "Alice" (оригинал не изменился)
print(person2.name) // "Bob" (копия изменена)


🟠Неявное копирование
Копирование происходит автоматически при присваивании или передаче структур. Это делает работу со структурами безопасной и предсказуемой.
     func updateName(person: Person) -> Person {
var updatedPerson = person
updatedPerson.name = "Charlie"
return updatedPerson
}

let person = Person(name: "Alice", age: 30)
let updatedPerson = updateName(person: person)

print(person.name) // "Alice"
print(updatedPerson.name) // "Charlie"


🟠Изменение свойств
Изменения, сделанные в одной копии структуры, не влияют на другие копии.
     var person1 = Person(name: "Alice", age: 30)
var person2 = person1
person2.age = 35

print(person1.age) // 30
print(person2.age) // 35


🟠Копирование вложенных структур
При копировании структуры копируются также все ее вложенные структуры.
     struct Address {
var city: String
}

struct Person {
var name: String
var address: Address
}

var person1 = Person(name: "Alice", address: Address(city: "New York"))
var person2 = person1
person2.address.city = "San Francisco"

print(person1.address.city) // "New York"
print(person2.address.city) // "San Francisco"


🚩Оптимизации копирования

🟠Copy-on-write (COW)
Swift использует оптимизацию copy-on-write для некоторых стандартных типов данных (например, массивов). Это означает, что фактическое копирование происходит только тогда, когда одна из копий изменяется.
     var array1 = [1, 2, 3]
var array2 = array1 // array1 и array2 указывают на один и тот же массив
array2.append(4) // array2 создает свою копию и модифицирует ее

print(array1) // [1, 2, 3]
print(array2) // [1, 2, 3, 4]


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

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

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

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

В языке Swift множества (sets) могут содержать только элементы одного типа. Это обусловлено тем, что множества реализованы как обобщённые (generic) коллекции.

🚩Почему множества в Swift содержат элементы одного типа

🟠Обобщённые коллекции
Swift использует обобщения (generics) для своих коллекций, таких как массивы (arrays), множества (sets) и словари (dictionaries). Это означает, что при создании множества вы указываете тип элементов, которые оно будет содержать, и все элементы должны быть этого типа.
🟠Типобезопасность
Это помогает обеспечить типобезопасность (type safety). Когда тип элементов известен, компилятор может проверять правильность операций с элементами во время компиляции, предотвращая множество потенциальных ошибок на этапе исполнения.

🚩Как создаются множества

Для создания множества необходимо указать тип элементов. Например, если мы хотим создать множество строк
var stringSet: Set<String> = ["Apple", "Banana", "Cherry"]


Если мы попробуем добавить в это множество элемент другого типа, компилятор выдаст ошибку
// Ошибка: Cannot convert value of type 'Int' to expected argument type 'String'
stringSet.insert(42)


🚩Пример с множествами различных типов

Множество целых чисел
var intSet: Set<Int> = [1, 2, 3, 4, 5]
intSet.insert(6) // Это допустимо


Множество строк
var stringSet: Set<String> = ["Red", "Green", "Blue"]
stringSet.insert("Yellow") // Это допустимо


Множество пользовательских объектов
struct Person: Hashable {
let name: String
let age: Int
}

var peopleSet: Set<Person> = [Person(name: "John", age: 30), Person(name: "Jane", age: 25)]
peopleSet.insert(Person(name: "Doe", age: 40)) // Это допустимо


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
🤔 Какие принципы программирования бывают?

1. SOLID: набор принципов ООП для создания гибкого и масштабируемого кода (единственная ответственность, открытость/закрытость, подстановка Лисков, разделение интерфейсов, инверсия зависимостей).
2. DRY (Don't Repeat Yourself): избегание повторения кода.
3. KISS (Keep It Simple, Stupid): упрощение структуры и логики программ.
4. YAGNI (You Aren't Gonna Need It): не добавляйте функционал, пока он не нужен.
5. Separation of Concerns: разделение логики программы на модули с отдельной ответственностью.


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

Да, Swift, язык программирования, используемый для разработки приложений на iOS, является строго типизированным языком. Это означает, что каждое значение в Swift имеет определенный тип, который определяет, какие операции можно выполнять с этим значением. Типобезопасность Swift помогает разработчикам избегать ошибок и писать более надежный код.

🚩Что значит "строго типизированный язык"?

🟠Явное указание типов
В Swift переменные и константы имеют определенный тип, который указывается при их объявлении. Если тип не указан явно, Swift может попытаться вывести тип автоматически на основе присваиваемого значения.
var explicitString: String = "Hello, World!" // Явное указание типа
var inferredInt = 42 // Неявное указание типа, Swift выводит тип как Int


🟠Проверка типов во время компиляции
Компилятор Swift проверяет правильность типов во время компиляции. Это позволяет обнаруживать многие ошибки на ранних этапах разработки, до выполнения программы.
var number: Int = 10
// number = "Ten" // Ошибка: Невозможно присвоить значение типа 'String' переменной типа 'Int'


🟠Безопасное преобразование типов
Swift требует явного преобразования типов, что предотвращает случайные ошибки.
let integer: Int = 42
let doubleValue: Double = Double(integer) // Явное преобразование Int в Double


🚩Почему типизация важна?

🟠Надежность и безопасность кода
Строгая типизация помогает выявлять ошибки на этапе компиляции, делая код более надежным и защищенным от множества потенциальных ошибок.

🟠Оптимизация производительности
Знание типов на этапе компиляции позволяет компилятору лучше оптимизировать код.

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

🚩Примеры работы с типами

Объявление переменных с явным указанием типов
let name: String = "Alice"
let age: Int = 30
let height: Double = 5.9


Использование выведения типов
let city = "New York" // Swift выводит тип как String
let population = 8_000_000 // Swift выводит тип как Int


Ошибка из-за несовместимости типов
let isOpen: Bool = true
// isOpen = 1 // Ошибка: Невозможно присвоить значение типа 'Int' переменной типа 'Bool'


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Можно совершить реализацию функции в протоколе?

Да, можно предоставить реализацию функции через расширения протоколов. Эта реализация будет доступна всем типам, которые соответствуют протоколу, если они не предоставили собственную реализацию.

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

В языке Swift массивы (arrays) являются типобезопасными коллекциями, что означает, что все элементы в массиве должны быть одного типа. Однако, если вам нужно хранить элементы разных типов в одном массиве, это можно сделать, используя некоторые обходные пути, такие как использование протоколов или объединённых типов. Рассмотрим это подробнее:

🚩Массивы одного типа

Обычно массивы в Swift содержат элементы одного типа. Это помогает компилятору проверять правильность типов и предотвращает множество ошибок.
var intArray: [Int] = [1, 2, 3, 4, 5]
var stringArray: [String] = ["Apple", "Banana", "Cherry"]


Попытка добавить элемент другого типа приведет к ошибке компиляции
// Ошибка: Cannot convert value of type 'String' to expected element type 'Int'
// intArray.append("Six")


🚩Хранение элементов разных типов

🟠Использование типа `Any`
Тип Any может представлять любой тип данных в Swift. Однако, использование Any убирает преимущества типобезопасности.
var mixedArray: [Any] = [1, "Two", 3.0, true]

for item in mixedArray {
if let intValue = item as? Int {
print("Integer value: \(intValue)")
} else if let stringValue = item as? String {
print("String value: \(stringValue)")
} else if let doubleValue = item as? Double {
print("Double value: \(doubleValue)")
} else if let boolValue = item as? Bool {
print("Boolean value: \(boolValue)")
}
}


🟠Использование объединённых типов (enums)
Можно определить перечисление с ассоциированными значениями для хранения различных типов данных в массиве.
enum MixedType {
case intValue(Int)
case stringValue(String)
case doubleValue(Double)
case boolValue(Bool)
}

var mixedArray: [MixedType] = [
.intValue(1),
.stringValue("Two"),
.doubleValue(3.0),
.boolValue(true)
]

for item in mixedArray {
switch item {
case .intValue(let intValue):
print("Integer value: \(intValue)")
case .stringValue(let stringValue):
print("String value: \(stringValue)")
case .doubleValue(let doubleValue):
print("Double value: \(doubleValue)")
case .boolValue(let boolValue):
print("Boolean value: \(boolValue)")
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Могут быть в протоколах опциональные функции?

Да, опциональные функции могут быть в протоколах, но только если протокол поддерживает Objective-C, что требует использования атрибута @objc. Они доступны для классов, так как зависят от Objective-C runtime.

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

🟠application(_:didFinishLaunchingWithOptions:)
Вызывается при запуске приложения, для начальной настройки.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}


🟠applicationDidBecomeActive(_:)
Когда приложение становится активным.
func applicationDidBecomeActive(_ application: UIApplication) {
// Восстановление задач
}


🟠applicationWillResignActive(_:)
Когда приложение станет неактивным.
func applicationWillResignActive(_ application: UIApplication) {
// Приостановка задач
}


🟠applicationDidEnterBackground(_:)
Когда приложение уходит в фоновый режим.
func applicationDidEnterBackground(_ application: UIApplication) {
// Сохранение данных
}


🟠applicationWillEnterForeground(_:)
Когда приложение возвращается на передний план.
func applicationWillEnterForeground(_ application: UIApplication) {
// Подготовка к возвращению
}


🟠applicationWillTerminate(_:)
Когда приложение завершает работу.
func applicationWillTerminate(_ application: UIApplication) {
// Завершение задач
}


🚩Жизненный цикл представления (UIViewController)

🟠viewDidLoad()
Вызывается после загрузки представления.
override func viewDidLoad() {
super.viewDidLoad()
// Настройка интерфейса
}


🟠viewWillAppear(_:)
Перед тем, как представление станет видимым.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Обновление данных
}


🟠viewDidAppear(_:)
После того, как представление стало видимым.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Запуск задач
}


🟠viewWillDisappear(_:)
Перед тем, как представление станет невидимым.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Сохранение данных
}


🟠viewDidDisappear(_:)
После того, как представление стало невидимым.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Освобождение ресурсов
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как будут реализованы опциональные функции в протоколах?

Опциональные функции реализуются как необязательные: их можно либо реализовать, либо игнорировать. Если функция не реализована, вызов такой функции будет просто проигнорирован без ошибок.

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

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

🚩Опционалы

В Swift опционалы (Optionals) позволяют переменной принимать либо значение определенного типа, либо значение nil. Опционалы "оборачивают" значение, указывая, что переменная может не содержать значения вовсе.
var name: String? = "Alex"


Принудительное разворачивание (force unwrapping)
if name != nil {
print(name!) // Использование "!" для принудительного разворачивания
}


Безопасное разворачивание (optional binding)
if let unwrappedName = name {
print(unwrappedName)
}


🚩Property Wrappers (Обёртки свойств)

Property Wrappers — это механизм, позволяющий добавлять поведение к свойствам классов и структур.
@propertyWrapper
struct Uppercased {
private var value: String = ""
var wrappedValue: String {
get { value }
set { value = newValue.uppercased() }
}
}

struct User {
@Uppercased var username: String
}

var user = User(username: "alex")
print(user.username) // Выведет "ALEX"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Чем коллекции отличаются от массивов?

Размер: массивы имеют фиксированный размер, тогда как коллекции (например, списки) динамически изменяются.
Тип данных: массивы содержат элементы одного типа, а коллекции могут быть обобщёнными (Generic).
Функциональность: массивы предоставляют базовый доступ по индексу, тогда как коллекции предлагают методы для сортировки, фильтрации и поиска.
Структура: массивы — линейные, коллекции включают списки, множества, словари и другие сложные структуры.


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

В контексте iOS и Swift, термин "scapin" не является общепринятым или стандартным. Возможно, вы имели в виду что-то другое. Могу предположить, что это опечатка или автокоррекция какого-то другого термина. Если у вас есть дополнительная информация или контекст, пожалуйста, поделитесь, чтобы я мог точнее ответить на ваш вопрос.

🚩Escaping Closures

В Swift замыкания (closures) могут быть обозначены как "escaping" или "не escaping". Это важно для управления временем жизни и областью видимости замыкания.

🟠Non-escaping Closures
По умолчанию замыкания не "escaping", что означает, что они должны быть выполнены до выхода из функции, в которую они переданы. Такой тип замыканий позволяет компилятору проводить более агрессивные оптимизации.
   func performAction(closure: () -> Void) {
closure()
}


🟠Escaping Closures
Замыкания, помеченные как @escaping, могут быть выполнены после выхода из функции, в которую они переданы. Это необходимо, когда замыкание сохраняется и вызывается позже, например, асинхронно.
   func performActionWithEscaping(closure: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
closure()
}
}


🚩Scoping

Область видимости (scope) определяет, где переменные и константы могут быть доступны в коде. В Swift существуют различные области видимости:

🟠Локальная область видимости
Переменные, объявленные внутри функции или блока кода, доступны только в пределах этого блока.
   func exampleFunction() {
let localVariable = "I am local"
print(localVariable)
}


🟠Область видимости экземпляра
Переменные, объявленные внутри класса или структуры, доступны для всех методов и свойств этого класса или структуры.
   class ExampleClass {
var instanceVariable = "I am an instance variable"

func printInstanceVariable() {
print(instanceVariable)
}
}


🟠Глобальная область видимости
Переменные, объявленные вне всех функций, классов и структур, доступны в любом месте в файле.
   let globalVariable = "I am global"

func printGlobalVariable() {
print(globalVariable)
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁21🤔21