JavaRush /Java блогу /Random-KY /Топ 50 Java негизги интервью суроолору жана жооптору. 3-б...
Roman Beekeeper
Деңгээл

Топ 50 Java негизги интервью суроолору жана жооптору. 3-бөлүк

Группада жарыяланган
Топ 50 Java негизги интервью суроолору жана жооптору. 1-бөлүк Java негизги 50 интервью суроолору жана жооптору. 2 бөлүк

Multithreading

37. Java тorнде жаңы жипти (агымды) кантип түзүүгө болот?

Тигил же башка жол менен түзүү Thread классын колдонуу аркылуу ишке ашат. Бирок бул жерде варианттар болушу мүмкүн...
  1. Бизден мурасjava.lang.Thread
  2. java.lang.RunnableБиз an objectиси конструктор Threadклассын кабыл алган интерфейсти ишке ашырабыз
Келгиле, алардын ар бири жөнүндө сөз кылалы.

Биз Thread классынан мураска алдык

Бул иш үчүн, биздин класста биз мурас java.lang.Thread. Анын курамында мет бар run(), бул бизге керектүү нерсе. Жаңы жиптин бүт өмүрү жана логикасы ушул ыкмада болот. Бул mainжаңы жип үчүн ыкманын бир түрү. Андан кийин, биздин класстын an objectисин түзүү жана методду аткаруу гана калды start(), ал жаңы жипти түзүп, анда жазылган логиканы иштетет. Кел карайбыз:
/**
* Пример того, How создавать треды путем наследования {@link Thread} класса.
*/
class ThreadInheritance extends Thread {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance threadInheritance1 = new ThreadInheritance();
       ThreadInheritance threadInheritance2 = new ThreadInheritance();
       ThreadInheritance threadInheritance3 = new ThreadInheritance();
       threadInheritance1.start();
       threadInheritance2.start();
       threadInheritance3.start();
   }
}
Консолдун чыгышы төмөнкүдөй болот:

Thread-1
Thread-0
Thread-2
Башкача айтканда, бул жерде да жиптер өз кезегинде эмес, JVM чечкендей аткарылганын көрөбүз)

Runnable интерфейсин ишке ашыруу

Эгерде сиз мураска каршы болсоңуз жана/же башка класстардын бирин мурастап алсаңыз, анда java.lang.Runnable. run()Бул жерде биздин класста биз бул интерфейсти ишке ашырабыз жана ошол мисалдагыдай методду ишке ашырабыз . Сиз жөн гана көбүрөөк an objectтерди түзүү керек Thread. Көбүрөөк саптар начарраак окшойт. Бирок биз тукум куучулук канчалык зыяндуу экенин жана андан ар кандай жол менен качкан жакшы экенин билебиз;) Келгиле, карап көрөлү:
/**
* Пример того, How создавать треды из интерфейса {@link Runnable}.
* Здесь проще простого - реализуем этот интерфейс и потом передаем в конструктор
* экземпляр реализуемого an object.
*/
class ThreadInheritance implements Runnable {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance runnable1 = new ThreadInheritance();
       ThreadInheritance runnable2 = new ThreadInheritance();
       ThreadInheritance runnable3 = new ThreadInheritance();

       Thread threadRunnable1 = new Thread(runnable1);
       Thread threadRunnable2 = new Thread(runnable2);
       Thread threadRunnable3 = new Thread(runnable3);

       threadRunnable1.start();
       threadRunnable2.start();
       threadRunnable3.start();
   }
}
Жана аткаруу натыйжасы:

Thread-0
Thread-1
Thread-2

38. Процесс менен жиптин айырмасы эмнеде?

Топ 50 Java негизги интервью суроолору жана жооптору.  3-1-бөлүкПроцесс менен жиптин ортосунда төмөнкүдөй айырмачылыктар бар:
  1. Аткаруудагы программа процесс деп аталат, ал эми Thread процесстин бир бөлүгү.
  2. Процесстер көз карандысыз, ал эми жиптер процесстин бир бөлүгү.
  3. Процесстердин эс тутумунда ар кандай дарек мейкиндиги бар, ал эми жиптер жалпы дарек мейкиндигин камтыйт.
  4. Контекстти которуу процесстерге салыштырмалуу жиптердин ортосунда тезирээк.
  5. Процесстер аралык байланыш тешиктер аралык байланышка караганда жайыраак жана кымбатыраак.
  6. Ата-эне процессиндеги кандайдыр бир өзгөртүүлөр бала процессине таасир этпейт, ал эми ата-эне жиптеги өзгөрүүлөр бала жипке таасир этиши мүмкүн.

39. Көп агымдын кандай артыкчылыктары бар?

Топ 50 Java негизги интервью суроолору жана жооптору.  3-2-бөлүк
  1. Multithreading тиркемеге/программага кандайдыр бир фондо тапшырмаларды аткарып жатса да, ар дайым киргизүүгө жооп берүүгө мүмкүндүк берет;
  2. Multithreading тапшырмаларды тезирээк бүтүрүүгө мүмкүндүк берет, анткени жиптер өз алдынча аткарылат;
  3. Multithreading кэштин жакшыраак пайдаланылышын камсыз кылат, анткени жиптер жалпы эс ресурстарын бөлүшөт;
  4. Multithreading талап кылынган serverдин көлөмүн азайтат, анткени бир server бир эле учурда бир нече жипти иштете алат.

40. Жиптин жашоо циклинде кандай абалдар бар?

Топ 50 Java негизги интервью суроолору жана жооптору.  3-3-бөлүк
  1. Жаңы: Бул абалда класс an objectи Threadжаңы оператордун жардамы менен түзүлөт, бирок жип жок. Биз чакырмайынча жип башталbyte start().
  2. Runnable: Бул абалда, жип методду чакыргандан кийин иштетүүгө даяр start(). Бирок, ал жип пландоочу тарабынан тандала элек.
  3. Иштеп жатат: Бул абалда, жипти пландоочу жипти даяр абалдан тандайт жана ал иштейт.
  4. Күтүү/Бөгөттөө: Бул абалда жип иштебейт, бирок дагы эле тирүү же башка жиптин бүтүшүн күтүп жатат.
  5. Өлгөн/Токтотулган: Метод чыкканда run()жип токтотулган же өлүк абалда болот.

41. Жипти эки жолу баштоого болобу?

Жок, жипти кайра баштай албайбыз, анткени жип башталып, аткарылгандан кийин, ал Өлүк абалга өтөт. Ошентип, биз жипти эки жолу иштетүүгө аракет кылсак, ал runtimeException " java.lang.IllegalThreadStateException " ыргытат . Кел карайбыз:
class DoubleStartThreadExample extends Thread {

   /**
    * Имитируем работу треда
    */
   public void run() {
	// что-то происходит. Для нас не существенно на этом этапе
   }

   /**
    * Запускаем тред дважды
    */
   public static void main(String[] args) {
       DoubleStartThreadExample doubleStartThreadExample = new DoubleStartThreadExample();
       doubleStartThreadExample.start();
       doubleStartThreadExample.start();
   }
}
Иш ошол эле жиптин экинчи башталышына жеткенде, анда өзгөчөлүк болот. Өзүңүз байкап көрүңүз;) жүз жолу уккандан көрө, бир көргөн жакшы.

42. Эгерде сиз start() ыкмасын чакырбай туруп, түздөн-түз run() ыкмасын чакырсаңызчы?

Ооба, run()албетте, сиз методду чакырсаңыз болот, бирок бул жаңы жипти түзбөйт жана аны өзүнчө жип катары аткарbyte. Бул учурда, ал жөнөкөй ыкманы чакырган жөнөкөй an object болуп саналат. Эгерде биз ыкма жөнүндө сөз кыла турган болсок start(), анда бул башка маселе. Бул ыкманы ишке киргизүү менен, runtimeал жаңысын ишке киргизет жана ал өз кезегинде биздин ыкманы иштетет;) Эгер мага ишенбесеңиз, аракет кылып көрүңүз:
class ThreadCallRunExample extends Thread {

   public void run() {
       for (int i = 0; i < 5; i++) {
           System.out.print(i);
       }
   }

   public static void main(String args[]) {
       ThreadCallRunExample runExample1 = new ThreadCallRunExample();
       ThreadCallRunExample runExample2 = new ThreadCallRunExample();

       // просто будут вызваны в потоке main два метода, один за другим.
       runExample1.run();
       runExample2.run();
   }
}
Ал эми консолго чыгуу төмөнкүдөй болот:

0123401234
Эч кандай жип түзүлбөгөнүн көрүүгө болот. Баары кадимки класстагыдай иштеди. Алгач биринчи класстын ыкмасы иштеди, андан кийин экинчиси.

43. Демон жип деген эмне?

Топ 50 Java негизги интервью суроолору жана жооптору.  3-4-бөлүкДемон жип (мындан ары демон жип) башка жипке карата фондо тапшырмаларды аткарган жип. Башкача айтканда, анын милдети башка (негизги) жип менен бирге гана аткарылышы керек болгон жардамчы иштерди аткаруу. Автоматтык түрдө иштеген көптөгөн демон жиптери бар, мисалы, таштанды жыйноочу, жыйынтыктоочу ж.б.

Эмне үчүн Java демон жипти жабат?

Демон жипинин бирден-бир максаты - бул фонддук колдоо тапшырмасы үчүн колдонуучунун жипине кызматтарды көрсөтүү. Демек, эгерде негизги жип бүтсө, анда иштөө убактысы анын бардык демон жиптерин автоматтык түрдө жабат.

Thread классында иштөө ыкмалары

Класс java.lang.Threadжип демону менен иштөөнүн эки ыкмасын камсыз кылат:
  1. public void setDaemon(boolean status)- бул демон жип болорун көрсөтөт. Демейки болуп саналат false, бул өзүнчө көрсөтүлбөсө, демон эмес жиптер түзүлөт дегенди билдирет.
  2. public boolean isDaemon()daemon- негизи бул биз мурунку ыкманы колдонуп койгон өзгөрмө үчүн алуучу .
Мисал:
class DaemonThreadExample extends Thread {

   public void run() {
       // Проверяет, демон ли этот поток or нет
       if (Thread.currentThread().isDaemon()) {
           System.out.println("daemon thread");
       } else {
           System.out.println("user thread");
       }
   }

   public static void main(String[] args) {
       DaemonThreadExample thread1 = new DaemonThreadExample();
       DaemonThreadExample thread2 = new DaemonThreadExample();
       DaemonThreadExample thread3 = new DaemonThreadExample();

       // теперь thread1 - поток-демон.
       thread1.setDaemon(true);

       System.out.println("демон?.. " + thread1.isDaemon());
       System.out.println("демон?.. " + thread2.isDaemon());
       System.out.println("демон?.. " + thread3.isDaemon());

       thread1.start();
       thread2.start();
       thread3.start();
   }
}
Консолдук чыгаруу:

демон?.. true
демон?.. false
демон?.. false
daemon thread
user thread
user thread
Чыгуудан биз жиптин өзүнүн ичинде статикалык currentThread()ыкманы колдонуп, бир жагынан анын кайсы жипте экенин биле алабыз, экинчи жагынан, бул жиптин an objectисине шилтеме болсо, биз биле алабыз. түздөн-түз андан. Бул конфигурацияда керектүү ийкемдүүлүктү берет.

44. Жип жаралгандан кийин аны демон кылууга болобу?

Жок. Эгер муну кылсаңыз, ал өзгөчө учурду жаратат IllegalThreadStateException. Ошондуктан, биз демон жипти ал башталганга чейин гана түзө алабыз. Мисал:
class SetDaemonAfterStartExample extends Thread {

   public void run() {
       System.out.println("Working...");
   }

   public static void main(String[] args) {
       SetDaemonAfterStartExample afterStartExample = new SetDaemonAfterStartExample();
       afterStartExample.start();

       // здесь будет выброшено исключение
       afterStartExample.setDaemon(true);
   }
}
Консолдук чыгаруу:

Working...
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.lang.Thread.setDaemon(Thread.java:1359)
	at SetDaemonAfterStartExample.main(SetDaemonAfterStartExample.java:14)

45. Өчүрүү линиясы деген эмне?

Shutdownhook бул JVM (Java Virtual Machine) жабылганга чейин кыйыр түрдө чакырылган жип. Ошентип, биз аны ресурсту тазалоо же Java Virtual Machine кадимки же күтүлбөгөн жерден өчүп калганда абалды сактоо үчүн колдоно алабыз. shutdown hookБиз төмөнкү ыкманы колдонуу менен кошо аласыз :
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
Мисалда көрсөтүлгөндөй:
/**
* Программа, которая показывает How запустить shutdown hook тред,
* который выполнится аккурат до окончания работы JVM
*/
class ShutdownHookThreadExample extends Thread {

   public void run() {
       System.out.println("shutdown hook задачу выполнил");
   }

   public static void main(String[] args) {

       Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());

       System.out.println("Теперь программа засыпает, нажмите ctrl+c чтоб завершить ее.");
       try {
           Thread.sleep(60000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }
}
Консолдук чыгаруу:

Теперь программа засыпает, нажмите ctrl+c чтоб завершить ее.
shutdown hook задачу выполнил

46. ​​Синхронизация деген эмне?

Javaдагы синхрондоштуруу - бул бир нече жиптердин каалаган жалпы ресурска кирүү мүмкүнчүлүгүн көзөмөлдөө. Бир нече жиптер бир эле тапшырманы аткарууга аракет кылганда, ката натыйжага алып келиши мүмкүн, ошондуктан бул көйгөйдү чечүү үчүн Java синхрондоштурууну колдонот, анын аркасында бир эле учурда бир жип иштей алат. Синхрондоштуруу үч жол менен ишке ашырылышы мүмкүн:
  • Синхрондоо ыкмасы
  • Белгилүү бир блокту синхрондоштуруу менен
  • Статикалык синхрондоштуруу

Методду синхрондоштуруу

Шайкештештирилген ыкма кандайдыр бир жалпы ресурс үчүн an objectти кулпулоо үчүн колдонулат. Жип синхрондоштурулган ыкманы чакырганда, ал автоматтык түрдө ошол an objectке кулпу алат жана жип өз милдетин аткарганда аны бошотот. Аны иштетүү үчүн, сиз синхрондоштурулган ачкыч сөздү кошушуңуз керек . Бул мисал менен кантип иштээрин карап көрөлү:
/**
* Пример, где мы синхронизируем метод. То есть добавляем ему слово synchronized.
* Есть два писателя, которые хотят использовать один принтер. Они подготовor свои поэмы
* И конечно же не хотят, чтоб их поэмы перемешались, а хотят, чтоб работа была сделана по * * * очереди для каждого из них
*/
class Printer {

   synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {
       // один an object для двух тредов
       Printer printer  = new Printer();

       // создаем два треда
       Writer1 writer1 = new Writer1(printer);
       Writer2 writer2 = new Writer2(printer);

       // запускаем их
       writer1.start();
       writer2.start();
   }
}

/**
* Писатель номер 1, который пишет свою поэму.
*/
class Writer1 extends Thread {
   Printer printer;

   Writer1(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<string> poem = Arrays.asList("Я ", this.getName(), " Пишу", " Письмо");
       printer.print(poem);
   }

}

/**
* Писатель номер 2, который пишет свою поэму.
*/
class Writer2 extends Thread {
   Printer printer;

   Writer2(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<String> poem = Arrays.asList("Не Я ", this.getName(), " Не пишу", " Не Письмо");
       printer.print(poem);
   }
}
Жана консолго чыгуу:

Я Thread-0 Пишу Письмо
Не Я Thread-1 Не пишу Не Письмо

Синхрондоштуруу блогу

Шайкештештирилген блок кандайдыр бир белгилүү бир ыкма ресурста синхрондоштурууну аткаруу үчүн колдонулушу мүмкүн. Келгиле, чоң ыкмада (ооба, ооба, мындай нерселерди жаза албайсың, бирок кээде ушундай болот) кандайдыр бир себептерден улам кичинекей гана бөлүгүн синхрондоштуруу керек дейли. Эгерде сиз методдун бардык codeдорун синхрондоштурулган блокко койсоңуз, ал синхрондоштурулган метод сыяктуу эле иштейт. Синтаксис мындай көрүнөт:
synchronized (“an object для блокировки”) {
   // сам code, который нужно защитить
}
Мурунку мисалды кайталабоо үчүн биз анонимдүү класстар аркылуу жиптерди түзөбүз, башкача айтканда, Runnable интерфейсин дароо ишке ашырабыз.
/**
* Вот How добавляется блок синхронизации.
* Внутри нужно указать у кого будет взят мьютекс для блокировки.
*/
class Printer {

   void print(List<String> wordsToPrint) {
       synchronized (this) {
           wordsToPrint.forEach(System.out::print);
       }
       System.out.println();
   }

   public static void main(String args[]) {
       // один an object для двух тредов
       Printer printer = new Printer();

       // создаем два треда
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Я ", "Writer1", " Пишу", " Письмо");
               printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Не Я ", "Writer2", " Не пишу", " Не Письмо");
               printer.print(poem);
           }
       });

       // запускаем их
       writer1.start();
       writer2.start();
   }
}

}
жана консолго чыгаруу

Я Writer1 Пишу Письмо
Не Я Writer2 Не пишу Не Письмо

Статикалык синхрондоштуруу

Эгерде сиз статикалык ыкманы синхрондоштурсаңыз, кулпу an objectте эмес, класста болот. Бул мисалда биз статикалык синхрондоштурууну аткаруу үчүн статикалык ыкмага синхрондоштурулган ачкыч сөздү колдонобуз:
/**
* Вот How добавляется блок синхронизации.
* Внутри нужно указать у кого будет взят мьютекс для блокировки.
*/
class Printer {

   static synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {

       // создаем два треда
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Я ", "Writer1", " Пишу", " Письмо");
               Printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Не Я ", "Writer2", " Не пишу", " Не Письмо");
               Printer.print(poem);
           }
       });

       // запускаем их
       writer1.start();
       writer2.start();
   }
}
жана консолго чыгаруу:

Не Я Writer2 Не пишу Не Письмо
Я Writer1 Пишу Письмо

47. Учма өзгөрмө деген эмне?

Ачкыч сөз volatileжиптин коопсуздугун камсыз кылуу үчүн көп жиптүү программалоодо колдонулат, анткени бир өзгөрмөлүү өзгөрмөнүн модификациясы бардык башка жиптерге көрүнүп турат, ошондуктан бир өзгөрмө бир эле учурда бир жип тарабынан колдонулушу мүмкүн. Ачкыч сөздү колдонуу менен, volatileөзгөрмө жип үчүн коопсуз жана жалпы эстутумда сакталаарына кепилдик бере аласыз, ал эми жиптер аны кэшине алbyte. Ал эмнеге окшош?
private volatile AtomicInteger count;
Биз жөн гана өзгөрмө кошобуз volatile. Бирок бул жиптин толук коопсуздугу дегенди билдирбейт... Анткени, операциялар өзгөрмө боюнча атомдук болбошу мүмкүн. AtomicБирок сиз операцияны атомдук түрдө аткарган класстарды, башкача айтканда, процессор тарабынан бир аткарууда колдоно аласыз . Мындай класстарды пакеттен тапса болот java.util.concurrent.atomic.

48. Туюктук деген эмне

Javaдагы туюк көп агымдын бир бөлүгү. Туюк жип башка жип тарабынан алынган an objectтин кулпусун күтүп турган, ал эми экинчи жип биринчи жип тарабынан алынган an objectтин кулпусун күтүп турган кырдаалда пайда болушу мүмкүн. Ошентип, бул эки жип бири-бирин күтүшөт жана алардын codeун аткарууну улантышпайт. Топ 50 Java негизги интервью суроолору жана жооптору.  3-5-бөлүкКелгиле, Runnable программасын ишке ашырган класс бар мисалды карап көрөлү. Ал конструктордо эки ресурстарды кабыл алат. Run() методунун ичинде, ал алар үчүн кулпуну бир-бирден алат, андыктан бул класстын эки an objectисин түзүп, ресурстарды ар кандай тартипте өткөрүп берсеңиз, кулпуга оңой эле кирип кетесиз:
class DeadLock {

   public static void main(String[] args) {
       final Integer r1 = 10;
       final Integer r2 = 15;

       DeadlockThread threadR1R2 = new DeadlockThread(r1, r2);
       DeadlockThread threadR2R1 = new DeadlockThread(r2, r1);

       new Thread(threadR1R2).start();
       new Thread(threadR2R1).start();
   }
}

/**
* Класс, который принимает два ресурса.
*/
class DeadlockThread implements Runnable {

   private final Integer r1;
   private final Integer r2;

   public DeadlockThread(Integer r1, Integer r2) {
       this.r1 = r1;
       this.r2 = r2;
   }

   @Override
   public void run() {
       synchronized (r1) {
           System.out.println(Thread.currentThread().getName() + " захватил ресурс: " + r1);

           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }

           synchronized (r2) {
               System.out.println(Thread.currentThread().getName() + " захватил ресурс: " + r2);
           }
       }
   }
}
Консолдук чыгаруу:

Первый тред захватил первый ресурс
Второй тред захватывает второй ресурс

49. Туюктан кантип сактануу керек?

Туюктун кантип пайда болорун биз билген нерселерге таянып, кээ бир тыянактарды чыгара алабыз...
  • Жогорудагы мисалда көрсөтүлгөндөй, туюк кулпулардын уя салуусунан улам болгон. Башкача айтканда, бир кулпунун ичинде башка же андан көп. Муну төмөнкүдөй жол менен болтурбай коюуга болот - уя салуунун ордуна, үстүнө жаңы абстракция кошуп, кулпуну жогорку деңгээлге чыгарып, уя салынган кулпуларды алып салышыңыз керек.
  • Канчалык көп бөгөт коюлса, ошончолук туюктун болушу ыктымал. Ошондуктан, кулпуну кошкон сайын, ал чындап эле керекпи жана жаңысын кошуудан качууга болорун ойлонуш керек.
  • колдонот Thread.join(). Туюк бир жип экинчисин күтүп турганда да жасалышы мүмкүн. join()Бул көйгөйдү болтурбоо үчүн, сиз ыкмага убакыт чегин коюуну ойлонушуңуз мүмкүн .
  • Эгерде бизде бир жип болсо, анда туюк болбойт;)

50. Жарыш шарты деген эмне?

Эгерде чыныгы жарыштарда унаалар аткарса, анда көп жиптүү жарыш терминологиясында жиптер жарыштарда аткарышат. Бирок эмне үчүн? Иштеп жаткан жана бир эле an objectке кире ала турган эки жип бар. Жана алар ошол эле учурда мамлекетти жаңылоого аракет кылышы мүмкүн. Азырынча баары түшүнүктүү, туурабы? Ошентип, жиптер же чыныгы параллелдүү (эгерде процессордо бирден ашык өзөк болсо) же шарттуу түрдө, процессор кыска убакытты бөлгөндө параллелдүү иштейт. Жана биз бул процесстерди башкара албайбыз, ошондуктан бир жип an objectтен маалыматтарды окуганда, аны башка жип жасаганга чейин өзгөртүүгө убактысы болот деп кепилдик бере албайбыз. Бул сыноо жана аракет айкалышы өтүп жатканда, ушул сыяктуу көйгөйлөр пайда болот. Бул эмнени билдирет? Мисалы, биздин ifденеде шарттын өзү өзгөргөн туюнтма бар, б.а.
int z = 0;

// проверь
if (z < 5) {
//действуй
   z = z + 5;
}
Ошентип, z дагы нөлгө барабар болгон учурда, эки жип бир эле учурда бул code блогуна кирген жана алар чогуу бул маанини өзгөрткөн кырдаал болушу мүмкүн. Акыр-аягы, биз күтүлгөн 5 эмес, 10 маанисин албайбыз. Муну кантип болтурбоо керек? Сиз аткаруу алдында жана кийин кулпулоо керек. Башкача айтканда, блокко кирген биринчи жип үчүн ifбардык аракеттерди жасап, аны өзгөртүп, zандан кийин гана кийинки жипке муну жасоого мүмкүнчүлүк бериңиз. Бирок кийинки жип блокко кирбейт if, анткени zал 5ке барабар болот:
// получить блокировку для z
if (z < 5) {
   z = z + 5;
}
// выпустить из блокировки z
===================================================

чыгаруунун ордуна

Аягына чейин окугандарга рахмат айткым келет. Бул узак жол болду жана сен ага жеттиң! Баары ачык-айкын болушу мүмкүн эмес. Бул Жакшы. Мен Java тorн үйрөнө баштаганда статикалык өзгөрмө эмне экенин биле албай калдым. Бирок эч нерсе жок, мен бул ой менен уктап, дагы бир нече булактарды окуп, акыры түшүндүм. Интервьюга даярдануу практикалык эмес, академиялык маселе. Ошондуктан, ар бир интервью алдында сиз көп колдонбогон нерселерди кайталап, эс тутумуңузду жаңыртып турушуңуз керек.

Жана дайыма эле, пайдалуу шилтемелер:

Окуганыңыз үчүн рахмат, жакында көрүшкөнчө) GitHubдагы профorм
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION