Разбор задач квалификации: Mobile

iOS

7. Какие особенности стоит учитывать при переопределении метода - [NSObject (BOOL)respondsToSelector:(SEL)aSelector]?

  • Результат может быть закеширован системой;
  • есть особенности с вызовом super;
  • все вышеперечисленные;
  • ничего из перечисленного.

Внутри ObjC runtime система может закешировать результат предыдущего запроса к этому классу (объекту класса).

// inst is an instance of cls or a subclass thereof, or nil if none is known.
// Non-nil inst is faster in some cases. See lookUpImpOrForward() for details.
bool class_respondsToSelector_inst(Class cls, SEL sel, id inst)
{
    IMP imp;

    if (!sel  ||  !cls) return NO;

    // Avoids +initialize because it historically did so.
    // We're not returning a callable IMP anyway.
    imp = lookUpImpOrNil(cls, sel, inst, 
                         NO/*initialize*/, YES/*cache*/, YES/*resolver*/);
    return bool(imp);
}

Правильный ответ — результат может быть закеширован системой.

17. Что произойдёт с кодом?

- (void)viewDidLoad {
  UILabel *label = nil;
  @autoreleasepool {
    label = [[UILabel alloc] init];
  }
  
  __weak typeof(label) wlabel = label;
  [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self addSubview:wlabel];
  }];
}
  • Не скомпилируется;
  • произойдёт ошибка в runtime;
  • всё хорошо;
  • текст поменяется сразу.

В данной реализации self является объектом класса UIViewController, который, в свою очередь, не имеет метода:

- (void)addSubview:(UIView *)subview;

Правильный ответ — не скомпилируется.

26. Что выведется в консоли?

@interface A : NSObject
@property (nonatomic, assign, readonly) BOOL toggle;
@end

@implementation A
@end

@interface B : A
@property (nonatomic, assign) BOOL toggle;
@end

@implementation B
@dynamic toggle;

@end

int main(int argc, char * argv[]) {
    B *b = [[B alloc] init];
    b.toggle = YES;
    
    NSLog(@"%d", b.toggle);
    return 0;
}
  • 0;
  • 1;
  • ничего;
  • ошибка в runtime.

Мы перегрузили property toggle у класса B, наследника класса A, и в объявлении сказали, что у него есть setter, в отличие от класса родителя, который имеет только getter. Директива @dynamic говорит компилятору: «Верь мне, всё есть у одного из классов родителей» — и, соответственно, не генерирует ни setter, ни getter. При компиляции ошибки не будет, но в момент выполнения мы получим «unrecognized selector sent to instance».

Правильный ответ — ошибка в runtime.

27. Что выведется в консоли, если код будет запущен на iPhone X?

int main(int argc, char * argv[]) {
    int8_t matrix [2048][2048];
    NSLog(@"%d", matrix[0][0]);
    return 0;
}
  • 0;
  • ошибка компиляции;
  • ошибка в runtime;
  • undefined.

Здесь будет обычный StackOverflow, так как размер стека на главном потоке — 1 MB (см. ссылку).

Правильный ответ — ошибка в runtime.

29. Что будет выведено в консоли?

NSData *responseData = nil;

dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);

NSLog(@"A");

NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSLog(@"B");
    responseData = data;
    dispatch_group_leave(group);
}];

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"C");
  • ABC;
  • ACB;
  • CAB;
  • ошибка компиляции.

В данной ситуации блок не сможет изменять объект responseData (отсутствует модификатор __block), для более подробной информации см. ссылку.

Правильный ответ — ошибка компиляции.

34. Что будет выведено в консоль?

NS_ROOT_CLASS
@interface A
@end
@implementation A

- (void)methodSignatureForSelector:(SEL)aSelector {
    NSLog(@"%@", NSStringFromSelector(aSelector));
}

@end

int main(int argc, char * argv[]) {
    __unused NSArray *a = @[ objc_getClass("A") ];
    return 0;
}
  • Retain;
  • ошибка компиляции;
  • ничего;
  • isProxy.

Мы создали новый рутовый класс в ObjC, который не имеет никаких методов, в отличие от NSProxy или NSObject.

Далее, при инициализации массива нашему объекту автоматически будет послано сообщение retain, и так как такой метод не был определён, ObjC попытается осуществить стандартный механизм method forwarding.

Правильный ответ — retain.

Android

6. Что будет, если вызвать метод start() два раза у одного и того же объекта Thread?

  • Два раза выполнится run() в двух разных потоках;
  • два раза выполнится run() в одном потоке;
  • один раз выполнится run();
  • будет выброшен exception.

Нельзя вызывать у класса Thread метод start() несколько раз.

Можно прочитать про это в документации к классу: «@throws IllegalThreadStateException — if this thread has already started».

Правильный ответ — будет выброшен exception.

7. Почему плохо использовать вложенные LinearLayout с не нулевыми layout_weight?

  • Это приведёт к экспоненциальному росту числа измерений Layout;
  • это удвоит число измерений Layout;
  • это приведёт к StackOverflowException;
  • нет причин.

Прочитать про оптимизацию иерархии Layouts приложения можно в документации: https://developer.android.com/training/improving-layouts/optimizing-layout.html.

Правильный ответ — это приведёт к экспоненциальному росту числа измерений Layout.

8. Какой стандартный элемент Android может использоваться без создания Application?

  • Activity;
  • Service;
  • ContentProvider;
  • все вышеперечисленные.

Обращение к ContentProvider через ContentResolver — синхронная операция и может быть выполнена из одного приложения к другому. Поэтому её нужно выполнять как можно быстрее. И в случае, если процесс второго приложения не запущен, Android так спроектирован, что onCreate ContentProvider вызывается до onCreate Application.

Прочитать про устройство ContentProvider можно в документации (https://developer.android.com/reference/android/content/ContentProvider) и в исходном коде AOSP, например в ActivityManagerServicer#getContentProviderImpl, ActivityThread#installContentProviders, ContentProvider#attachInfo.

Правильный ответ — ContentProvider.

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

  • implementation;
  • api;
  • compile;
  • все вышеперечисленные.

Почитать про подключение модулей в Gradle можно в документации:

https://docs.gradle.org/current/userguide/dependency_management_terminology.html.

Правильный ответ — api.

12. Какой результат работы кода:

int f() {
    try {
        return 0;
    } finally {
        return 1;
    }
}
  • 1;
  • 0;
  • Compilation error;
  • Runtime exception.

Блок finally всегда выполняется после блока try. И, соответственно, в байткоде логика возврата значения функции будет выполнена в самом конце.

Правильный ответ — 1.

2296 views·8 shares