Хочу упростить навигацию по каналу и обозначить темы, о которых мне интересно писать и размышлять.
1. Этот канал создавался, как помощник изучающим #swift и #ios в целом. Постараюсь фокусироваться на шеринг знаний в этих областях, как main stream канала.
2. Многие из вас в активном поиске новой работы или даже первой. Я уверен, что мой опыт в проведении и прохождении технических интервью будет релевантным. Топик - #interview #lookingforjob
3. Я долгое время хотел найти работу за рубежом и больше путешествовать. Поэтому хочу делиться своим опытом, как digital nomad и опытом переезда на постоянку в другую страну #relocate #remote #digitalnomad
4. Думаю, что так или иначе будут проскальзывать общие темы об #it и #programming через призму моего опыта и наблюдений #experience.
5. Все, что не попадет в обозначенные темы, но очень захочется запостить помечу #random
Чтобы получше узнать, что вам вообще интересно, запущу опросы. Не стесняйтесь голосовать они будут анонимны)
1. Этот канал создавался, как помощник изучающим #swift и #ios в целом. Постараюсь фокусироваться на шеринг знаний в этих областях, как main stream канала.
2. Многие из вас в активном поиске новой работы или даже первой. Я уверен, что мой опыт в проведении и прохождении технических интервью будет релевантным. Топик - #interview #lookingforjob
3. Я долгое время хотел найти работу за рубежом и больше путешествовать. Поэтому хочу делиться своим опытом, как digital nomad и опытом переезда на постоянку в другую страну #relocate #remote #digitalnomad
4. Думаю, что так или иначе будут проскальзывать общие темы об #it и #programming через призму моего опыта и наблюдений #experience.
5. Все, что не попадет в обозначенные темы, но очень захочется запостить помечу #random
Чтобы получше узнать, что вам вообще интересно, запущу опросы. Не стесняйтесь голосовать они будут анонимны)
Провел mock interview для совместного проекта Solvery и AgileFluent. К сожалению, были проблемы с трансляцией и звук записался в плохом качестве. Ссылку на собес все равно оставлю, но рекомендовать к просмотру не буду)
https://www.youtube.com/live/o6jxnLg6tks?feature=share
Теоретические вопросы, которые успели обсудить, прилагаются. На некоторые можно дать лаконичный ответ, а другие предполагают развернутые ответы в зависимости от уровня кандидата.
Common questions:
• First of all, please, tell me about your background and experience?
• What are you looking for in the next role?
• What is your the greatest achievement as an employee?
Computer science and Algorithm complexity:
• Let discuss SOLID principles. Can you find any examples from standard swift libraries where principles were kept or violated?
• Can you give some examples of where singletons might be a good idea? (Examples from ios UIApplication or URLSession)
• What kind of collections we have in Swift?
• What is the complexity of main operations in them?
• What the difference between Set and OrderedSet?
• How does OrderedSet look like under the hood?
Swift and ios
• How would you explain protocol-oriented programming to a new Swift developer? What is the difference between OOP and POP?
• What steps would you follow to make a network request? (Back to main thread, Combine, Swift type result)
Memory handling
• What is the difference between value type and reference type?
• Why we need unowned if we have weak parameter?
• What is the autorelease and autorelease pool? Use cases?
• What is the side table?
UI layer
• What does view controller life-cycle look like?
• What is the difference between CALayer and UIView?
• Can you name any different CALayer subclasses?
• Why we have three similar methods layoutSubview, layoutIfNeeded and setNeedsLayout?
• How can we establish relationship between two horizontal labels in case when text doesn't fit the screen?
Если какие-то вопросы не понятны, можете спросить в комментариях
#lookingforjob #interview #ios #swift
https://www.youtube.com/live/o6jxnLg6tks?feature=share
Теоретические вопросы, которые успели обсудить, прилагаются. На некоторые можно дать лаконичный ответ, а другие предполагают развернутые ответы в зависимости от уровня кандидата.
Common questions:
• First of all, please, tell me about your background and experience?
• What are you looking for in the next role?
• What is your the greatest achievement as an employee?
Computer science and Algorithm complexity:
• Let discuss SOLID principles. Can you find any examples from standard swift libraries where principles were kept or violated?
• Can you give some examples of where singletons might be a good idea? (Examples from ios UIApplication or URLSession)
• What kind of collections we have in Swift?
• What is the complexity of main operations in them?
• What the difference between Set and OrderedSet?
• How does OrderedSet look like under the hood?
Swift and ios
• How would you explain protocol-oriented programming to a new Swift developer? What is the difference between OOP and POP?
• What steps would you follow to make a network request? (Back to main thread, Combine, Swift type result)
Memory handling
• What is the difference between value type and reference type?
• Why we need unowned if we have weak parameter?
• What is the autorelease and autorelease pool? Use cases?
• What is the side table?
UI layer
• What does view controller life-cycle look like?
• What is the difference between CALayer and UIView?
• Can you name any different CALayer subclasses?
• Why we have three similar methods layoutSubview, layoutIfNeeded and setNeedsLayout?
• How can we establish relationship between two horizontal labels in case when text doesn't fit the screen?
Если какие-то вопросы не понятны, можете спросить в комментариях
#lookingforjob #interview #ios #swift
YouTube
Моковое собеседование на iOS-разработчика в зарубежную компанию | Solvery + AgileFluent
Solvery совместно с AgileFluent и при поддержке сообщества Coffee&Code (https://t.me/coffeeCodeEverywhere) проведёт техническое собеседование на iOS-разработчика в международную компанию в прямом эфире! Присоединяйтесь, поддержите участника и узнайте, как…
Stack vs Heap 👨💻
Базовый вопрос на любой уровень кандидата, но часто слышу невнятные ответы. Собрал полный ответ, который зачастую, хотят услышать на интервью:
Stack(Стек):
• Статичная память. Выделение происходит только во время компиляции.
• Стек имеет структуру данных LIFO (последний пришел – первый вышел)
• Очень быстрый доступ
• При вызове функции все локальные экземпляры этой функции помещаются в текущий стек. И как только функция завершит выполнение, все экземпляры будут удалены из стека.
• Данные, хранящиеся в стеке, находятся там только временно, пока функция не завершит работу и не вызовет автоматическое освобождение всей памяти в стеке.
• Каждая область действия (scope) в вашем приложении (например, внутреннее содержимое метода) будет предоставлять необходимый объем памяти.
• Cтек не используется с объектами, которые изменяют размер.
• Каждый поток имеет собственный стек
• В стеках хранятся типы значений(value type), такие как структуры и перечисления, скаляры.
• Если размер вашего типа значения может быть определен во время компиляции или если ваш тип значения не содержит рекурсивно/не содержит ссылочного типа, тогда потребуется выделение стека.
• Value type не увеличивает счетчик ссылок. Но если ваш value type содержит внутренний reference typy, для его копирования потребуется вместо этого увеличить счетчик ссылок его дочерних элементов.
Heap(Куча):
• Динамическое распределение памяти и распределение происходит во время выполнения.
• К значениям можно обращаться в любое время через адрес памяти.
• Нет ограничений на объем памяти
• Доступ к объектам медленнее чем на стеке
• Когда процесс запрашивает определенный объем памяти, куча ищет адрес памяти, удовлетворяющий этому запросу, и возвращает его процессу.
• Когда память больше не используется, процесс должен сказать куче освободить этот раздел памяти.
• Требуется потокобезопасность.
• Куча доступна всем потокам
• Если размер вашего типа значения(value type) не может быть определен во время компиляции (из-за протокола/дженерика) или если ваш value type рекурсивно содержит/содержится внутри ссылочного типа (помните, что замыкания также являются ссылочными типами), тогда потребуется выделение кучи.
• Классы хранятся в динамической памяти.
Выделение кучи медленнее, чем выделение стека, не только из-за более сложной структуры данных — оно также требует безопасности потоков. Каждый поток имеет свой собственный стек, но куча используется совместно всеми, что требует синхронизации.
#interview #ios #swift
Базовый вопрос на любой уровень кандидата, но часто слышу невнятные ответы. Собрал полный ответ, который зачастую, хотят услышать на интервью:
Stack(Стек):
• Статичная память. Выделение происходит только во время компиляции.
• Стек имеет структуру данных LIFO (последний пришел – первый вышел)
• Очень быстрый доступ
• При вызове функции все локальные экземпляры этой функции помещаются в текущий стек. И как только функция завершит выполнение, все экземпляры будут удалены из стека.
• Данные, хранящиеся в стеке, находятся там только временно, пока функция не завершит работу и не вызовет автоматическое освобождение всей памяти в стеке.
• Каждая область действия (scope) в вашем приложении (например, внутреннее содержимое метода) будет предоставлять необходимый объем памяти.
• Cтек не используется с объектами, которые изменяют размер.
• Каждый поток имеет собственный стек
• В стеках хранятся типы значений(value type), такие как структуры и перечисления, скаляры.
• Если размер вашего типа значения может быть определен во время компиляции или если ваш тип значения не содержит рекурсивно/не содержит ссылочного типа, тогда потребуется выделение стека.
• Value type не увеличивает счетчик ссылок. Но если ваш value type содержит внутренний reference typy, для его копирования потребуется вместо этого увеличить счетчик ссылок его дочерних элементов.
Heap(Куча):
• Динамическое распределение памяти и распределение происходит во время выполнения.
• К значениям можно обращаться в любое время через адрес памяти.
• Нет ограничений на объем памяти
• Доступ к объектам медленнее чем на стеке
• Когда процесс запрашивает определенный объем памяти, куча ищет адрес памяти, удовлетворяющий этому запросу, и возвращает его процессу.
• Когда память больше не используется, процесс должен сказать куче освободить этот раздел памяти.
• Требуется потокобезопасность.
• Куча доступна всем потокам
• Если размер вашего типа значения(value type) не может быть определен во время компиляции (из-за протокола/дженерика) или если ваш value type рекурсивно содержит/содержится внутри ссылочного типа (помните, что замыкания также являются ссылочными типами), тогда потребуется выделение кучи.
• Классы хранятся в динамической памяти.
Выделение кучи медленнее, чем выделение стека, не только из-за более сложной структуры данных — оно также требует безопасности потоков. Каждый поток имеет свой собственный стек, но куча используется совместно всеми, что требует синхронизации.
#interview #ios #swift
❓ OOP vs POP
И так, продолжаю рубрику - батл #versus
Объектно-ориентированное программирование (ООП) и протокольно-ориентированное программирование (POP) представляют различные подходы к структурированию и проектированию кода. Вот некоторые сходства и различия между ними, которые стоит упоминуть, отвечая на такой вопрос:
Сходства:
✅ Оба подхода стремятся к абстракции и моделированию реального мира с помощью объектов и их взаимодействия.
✅ И ООП, и POP позволяют использовать полиморфизм для работы с разными типами данных, обрабатывая их через общий интерфейс.
✅ Оба подхода поддерживают концепцию инкапсуляции, позволяющую скрыть внутренние детали реализации и предоставить доступ только к необходимой функциональности.
Различия:
⚠️ ООП сосредоточено на использовании классов и наследования для организации кода. Классы могут наследовать свойства и методы от других классов и создавать иерархию наследования. В POP используются протоколы вместо классов для определения требований к функциональности.
⚠️ Наследование, может привести к сложным иерархиям классов и проблемам с тесной связностью. В особенности, множественного наследования (отсутствует в Swift). В POP используется композиция, где типы состоят из более специализированных компонентов через соответствие (conform) протоколам, обеспечивая более гибкую и модульную организацию кода.
⚠️ В ООП функциональность определяется внутри классов и их методов. В POP функциональность определяется через протоколы. Протоколы могут иметь требования к методам и свойствам, и типы должны реализовать эти требования.
⚠️ В POP протоколы позволяют использовать расширения протоколов для предоставления реализации методов по умолчанию. Это делает код более гибким и легким для расширения новыми функциями или высичляемыми свойствами. В ООП расширение функциональности класса может быть достигнуто через наследование или создание подклассов.
Какой подход выбрать зависит от требований и конкретной ситуации. В некоторых случаях ООП может быть предпочтительным, особенно если требуется сильная связь между объектами и наследование функциональности. В других случаях POP может предоставить более гибкую и модульную организацию кода с помощью протоколов и композиции. Apple транслирует в своих библиотеках именно POP, поэтому при разработке приложений на Swift он используется чаще.
#interview #swift #ios
И так, продолжаю рубрику - батл #versus
Объектно-ориентированное программирование (ООП) и протокольно-ориентированное программирование (POP) представляют различные подходы к структурированию и проектированию кода. Вот некоторые сходства и различия между ними, которые стоит упоминуть, отвечая на такой вопрос:
Сходства:
✅ Оба подхода стремятся к абстракции и моделированию реального мира с помощью объектов и их взаимодействия.
✅ И ООП, и POP позволяют использовать полиморфизм для работы с разными типами данных, обрабатывая их через общий интерфейс.
✅ Оба подхода поддерживают концепцию инкапсуляции, позволяющую скрыть внутренние детали реализации и предоставить доступ только к необходимой функциональности.
Различия:
⚠️ ООП сосредоточено на использовании классов и наследования для организации кода. Классы могут наследовать свойства и методы от других классов и создавать иерархию наследования. В POP используются протоколы вместо классов для определения требований к функциональности.
⚠️ Наследование, может привести к сложным иерархиям классов и проблемам с тесной связностью. В особенности, множественного наследования (отсутствует в Swift). В POP используется композиция, где типы состоят из более специализированных компонентов через соответствие (conform) протоколам, обеспечивая более гибкую и модульную организацию кода.
⚠️ В ООП функциональность определяется внутри классов и их методов. В POP функциональность определяется через протоколы. Протоколы могут иметь требования к методам и свойствам, и типы должны реализовать эти требования.
⚠️ В POP протоколы позволяют использовать расширения протоколов для предоставления реализации методов по умолчанию. Это делает код более гибким и легким для расширения новыми функциями или высичляемыми свойствами. В ООП расширение функциональности класса может быть достигнуто через наследование или создание подклассов.
Какой подход выбрать зависит от требований и конкретной ситуации. В некоторых случаях ООП может быть предпочтительным, особенно если требуется сильная связь между объектами и наследование функциональности. В других случаях POP может предоставить более гибкую и модульную организацию кода с помощью протоколов и композиции. Apple транслирует в своих библиотеках именно POP, поэтому при разработке приложений на Swift он используется чаще.
#interview #swift #ios
SwiftData
Посмотрел я значит все сессии по SwiftData. Подумал, надо набросать статью обзор-перевод этих сессий и провести немного эксперементов с нововедениями и миграцию с CoreData. Но вчера вышла статья на хабре, которая на мой взгляд, покрывает все о чем я хотел написать)
Досадно немного, но зато сэкономил себе пару часов времени.
https://habr.com/ru/companies/surfstudio/articles/742696/
Ссылки на сессии по SwiftData с WWDC23:
• Meet SwiftData
• Build an app with SwiftData
• Model your schema with SwiftData
• Migrate to SwiftData
• Dive deeper into SwiftData
UPD: Если кто-то может подкинуть еще интересных сессий напишите в комменты
#ios #swift
Посмотрел я значит все сессии по SwiftData. Подумал, надо набросать статью обзор-перевод этих сессий и провести немного эксперементов с нововедениями и миграцию с CoreData. Но вчера вышла статья на хабре, которая на мой взгляд, покрывает все о чем я хотел написать)
Досадно немного, но зато сэкономил себе пару часов времени.
https://habr.com/ru/companies/surfstudio/articles/742696/
Ссылки на сессии по SwiftData с WWDC23:
• Meet SwiftData
• Build an app with SwiftData
• Model your schema with SwiftData
• Migrate to SwiftData
• Dive deeper into SwiftData
UPD: Если кто-то может подкинуть еще интересных сессий напишите в комменты
#ios #swift
Хабр
На смену CoreData пришёл новый фреймворк SwiftData. Разбираемся, как он упрощает хранение данных
Фреймворк для хранения данных Core Data был написан еще во времена Objective-C. Многим iOS-разработчикам хотелось иметь более современный инструмент, который бы поддерживал все новые возможности языка...
Многопоточность
Часто такие примеры встречаются на собеседовании. Нужно ответить в каком порядке будут выведены цифры в консоль.
Проверим ваши знания и внимательность.
UPD: Изначально скрин был неправильный, сорри)
#interview #ios #swift
Часто такие примеры встречаются на собеседовании. Нужно ответить в каком порядке будут выведены цифры в консоль.
Проверим ваши знания и внимательность.
UPD: Изначально скрин был неправильный, сорри)
#interview #ios #swift
Capture list 🤔
Сегодня разберем еще один классический вопрос с ios собеседований. Необходимо понять, что будет выведено в консоль.
Начем с самого простого. Переменная cityClass в пункте 4 меняет свое значение поля name. Т.к классы относятся к reference type, то захват в capture list никак не повлияет на итоговое значение. В консоле мы увидем в обоих случаях "Liverpool".
Переменная cityStruct - cтруктура, поэтому в первом замыкании она будет скопирована при захвате в capture list, а во втором обращение произойдет в момент выполнения замыкания к уже обновленной переменной. Поэтому "London" и "Marseille" соответственно.
Последний случай может показаться самым неочевидным. Переменная cityClassOptional захватывается в первом замыкании по слабой ссылке. В пункте 4 сначала создается еще один указатель на cityClassOptional, а потом заниляется. В замыкании closure1 будет выведено Paris - счетчик ссылок у объекта еще не равен нулю (doubleClass удерживает объект по сильной ссылке), а вот closure2 обратится по указателю уже к пустому значению.
Как итог, вывод в консоль будет выглядеть следующим образом:
1 - my city is Liverpool
2 - my city is London
3 - my city is Paris
4 - my city is Liverpool
5 - my city is Marseille
6 - my city is nil
А что произойдет если применить weak к переменной с типом структуры? К счастью, компилятор поможет понять, что такое действие недопустимо. ARC не применим к Value Types
'weak' may only be applied to class and class-bound protocol types
#interview #ios #swift
Сегодня разберем еще один классический вопрос с ios собеседований. Необходимо понять, что будет выведено в консоль.
Начем с самого простого. Переменная cityClass в пункте 4 меняет свое значение поля name. Т.к классы относятся к reference type, то захват в capture list никак не повлияет на итоговое значение. В консоле мы увидем в обоих случаях "Liverpool".
Переменная cityStruct - cтруктура, поэтому в первом замыкании она будет скопирована при захвате в capture list, а во втором обращение произойдет в момент выполнения замыкания к уже обновленной переменной. Поэтому "London" и "Marseille" соответственно.
Последний случай может показаться самым неочевидным. Переменная cityClassOptional захватывается в первом замыкании по слабой ссылке. В пункте 4 сначала создается еще один указатель на cityClassOptional, а потом заниляется. В замыкании closure1 будет выведено Paris - счетчик ссылок у объекта еще не равен нулю (doubleClass удерживает объект по сильной ссылке), а вот closure2 обратится по указателю уже к пустому значению.
Как итог, вывод в консоль будет выглядеть следующим образом:
1 - my city is Liverpool
2 - my city is London
3 - my city is Paris
4 - my city is Liverpool
5 - my city is Marseille
6 - my city is nil
А что произойдет если применить weak к переменной с типом структуры? К счастью, компилятор поможет понять, что такое действие недопустимо. ARC не применим к Value Types
'weak' may only be applied to class and class-bound protocol types
#interview #ios #swift
Please open Telegram to view this post
VIEW IN TELEGRAM
Method dispatch
Про то, как устроена диспетчеризация методов в Swift написано не мало, поэтому я не хочу повторяться в пересказе. Детально погрузиться или повторить все аспекты, предлагаю за просмотром видео Swift Mehtod Dispatch. Статей, где подробно объясняется зачем и почему в Swift сосуществуют различные типы нахождения и вызовов методом предостаточно, например, вот. Вообще говоря, большого прикладного применения я в этом не вижу, но понимать базово все же стоит.
Разберем несколько "tricky" примеров-вопросов с собеседований, которые могут действительно застать врасплох.
На первом скрине, у нас есть вызов метода сначала у структуры, а затем у структуры приведенной к протоколу. В случае если метод определен только в расширении протокола, мы получим ответы:
// In Struct
// In Protocol
Будет использована Static dispatch для метода из расширения протокола.
Если же мы добавим метод и в объявление протокола, то будет применен Witness table (скрин 2) и ответ станет:
// In Struct
// In Struct
На третьем скрине ситуация посложнее. Метод определен в протоколе и в его расширении. Есть класс B, который реализует протокол, но не перегружает метод из него. И есть класс С потомок класса B и переопределенный метод из протокола P. При вызове метода у класса С приведенного к протоколу, логично предполагать, что будет вызван переопределенный метод из класса С, но мы получаем вызов метода из расширения протокола 🤯.
Баг открыт много лет и пока не был поправлен. Собственно, как можно его закостылись смотреть там же)
#ios #swift #interview
Про то, как устроена диспетчеризация методов в Swift написано не мало, поэтому я не хочу повторяться в пересказе. Детально погрузиться или повторить все аспекты, предлагаю за просмотром видео Swift Mehtod Dispatch. Статей, где подробно объясняется зачем и почему в Swift сосуществуют различные типы нахождения и вызовов методом предостаточно, например, вот. Вообще говоря, большого прикладного применения я в этом не вижу, но понимать базово все же стоит.
Разберем несколько "tricky" примеров-вопросов с собеседований, которые могут действительно застать врасплох.
На первом скрине, у нас есть вызов метода сначала у структуры, а затем у структуры приведенной к протоколу. В случае если метод определен только в расширении протокола, мы получим ответы:
// In Struct
// In Protocol
Будет использована Static dispatch для метода из расширения протокола.
Если же мы добавим метод и в объявление протокола, то будет применен Witness table (скрин 2) и ответ станет:
// In Struct
// In Struct
На третьем скрине ситуация посложнее. Метод определен в протоколе и в его расширении. Есть класс B, который реализует протокол, но не перегружает метод из него. И есть класс С потомок класса B и переопределенный метод из протокола P. При вызове метода у класса С приведенного к протоколу, логично предполагать, что будет вызван переопределенный метод из класса С, но мы получаем вызов метода из расширения протокола 🤯.
Баг открыт много лет и пока не был поправлен. Собственно, как можно его закостылись смотреть там же)
#ios #swift #interview
Swift for Algorithm 👌
Swift - классный язык программирования, но он не очень удобен при решения алгоритмических задач на собеседованиях. Я не владею, на должном уровне, другими языками, поэтому выбора нет.
На алгоритмических секциях отводится ограниченное количество времени на решение задачи, обычно 30-50 минут, за это время нужно понять что от тебя хотят, придумать решение и написать его. Поэтому экономить приходится каждую минуту.
Хочу обратить внимание на несколько хаков, которые помогли мне ускорить и повысить качество решений на интервью в такие компании, как Yandex, Bloomberg и AliExpress.
1. Работа со строками
В Swift это какая-то мутота. Мы не можем спокойно обратиться по порядковому номеру символа в строке и получить объект типа Character. Нужно создавать объект типа String.Index и работать с ним.
⛔️
let myString = "Hello, Swift!"
let index = myString.index(myString.startIndex, offsetBy: 7)
let characterAtIndex = myString[index]
print(characterAtIndex) // "S"
Мне больше нравится работать со строкой, как обычным массивом. У меня это получается лаконичней и быстрее. Но уточните насколько критично для решения выделение доп памяти под новый массив. Например, на собеседовании в Яндексе такой прием был допустим и интервьюер согласился, что работа со строками не сильно место в Swift)
❇️
let collectionOfCharacters = Array(myString)
let characterAtIndex = collectionOfCharacters[7]
print(characterAtIndex) // "S"
2. Сложность стандартных операций
Системные методы могут работать не так, как мы предполагаем. Был случай, что я неправильно оценил сложность алгоритма, потому что не учел сложность метода removeAll у коллекций. В документации сказано, она О(n) я подумал, что константная. ⛔️
❇️ array = [] - решает проблему выше.
3. Сигнатура метода
Обычно алгоритмические задачи предполагают написание одного метода. Прежде чем ее решать нужно выяснить все требования. Часть из них можно поместить сразу в параметры (при условии, что вы пишите все с чистого листа без шаблона, как на LeetCode).
Допустим в задаче есть двумерный массив, тогда метод может выглядеть следующим образом:
⛔️
func testMethod(array: [[Int]]) -> Int {
let n = array.count
let m = array[0].count
...
}
Но можно лучше и вам уже не придется высчитывать границы этого массива:
❇️
func testMethod(array: [[Int]], n: Int, m: Int) -> Int { … }
На первый взгляд мелочь, но когда у вас жесткий дедлай и волнение, даже в таких мелочах можно лажануть)
4. Функции высшего порядка
Ну это база. Допустим есть массив целых чисел, нужно найти сумму всех элементов.
var numbers = [0, 1, 2, 3]
⛔️
var sum = 0
for number in numbers {
sum += number
}
print(sum)
❇️
let sumFast = numbers.reduce(0, +)
print(sumFast)
Кода меньше, пишется быстрее - профит. Map, filter, compactMap, reduce и forEach пригодятся в 80% задач на собесах.
5. Работа со словарем
Первый вариант стремный, второй православный. Тут даже не обсуждается.
var dict: [Int: Int] = [:]
⛔️
if dict[0] != nil {
dict[0]! += 1
}
❇️
dict[0, default: 0] += 1
P.S. Если интересно узнать больше об алгоритмах и собеседованих - ставьте лайки. Расскажу, как я готовился и получил предложение о работе на One day offer в Яндексе.
#swift #interview #algorithm
Swift - классный язык программирования, но он не очень удобен при решения алгоритмических задач на собеседованиях. Я не владею, на должном уровне, другими языками, поэтому выбора нет.
На алгоритмических секциях отводится ограниченное количество времени на решение задачи, обычно 30-50 минут, за это время нужно понять что от тебя хотят, придумать решение и написать его. Поэтому экономить приходится каждую минуту.
Хочу обратить внимание на несколько хаков, которые помогли мне ускорить и повысить качество решений на интервью в такие компании, как Yandex, Bloomberg и AliExpress.
1. Работа со строками
В Swift это какая-то мутота. Мы не можем спокойно обратиться по порядковому номеру символа в строке и получить объект типа Character. Нужно создавать объект типа String.Index и работать с ним.
⛔️
let myString = "Hello, Swift!"
let index = myString.index(myString.startIndex, offsetBy: 7)
let characterAtIndex = myString[index]
print(characterAtIndex) // "S"
Мне больше нравится работать со строкой, как обычным массивом. У меня это получается лаконичней и быстрее. Но уточните насколько критично для решения выделение доп памяти под новый массив. Например, на собеседовании в Яндексе такой прием был допустим и интервьюер согласился, что работа со строками не сильно место в Swift)
❇️
let collectionOfCharacters = Array(myString)
let characterAtIndex = collectionOfCharacters[7]
print(characterAtIndex) // "S"
2. Сложность стандартных операций
Системные методы могут работать не так, как мы предполагаем. Был случай, что я неправильно оценил сложность алгоритма, потому что не учел сложность метода removeAll у коллекций. В документации сказано, она О(n) я подумал, что константная. ⛔️
❇️ array = [] - решает проблему выше.
3. Сигнатура метода
Обычно алгоритмические задачи предполагают написание одного метода. Прежде чем ее решать нужно выяснить все требования. Часть из них можно поместить сразу в параметры (при условии, что вы пишите все с чистого листа без шаблона, как на LeetCode).
Допустим в задаче есть двумерный массив, тогда метод может выглядеть следующим образом:
⛔️
func testMethod(array: [[Int]]) -> Int {
let n = array.count
let m = array[0].count
...
}
Но можно лучше и вам уже не придется высчитывать границы этого массива:
❇️
func testMethod(array: [[Int]], n: Int, m: Int) -> Int { … }
На первый взгляд мелочь, но когда у вас жесткий дедлай и волнение, даже в таких мелочах можно лажануть)
4. Функции высшего порядка
Ну это база. Допустим есть массив целых чисел, нужно найти сумму всех элементов.
var numbers = [0, 1, 2, 3]
⛔️
var sum = 0
for number in numbers {
sum += number
}
print(sum)
❇️
let sumFast = numbers.reduce(0, +)
print(sumFast)
Кода меньше, пишется быстрее - профит. Map, filter, compactMap, reduce и forEach пригодятся в 80% задач на собесах.
5. Работа со словарем
Первый вариант стремный, второй православный. Тут даже не обсуждается.
var dict: [Int: Int] = [:]
⛔️
if dict[0] != nil {
dict[0]! += 1
}
❇️
dict[0, default: 0] += 1
P.S. Если интересно узнать больше об алгоритмах и собеседованих - ставьте лайки. Расскажу, как я готовился и получил предложение о работе на One day offer в Яндексе.
#swift #interview #algorithm
Please open Telegram to view this post
VIEW IN TELEGRAM
Сделал еще несколько разборов интересных задач с интервью.
➡️ Похожая задача мне попалась на интервью в австралийский Google. Я с ней справился достаточно уверенно и, думаю, было бы полезно показать решение. Если в ваших планах - получить работу в FAANG или другом big tech, то обязательно разберитесь во всех нюансах.
➡️ Еще одна задачка от Yandex. На этот вопрос по проектированию модуля отмены и возобновления отводиться 30-40 минут, поэтому допускается не идеальное решение. Главное - показать правильный ход мыслей и структурированное, логически обоснованное рассуждение.
Напоминаю, что подписчикам доступен чат для любых вопросов по урокам.
#course #ios #swift
Напоминаю, что подписчикам доступен чат для любых вопросов по урокам.
#course #ios #swift
Please open Telegram to view this post
VIEW IN TELEGRAM
Задание на дженерики 💻
В открытый доступ вышло задание на работу с дженериками. Вы сможете вспомнить или узнать, какую проблему они решают. Также можете использовать это задание на собеседовании в ваши компании. Буквально за 20-30 минут оно проверяет, как кандидат умеет писать шаблонный код.
Ссылка на разбор
#couse #swift #ios
В открытый доступ вышло задание на работу с дженериками. Вы сможете вспомнить или узнать, какую проблему они решают. Также можете использовать это задание на собеседовании в ваши компании. Буквально за 20-30 минут оно проверяет, как кандидат умеет писать шаблонный код.
Ссылка на разбор
#couse #swift #ios
boosty.to
Пятый урок. Практическая задача на дженерики - Vadim Chistiakov | IT Community
Задача позволяет проверить навыки работы с универсальными шаблонными. Также вы сможете понять, когда действительно дженерики полезны и какую проблему они решают. Это задание использовали такие компании, как Озон и Тинькофф https://pumped-day-fa6.notion.site/5…