JavaRush /Java блогы /Random-KK /Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары. ...
Roman Beekeeper
Деңгей

Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары. 2-бөлім

Топта жарияланған
Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары. 1 бөлім Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  2 - 1 бөлім

Жинақтар

25. Java тіліндегі коллекциялар нені білдіреді?

Коллекция - бұл an objectілерді сақтауға және өңдеуге арналған құрылым. Келесі операцияларды орындау үшін қолданылады:
  • іздеу;
  • сұрыптау;
  • манипуляция;
  • қосу;
  • жою.
Коллекция құрылымына арналған барлық сыныптар мен интерфейстер java.utilбумада бар.

26. Collection фреймворкінде қандай класстар мен интерфейстер бар?

Интерфейстер:
  • Коллекция;
  • Тізім;
  • Жиын;
  • Карта;
  • Сұрыпталған жиын;
  • Сұрыпталған карта;
  • Кезек.
Сабақтар:
  • Тізімдер:
    1. ArrayList;
    2. LinkedList;
    3. Вектор (ескірген).
  • Жиындар:
    1. HashSet;
    2. LinkedHashSet;
    3. Tree Set.
  • Карталар:
    1. HashMap
    2. TreeMap
    3. HashTable (ескірген)
    4. LinkedHashMap
  • Кезек
    1. Басымдық кезек.

27. Жинақтарда сұрыпталған және реттелген деп нені айтады?

Тапсырыс берілді:

Бұл жинақта сақталған элементтер жинаққа қосылған мәндерге негізделгенін білдіреді. Осылайша біз жинақтағы мәндерді белгілі бір ретпен қайталай аламыз. Басқаша айтқанда, бұл коллекция элементтерінің өздеріне сәйкес орналасатын белгілі бір реті бар екенін білдіреді. Жақсырақ түсіну үшін ретсіз жинақ өз элементтерін кездейсоқ ретпен сақтайды. Мысалы, Set.

Сұрыпталған:

Бұл элементтер тобы жинақ элементінің деректері негізінде жинаққа сұрыпталғанын білдіреді. Яғни коллекция реттелген ғана емес, элементтердің реті де олардың мәндеріне байланысты. Басқа элемент мәні бойынша сұрыптасаңыз, бұл тәртіп өзгеруі мүмкін.

28. List интерфейсі бар қандай жинақтар бар? Тізіммен қалай жұмыс істейсіз?

Парақтағы элементтердің мәндері олардың индексіне негізделген - олар индекс бойынша реттелген. Элементтердің қайталануына рұқсат етіледі (яғни, бір нысанды жинаққа бірнеше рет қосуға болады және ол жақсы болады).

Массивтер тізімі:

Ең көп таралған жинақ. Негізінде бұл динамикалық түрде кеңейетін өлшемі бар массив. Массив өлшемін басқару жұмысы жинаққа байланысты. Біз үшін көп жағдайда осыны пайдалануымыз керек екенін түсіну маңызды. Ерекшеліктер:
  • жылдам іздеу және индексті жылдам іздеу;
  • жинақ индекс бойынша реттелген, бірақ сұрыпталмаған;
  • RandomAccess интерфейсін жүзеге асырады;
  • тізімнің ортасына біртіндеп қосылады.
Мысалы:
public class A {

   public static void main(String[] args) {
       ArrayList names = new ArrayList<>();
       names.add("John");
       names.add("John");
       names.add("Roman");
       names.add("Ivan");
   }

}
>> шығару

   [John, John, Roman, Ivan]
Шығару бұл қайталанатын элементтер екенін көрсетеді. Олар жазылған ретпен көрсетіледі. Тағы не оқу керек? Иә, ақпарат өте көп, JavaRush-тен шығудың қажеті жоқ:

Байланыстырылған тізім:

Бұл әрбір элементтің алдыңғы және келесі элементтерге сілтемесі бар жинақ. Бұл сілтемелер бір элементтен екіншісіне өтуге мүмкіндік береді. Элемент қосқан кезде алдыңғы және келесі элементтерге сілтемелер жай ғана өзгереді: Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  2 - 2 бөлім
  • элементтер бір-бірімен байланысқан, яғни қосарланған тізім жүзеге асады;
  • жұмыстың жалпы жылдамдығы ArrayList-ке қарағанда айтарлықтай төмен;
  • массивтің ортасына көптеген кірістірулер мен жоюлар үшін тамаша таңдау;
  • Queue және Deque тізімі интерфейстерін жүзеге асырады, сондықтан олардың жұмыс істеу әдістері бар.
Мысалы:
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("One");
linkedList.add("Two");
linkedList.add("Three");

29. Карта жинағы және оны жүзеге асыру туралы айтып беріңізші?

Карта – кілттер жиынтығы. Бірегей кілт және сол мәнге сәйкес мән бар. Әдістер кілттің бірегейлігін анықтау үшін equals()де қолданылады .hashcode()

HashMap:

  • сұрыпталмаған немесе реттелмеген;
  • тәртіп пен сұрыптау маңызды болмаса қолданылады;
  • нөлдік кілтті қолдайды.
Мысалы:
public class CollectionExample {

   public static void main(String[] args) {
       HashMap positions = new HashMap<>();
       positions.put("junior", "Ivan");
       positions.put("middle", "Roman");
       positions.put("senior", "Vasily");
       positions.put("team lead", "Anton");
       positions.put("arthitect", "Andrew");
       positions.put("senior", "John");
       System.out.println(positions);
   }
}

// вывод в консоль
// {junior=Ivan, middle=Roman, senior=John, team lead=Anton, arthitect=Andrew}
Кілттер әрқашан бірегей, сондықтан тек бір аға жазылады.

LinkedHashMap:

  • енгізу тәртібін сақтайды;
  • HashMap қарағанда баяу;
  • Итерация HashMap-ке қарағанда жылдамырақ болады деп күтілуде.
Мысалы:
public class CollectionExample {

   public static void main(String[] args) {
       LinkedHashMap<String, String> positions = new LinkedHashMap<>();
       positions.put("junior", "Ivan");
       positions.put("middle", "Roman");
       positions.put("senior", "Vasily");
       positions.put("team lead", "Anton");
       positions.put("arthitect", "Andrew");
       positions.put("senior", "John");
       System.out.println(positions);
   }
}

// вывод в консоль
// {junior=Ivan, middle=Roman, senior=John, team lead=Anton, arthitect=Andrew}

Ағаш картасы:

Кілттердің табиғи ретіне сәйкес сұрыпталған жазбаларды сақтайтын картаны іске асыру немесе карта жасалған кезде конструкторда қамтамасыз етілсе, салыстыру құралын пайдалану. Мысалы:
  1. Салыстырғышсыз

    public class CollectionExample {
    
       public static void main(String[] args) {
           TreeMap<Integer, String> positions = new TreeMap<>();
           positions.put(1, "Ivan");
           positions.put(3, "Roman");
           positions.put(2, "Vasily");
           positions.put(10, "Anton");
           positions.put(7, "Andrew");
           positions.put(1, "John");
           System.out.println(positions);
       }
    }
    
    // вывод в консоль
    // {1=John, 2=Vasily, 3=Roman, 7=Andrew, 10=Anton}
  2. Салыстырғышпен

    public class CollectionExample {
    
       public static void main(String[] args) {
           //используем реализацию Strategy Pattern'a и добавим компаратор:
           TreeMap<Integer, String> positions = new TreeMap<>(Comparator.reverseOrder());
           positions.put(1, "Ivan");
           positions.put(3, "Roman");
           positions.put(2, "Vasily");
           positions.put(10, "Anton");
           positions.put(7, "Andrew");
           positions.put(1, "John");
           System.out.println(positions);
       }
    }
    
    // вывод в консоль
    // {10=Anton, 7=Andrew, 3=Roman, 2=Vasily, 1=John}
Біз өсу реті бойынша сұрыптау стандарт ретінде жүзеге асырылатынын көреміз, бірақ оны конструкторға компаратор қосу арқылы өзгертуге болады. TreeMap мұнда жақсы сипатталған .

30. Set жинағы және оны жүзеге асыру туралы айтып беріңізші?

Жиын – бірегей элементтердің жиынтығы және бұл оның басты ерекшелігі. Яғни, Set бірдей элементтерді қайталауға мүмкіндік бермейді. Бұл жерде қосылған нысандардың іске асырылған әдісі болуы маңызды equals .

Хэштер жинағы:

  • сұрыпталмаған немесе реттелген емес. Сорғыштың астында мәнге арналған толтырғышы бар HashMap бар. Өзіңіз қараңыз;)
  • нысандарды қосу үшін hashCode пайдаланады;
  • Ол бірегей нысандарға ие болу қажет болғанда және олардың реті маңызды емес болғанда қолданылуы керек.
Мысалы:
public class CollectionExample {

   public static void main(String[] args) {
       HashSet<String> positions = new HashSet<>();
       positions.add("junior");
       positions.add("junior");
       positions.add("middle");
       positions.add("senior");
       positions.add("team lead");
       positions.add("architect");
       System.out.println(positions);
   }
}

// вывод в консоль
// [senior, middle, team lead, architect, junior]
Мұнда екі рет қосылған «кіші» элемент тек бір данада ғана бар екенін көруге болады. Ал реті қосу кезіндегідей емес.

LinkedHashSet:

  • HashSet-тің реттелген нұсқасы;
  • барлық элементтер үшін қосарланған байланыстырылған тізімді жүргізеді;
  • Итерацияда тәртіп қажет болғанда пайдаланыңыз.
Мысалы:
public class CollectionExample {

   public static void main(String[] args) {
       LinkedHashSet<String> positions = new LinkedHashSet<>();
       positions.add("junior");
       positions.add("junior");
       positions.add("middle");
       positions.add("senior");
       positions.add("team lead");
       positions.add("architect");
       System.out.println(positions);
   }
}

// вывод в консоль
// [senior, middle, team lead, architect, junior]

Ағаштар жиынтығы:

  • сұрыпталған екі жинақтың бірі;
  • қызыл-қара ағаш құрылымын қолданады және элементтердің өсу ретімен орналасуын қамтамасыз етеді;
  • Сорғыштың астында бұл мәндер бойынша кесіндісі бар TreeMap. Ал TreeSet элементтері TreeMap кілттері болып табылады (сонымен қатар қараңыз;)).
Мысалы:
public class CollectionExample {

   public static void main(String[] args) {
       TreeSet<String> positions = new TreeSet<>();
       positions.add("junior");
       positions.add("junior");
       positions.add("middle");
       positions.add("senior");
       positions.add("team lead");
       positions.add("architect");
       System.out.println(positions);
   }
}

// вывод в консоль
// [architect, junior, middle, senior, team lead]

Ерекшеліктер

31. Ерекшелік дегеніміз не?

Ерекшелік - орындалу уақытында орын алуы мүмкін мәселе. Бұл қандай да бір себептермен туындайтын ерекше жағдай. Ерекшеліктің мұрагерлік диаграммасы келесідей көрінеді (оны жатқа білу керек ;)): Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  2 - 3 бөлімДиаграмма жалпы алғанда барлық ерекшеліктер екі топқа бөлінгенін көрсетеді - ерекшеліктер және қате. Қате - JVM қолданбасы енді мағынасы жоқ қателерді көрсету үшін пайдаланылады. Мысалы, StackOverFlowError, ол стек толы және бағдарлама енді жұмыс істей алмайтынын айтады. Ерекшелік - codeта бағдарламалық түрде жасалған ерекшеліктер. Әртүрлі ерекшеліктер бар, тексерілген және белгіленбеген, бірақ ең бастысы - олар бар және оларды ұстап алуға болады және қолданба жұмысын жалғастыра алады. Ерекшеліктер, өз кезегінде, RuntimeException және Ерекшеліктің басқа ұрпақтарынан мұра алатындарға бөлінеді. Бұл мәселе бойынша ақпарат жеткілікті. Төменде белгіленген/белгіленбеген ерекшеліктер туралы айтатын боламыз.

32. JVM ерекше жағдайларды қалай өңдейді?

Бұл қалай жұмыс істейді? Ерекшелік бір жерге тасталса, орындалу уақыты Ерекшелік нысанын жасайды (ExcObj ретінде белгіленеді). Ол жұмыс үшін қажетті барлық ақпаратты сақтайды - лақтырылған ерекшелік және оның болған жері. Орындау уақытына құру ExcObjжәне жіберу «ерекшелік тастаудан» басқа ештеңе емес. ExcObjерекшелік жойылған жерге жету үшін қолданылатын әдістерді қамтиды. Бұл әдістер жиынтығы Call Stack деп аталады. Әрі қарай, орындалу уақыты жүйесі ерекше жағдайды өңдей алатын Қоңыраулар стекіндегі әдісті іздейді. Егер ол сәйкес өңдегішті тапса, яғни ерекше жағдай түрі өңдегіштегі түрге сәйкес келсе, бәрі жақсы. Егер ол оны таппаса, орындау уақыты барлығын жауап дайындап, шығатын әдепкі ерекшелік өңдеушісіне береді. Мынадай көрінеді:
/**
* Пример, в котором показываются две опции — когда находится обработчик для исключения и когда нет.
*/
class ThrowerExceptionExample {

   public static void main(String[] args) throws IllegalAccessException {

       ThrowerExceptionExample example = new ThrowerExceptionExample();

       System.out.println(example.populateString());
   }

   /**
    * Здесь происходит перехват одного из возможных исключений — {@link IOException}.
    * А вот второй будет пробрасываться дальше вверх по вызову.
    */
   private String populateString() throws IllegalAccessException {
       try {
           return randomThrower();
       } catch (IOException e) {
           return "Caught IOException";
       }
   }

   /**
    * Здесь две опции: or бросается {@link IOException} or {@link IllegalAccessException}.
    * Выбирается случайным образом.
    */
   private String randomThrower() throws IOException, IllegalAccessException {
       if (new Random().nextBoolean()) {
           throw new IOException();
       } else {
           throw new IllegalAccessException();
       }
   }
}
Біздің жағдайда CallStack схемалық түрде келесідей болады:

randomThrower() => populateString() => main(String[] args)
Екі нұсқа бар: бір немесе басқа ерекшелік кездейсоқ тасталады. IOException үшін бәрі жақсы, егер ол жасалса, жұмыс нәтижесі келесідей болады: "Caught IOException". Бірақ өңдеушісі жоқ екінші ерекшелік болса, бағдарлама келесі нәтижемен тоқтайды:

Exception in thread "main" java.lang.IllegalAccessException
  at ThrowerExceptionExample.randomThrower(CollectionExample.java:38)
  at ThrowerExceptionExample.populateString(CollectionExample.java:24)
  at ThrowerExceptionExample.main(CollectionExample.java:15)

33. Бағдарламашылар ерекше жағдайларды қалай өңдейді?

Жоғарыдағы сұрақтарда кейбір кілт сөздер ерекше жағдайлармен жұмыс істеу үшін қолданылған, енді олар туралы толығырақ айту керек. Негізгі сөздер қандай?
  • тырысу
  • ұстау
  • лақтыру
  • лақтырады
  • ақырында
Ұстау, лақтыру және лақтыру әрекеттерін тек java.lang.Throwable арқылы пайдалануға болатынын ескеру маңызды. Бұл басқа түрлермен жұмыс істемейді. Енді біз көріңіз, ұстаңыз және соңында талқылаймыз.
  • try-catch-finallyерекше жағдайды дұрыс ұстауға және өңдеуге мүмкіндік беретін конструкция болып табылады.
  • try- бір ғана уақыт болуы мүмкін, логика дәл осы жерде болады;
  • catch— қандай да бір ерекшелік түрін алатын блок; олардың көпшілігі болуы мүмкін. Мысалы, try блогы бір-бірімен ешқандай қатысы жоқ бірнеше ерекшеліктерді шығарады;
  • finally- «ақырында» бұл блок. Бұл try, catch-те не жасалғанына қарамастан, кез келген жағдайда орындалатын блок.
Мынадай көрінеді:
try {
   // сюда передают тот code, который может вызвать исключение.
} catch (IOException e) {
   // первый catch блок, который принимает IOException и все его подтипы(потомки).
   // Например, нет file при чтении, выпадает FileNotFoundException, и мы уже соответствующе
   // обрабатываем это.
} catch (IllegalAccessException e) {
   // если нужно, можно добавить больше одного catch блока, в этом нет проблем.
} catch (OneException | TwoException e) {
   // можно даже объединять несколько в один блок
} catch (Throwable t) {
   // а можно сказать, что мы принимаем ВСЁ))))
} finally {
   // этот блок может быть, а может и не быть.
   // и он точно выполнится.
}
Мысалдың сипаттамасын мұқият оқып шығыңыз және бәрі түсінікті болады)

34. Java-да лақтыру және тастау

лақтыру

throwжаңа ерекше жағдайды нақты жасау қажет болғанда пайдаланылады. Ол теңшелетін ерекше жағдайларды жасау және шығару үшін пайдаланылады. Мысалы, валидацияға қатысты ерекшеліктер. Әдетте, тексеру үшін олар мұраға алады RuntimeException. Мысалы:
// пример пробрасывания исключения
throw new RuntimeException("because I can :D");
Бұл құрылысты тек мұраға қалдыратын нәрсе ғана пайдалана алатыны маңызды Throwable. Яғни, сіз мұны айта алмайсыз:
throw new String("How тебе такое, Илон Маск?");
Содан кейін ағынның жұмысы тоқтатылады және оны өңдей алатын өңдеуші іздеу басталады. Ол оны таппаған кезде, ол оны шақырған әдіске өтеді, осылайша іздеу сәйкес өңдеушіні тапқанша немесе қолданбаны жұмыс істеп тұрған күйде қалдырмайынша қоңыраулар жолына көтеріледі. Қарап көрейік:
// Пример, который демонстрирует работу throw
class ThrowExample {

   void willThrow() throws IOException {
       throw new IOException("Because I Can!");
   }

   void doSomething() {
       System.out.println("Doing something");
       try {
           willThrow();
       } catch (IOException e) {
           System.out.println("IOException was successfully handled.");
       }
   }

   public static void main(String args[]) {
       ThrowExample throwExample = new ThrowExample();
       throwExample.doSomething();
   }
}
Бағдарламаны іске қоссақ, келесі нәтиже аламыз:

Doing something
IOException was successfully handled.

лақтырады

throws— әдіс бір немесе бірнеше ерекшеліктерді шығара алатын механизм. Олар үтір арқылы қосылады. Мұның қаншалықты оңай және қарапайым екенін көрейік:
private Object willThrow() throws RuntimeException, IOException, FileNotFoundException
Сонымен қатар, тексерілген және белгіленбеген ерекше жағдайлардың болуы мүмкін екенін ескеру маңызды. Әрине, белгіленбеген ерекшеліктер -ге қосылмауы мүмкін throws, бірақ әдептілік басқаша айтады. Егер бұл тексерілетін болса, оларды жасайтын әдісті пайдаланып, оны қандай да бір жолмен өңдеу керек. Екі нұсқа бар:
  1. try-catchСәйкес және жоғарыдағы мұралық ерекшелікпен жазыңыз .
  2. Басқа біреуде бұл мәселе бұрыннан бар болуы үшін оны throwsдәл солай пайдаланыңыз: D

35. Java тіліндегі тексерілген және белгіленбеген ерекшеліктер

Java-да ерекше жағдайлардың екі түрі бар - тексерілген және белгіленбеген.

Тексерілген ерекшеліктер:

Бұл компиляция уақытында тексерілетін ерекшеліктер. Әдістегі кейбір code ерекшелік кезінде тексерілген ерекшелікті шығарса, әдіс оны пайдаланып өңдеуі try-catchнемесе оны әрі қарай жіберуі керек. Мысалы, "/users/romankh3/image.png" жолынан суретті оқитын, оны жаңартады. қандай да бір жолмен (біз үшін бұл маңызды емес) және оны қайтадан сақтайды.
class CheckedImageExample {
   public static void main(String[] args) {
       File imageFile = new File("/users/romankh3/image.png");
       BufferedImage image = ImageIO.read(imageFile);
       updateAndSaveImage(image, imageFile);
   }

   private static void updateAndSaveImage(BufferedImage image, File imageFile) {
       ImageIO.write(image, "png", imageFile);
   }
}
Мұндай code компиляцияланбайды, өйткені статикалық әдістер тексерілетін және тиісінше өңделуі керек IOException ImageIO.read()жібереді . ImageIO.write()Мұнда біз жоғарыда талқылаған екі нұсқа бар: не пайдаланыңыз try-catch, не әрі қарай жалғастырыңыз. Жақсырақ ассимиляциялау үшін біз мұны және мұны істейміз. Яғни, updateAndSaveбіз оны тек әдісте жібереміз, содан кейін оны негізгі әдісте қолданамыз try-catch:
class CheckedImageExample {
   public static void main(String[] args) {
       File imageFile = new File("/users/romankh3/image.png");
       try {
           BufferedImage image = ImageIO.read(imageFile);
           updateAndSaveImage(image, imageFile);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   private static void updateAndSaveImage(BufferedImage image, File imageFile) throws IOException {
       ImageIO.write(image, "png", imageFile);
   }
}

Тексерілмеген ерекшеліктер:

Бұл құрастыру сатысында тексерілмейтін ерекшеліктер. Яғни, әдіс RuntimeException жасай алады, бірақ компилятор оны қандай да бір жолмен өңдеуді еске салмайды. Төменде көрсетілгендей, бізде RuntimeException мұрағатының бәрі бар және Қате құсбелгісіз. Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  2 - 4 бөлімКелесі Java бағдарламасын қарастырыңыз. Код жақсы құрастырылады, бірақ іске қосылғанда ерекше жағдайды шығарады ArrayIndexOutOfBoundsException. Компилятор оны компиляциялауға мүмкіндік береді, себебі ArrayIndexOutOfBoundsExceptionбұл тексерілмеген ерекшелік. Массивпен жалпы жағдай, ол келесідей болуы мүмкін:
class CheckedImageExample {
   public static void main(String[] args) {
       int[] array = new int[3];
       array[5] = 12;
   }
}
Нәтиже болады:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
  at main(CheckedImageExample.java:12)
Айтпақшы, сіз Java-да ешкім қысқа есімдер бермейтінін байқадыңыз ба? Көбірек болса жақсы. Ол, Spring Framework, бұл өте сәтті болды: жай ғана BeanFactoryPostProcessor сыныбын алыңыз)))

36. Ресурстармен жұмыс істеу дегеніміз не?

Бұл барлық ресурстарды дұрыс жабу керек механизм. Бұл қандай да бір түсініксіз, солай ма?) Біріншіден, ресурс дегеніміз не... Ресурс - бұл an object, онымен жұмыс істегеннен кейін оны жабу керек, яғни close(). Ресурс интерфейсті жүзеге асыратын барлық an objectілерге жатады AutoClosable, ол өз кезегінде интерфейсті жүзеге асырады Closeable. InputStreamБіз үшін бәрі ресурс екенін түсіну маңызды OutpuStreamжәне оны дұрыс және сәтті шығару керек. try-with-resourceДәл осы себепті біз құрылымды пайдалануымыз керек . Мынадай көрінеді:
private void unzipFile(File zipFile) throws IOException {
   try(ZipInputStream zipOutputStream = new ZipInputStream(new FileInputStream(zipFile))) {
       ZipEntry zipEntry = zipOutputStream.getNextEntry();
       while (zipEntry != null) {

       }
   }
}

private void saveZipEntry(ZipEntry zipEntry) {
   // логика сохранения
}
Бұл мысалда ресурс болып табылады ZipInputStream, онымен жұмыс істегеннен кейін оны жабу керек. Ал әдісті шақыру туралы ойламау үшін close()біз мысалда көрсетілгендей бұл айнымалыны try блогында анықтаймыз және осы блоктың ішінде біз барлық қажетті нәрсені жасаймыз. Мысал не істейді? Ол zip мұрағатын ашады. Мұны істеу үшін сізге 'om пайдалану керек InputStream. Бірнеше айнымалыны анықтауға болады, олар нүктелі үтірмен бөлінген. Мәселе неде? finallyБірақ сіз блокты пайдалана аласыз , сіз айта аласыз. Міне, осы тәсілдің мәселелерін егжей-тегжейлі сипаттайтын мақала . Сондай-ақ, ол осы дизайнды қолдануға немқұрайлы қараған адамның басына түсуі мүмкін сәтсіздіктердің толық тізімін сипаттайды. Мен оны оқуға кеңес беремін ;) Қорытынды бөлімде Multithreading тақырыбы бойынша сұрақтар/жауаптар бар. Менің GitHub профилім
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION