JavaRush /Java блогу /Random-KY /26-деңгээл. Деңгээлдеги тема боюнча интервью суроолоруна ...
zor07
Деңгээл
Санкт-Петербург

26-деңгээл. Деңгээлдеги тема боюнча интервью суроолоруна жооптор. 2-бөлүк. 6-9, 11-12-суроолор

Группада жарыяланган
26-деңгээл. Деңгээлдеги тема боюнча интервью суроолоруна жооптор.  2-бөлүк. 6-9, 11-12 - 1 суроолор

6. Канкаренци деген эмне?

Concurrency – бул Java тorндеги класс китепканасы, анда бир нече жиптер боюнча иштөө үчүн оптималдаштырылган атайын класстар бар. Бул класстар пакетте чогултулган java.util.concurrent. Функционалдык мүмкүнчүлүктөрү боюнча аларды схемалык түрдө төмөнкүчө бөлүүгө болот: 26-деңгээл. Деңгээлдеги тема боюнча интервью суроолоруна жооптор.  2-бөлүк. 6-9, 11-12 - 2 суроолорКошумалдуу коллекцияларjava.util – пакеттеги стандарттуу универсалдуу коллекцияларга караганда көп жиптүү чөйрөдө эффективдүү иштеген коллекциялардын жыйындысы . Бүткүл коллекцияга кирүү мүмкүнчүлүгүн бөгөттөөчү негизги оромонун ордуна Collections.synchronizedList, маалымат сегменттериндеги кулпулар колдонулат же күтүү алгоритмдерин колдонуу менен маалыматтарды параллель окуу үчүн оптималдаштырылган. Кезектер - көп жипти колдоо менен бөгөттөлбөгөн жана бөгөттөөчү кезектер. Бөгөтсүз кезектер жиптерди бөгөтпөстөн ылдамдык жана иштөө үчүн иштелип чыккан. Бөгөттөө кезектери "Продюсер" же "Керектөөчү" жиптерин "басаңdateу" керек болгондо колдонулат, эгерде кээ бир шарттар аткарылбаса, мисалы, кезек бош же толуп кетсе, же бекер "Керектөөчү" жок болсо. Синхронизаторлор жиптерди синхрондоштуруу үчүн көмөкчү программалар болуп саналат. Алар "параллель" эсептөөдө күчтүү курал болуп саналат. Аткаруучулар - жип бассейндерин түзүү, асинхрондук тапшырмаларды пландаштыруу жана натыйжаларды алуу үчүн мыкты алHowтарды камтыйт. Кулпуларsynchronized - негизгиге waitсалыштырмалуу жипти синхрондоштуруунун альтернативалуу жана ийкемдүү механизмдерин билдирет notify. Атомика - примитивдер жана шилтемелер боюнча атомдук операцияларды колдогон класстар. Булак:notifyAll

7. Канкаренсиден кандай класстарды билесиз?

Бул суроонун жообу бул макалада эң сонун айтылган . Мен мунун баарын бул жерде кайра басып чыгаруунун маанисин көрбөй турам, андыктан мен кыскача таанышуу сыймыгына ээ болгон класстарга гана мүнөздөмө берем. ConcurrentHashMap<K, V> - Hashtableжана блокторунан synhronizedайырмаланып HashMap, маалыматтар сегменттер түрүндө берилген, ачкычтардын хэштерине бөлүнгөн. Натыйжада, маалыматтар бир an object менен эмес, сегменттер тарабынан жеткorктүү болот. Мындан тышкары, итераторлор белгилүү бир убакыт аралыгындагы маалыматтарды билдирет жана ыргытпайт ConcurrentModificationException. AtomicBoolean, AtomicInteger, AtomicLong, AtomicIntegerArray, AtomicLongArray - Эгер класста сиз түрдөгү бир жөнөкөй өзгөрмөгө кирүү мүмкүнчүлүгүн синхрондоштуруу керек болсочы int? Сиз менен конструкцияларды колдоно аласыз synchronizedжана атомдук операцияларды колдонууда set/get, volatile. Бирок сиз жаңы класстарды колдонуу менен мындан да жакшыраак кыла аласыз Atomic*. CAS колдонулгандыктан, бул класстар менен операциялар синхрондоштурууга караганда ылдамыраак болот synchronized/volatile. Мындан тышкары, белгилүү бир өлчөмдө атом кошуу ыкмалары бар, ошондой эле көбөйтүү/азайтуу.

8. ConcurrentHashMap классы кандай иштейт?

Аны киргизүү учурунда ConcurrentHashMapJava иштеп чыгуучулары төмөнкү хэш картаны ишке ашырууга муктаж болушкан:
  • Жиптин коопсуздугу
  • Ага жетүү учурунда бүт үстөлдө кулпулар жок
  • Окуу операциясын аткарып жатканда үстөл кулпулары болбошу керек
Негизги ишке ашыруу идеялары ConcurrentHashMapболуп төмөнкүлөр саналат:
  1. Карта элементтери

    Элементтерден айырмаланып HashMap, Entryin ConcurrentHashMapкатары жарыяланды volatile. Бул маанилүү өзгөчөлүк, ошондой эле JMMдеги өзгөрүүлөргө байланыштуу .

    static final class HashEntry<K, V> {
        final K key;
        final int hash;
        volatile V value;
        final HashEntry<K, V> next;
    
        HashEntry(K key, int hash, HashEntry<K, V> next, V value) {
            this .key = key;
            this .hash = hash;
            this .next = next;
            this .value = value;
         }
    
        @SuppressWarnings("unchecked")
        static final <K, V> HashEntry<K, V>[] newArray(int i) {
            return new HashEntry[i];
        }
    }
  2. Хеш функциясы

    ConcurrentHashMapжакшыртылган хэшинг функциясы да колдонулат.

    JDK 1.2де кандай болгонун эске сала кетейин HashMap:

    static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

    ConcurrentHashMap JDK 1.5 versionсы:

    private static int hash(int h) {
        h += (h << 15) ^ 0xffffcd7d;
        h ^= (h >>> 10);
        h += (h << 3);
        h ^= (h >>> 6);
        h += (h << 2) + (h << 14);
        return h ^ (h >>> 16);
    }

    Эмне үчүн хэш-функцияны татаалдантуу зарыл? Хэш картадагы tableлардын узундугу эки күч менен аныкталган. Бинардык өкүлчүлүктөрү төмөн жана жогорку абалда айырмаланбаган хэш codeдору үчүн бизде кагылышуулар болот. Хеш функциясынын татаалдыгын жогорулатуу бул көйгөйдү чечип, картада кагылышуулардын ыктымалдыгын азайтат.

  3. Сегменттер

    Карта N түрдүү сегменттерге бөлүнгөн (демейки боюнча 16, максималдуу маани 16 бит болушу мүмкүн жана эки күч). Ар бир сегмент карта элементтеринин жип менен коопсуз tableсы болуп саналат. Сегменттердин санын көбөйтүү бир нече сегментти камтыган өзгөртүү операцияларын стимулдайт, иштөө убагында бөгөттөө ыктымалдыгын азайтат.

  4. ConcurrencyLevel

    Бул параметр эстутум картасын колдонууга жана картадагы сегменттердин санына таасирин тийгизет.

    Сегменттердин саны concurrencyLevel деңгээлинен чоңураак экинин жакынкы күчү катары тандалат. ConcurrencyLevel деңгээлин төмөндөтүү жиптер жазып жатканда карта сегменттерин бөгөттөп коюу ыктымалдыгын жогорулатат. Көрсөткүчтү ашыкча баалоо эстутумду натыйжасыз пайдаланууга алып келет. Эгерде бир гана жип картаны өзгөртсө, калгандары окуса, анда 1 маанисин колдонуу сунушталат.

  5. Бардыгы

    Ошентип, негизги артыкчылыктары жана ишке ашыруу өзгөчөлүктөрү ConcurrentHashMap:

    • Картада окшош hashmapөз ара аракеттенүү интерфейси бар
    • Окуу операциялары кулпуларды талап кылbyte жана параллелдүү аткарылат
    • Жазуу операциялары да көп учурда бөгөттөлбөй эле параллелдүү аткарылышы мүмкүн
    • Түзүүдө талап кылынат көрсөтүлөт concurrencyLevel, статистиканы окуу жана жазуу менен аныкталат
    • valueКарта элементтери деп жарыяланган мааниге ээvolatile
    Булак: ConcurrentHashMap кантип иштейт

9. Lock классы деген эмне?

Бөлүшүлгөн ресурска кирүү мүмкүнчүлүгүн көзөмөлдөө үчүн, синхрондоштурулган операторго альтернатива катары кулпуларды колдоно алабыз. Кулпулоо функциясы пакетте камтылган java.util.concurrent.locks. Биринчиден, жип бөлүшүлгөн ресурска кирүүгө аракет кылат. Эгерде ал бош болсо, анда жипке кулпу коюлат. Иш аяктагандан кийин, жалпы ресурстун кулпусу бошотулат. Эгерде ресурс бош эмес болсо жана ага кулпу орнотулган болсо, анда жип бул кулпу бошотулганга чейин күтөт. LockКулпу класстары төмөнкү ыкмаларды аныктаган интерфейсти ишке ашырат :
  • void lock():кулпу алынганга чейин күтөт
  • boolean tryLock():кулпуну алууга аракет кылат; эгер кулпу алынса, ал чындыкты кайтарат . Эгер кулпу алынбаса, ал false кайтарат . Бул ыкмадан айырмаланып, lock()эгер кулпу жок болсо, аны алууну күтпөйт
  • void unlock():кулпусун алып салат
  • Condition newCondition():Conditionучурдагы кулпу менен байланышкан an objectти кайтарат
Жалпы учурда кулпулоону уюштуруу абдан жөнөкөй: кулпуну алуу үчүн, ыкма деп аталат , ал эми жалпы ресурстар менен иштөө аяктагандан кийин, кулпуну бошотуучу lock()ыкма деп аталат . unlock()Объект Conditionбөгөт коюуну башкарууга мүмкүндүк берет. Эреже катары, кулпулар менен иштөө үчүн ReentrantLockпакеттен класс колдонулат.Бул java.util.concurrent.locks.класс интерфейсти ишке ашырат Lock. Мисал катары кичинекей программаны колдонуп Java Lock API колдонууну карап көрөлү: Ошентип, бизде Resourceжиптин коопсуздугу талап кылынбаган бир нече жип үчүн коопсуз методдор жана методдор бар класс бар дейли.
public class Resource {

    public void doSomething(){
        // пусть здесь происходит работа с базой данных
    }

    public void doLogging(){
        // потокобезопасность для логгирования нам не требуется
    }
}
RunnableЭми интерфейсти ишке ашырган жана класстын ыкмаларын колдонгон классты алалы Resource.
public class SynchronizedLockExample implements Runnable{

    // экземпляр класса Resource для работы с методами
    private Resource resource;

    public SynchronizedLockExample(Resource r){
        this.resource = r;
    }

    @Override
    public void run() {
        synchronized (resource) {
            resource.doSomething();
        }
        resource.doLogging();
    }
}
Эми жогорудагы программаны Lock API ордуна кайра жазалы synchronized.
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// класс для работы с Lock API. Переписан с приведенной выше программы,
// но уже без использования ключевого слова synchronized
public class ConcurrencyLockExample implements Runnable{

    private Resource resource;
    private Lock lock;

    public ConcurrencyLockExample(Resource r){
        this.resource = r;
        this.lock = new ReentrantLock();
    }

    @Override
    public void run() {
        try {
            // лочим на 10 секунд
            if(lock.tryLock(10, TimeUnit.SECONDS)){
            resource.doSomething();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //убираем лок
            lock.unlock();
        }
        // Для логгирования не требуется потокобезопасность
        resource.doLogging();
    }

}
Программадан көрүнүп тургандай, биз tryLock()жип белгилүү бир убакытты гана күтөөрүнө ынануу үчүн ыкманы колдонобуз. Эгерде ал an objectке кулпу албаса, анда ал жөн гана журналга кирип чыгып кетет. Дагы бир маанилүү жагдай. Метод өзгөчө учурду ыргытса try-finallyда кулпу бошотулушун камсыз кылуу үчүн блокту колдонушуңуз керек . Булактары:doSomething()

11. Мутекс деген эмне?

Мутекс жиптерди/процесстерди синхрондоштуруу үчүн атайын an object болуп саналат. Бул эки штатты ала алат - бош эмес жана акысыз. Жөнөкөйлөтүү үчүн, мутекс бул эки маанини кабыл алган логикалык өзгөрмө: бош (чын) жана бош (жалган). Жип an objectке эксклюзивдүү ээлик кылууну каалаганда, ал өзүнүн мутексин бош эмес деп белгилейт, ал эми аны менен иштеп бүткөндөн кийин, анын мутексин бош деп белгилейт. Мутекс Javaдагы ар бир an objectке тиркелет. Мутекске Java машинасы гана түз кире алат. Ал программисттен жашырылган.

12. Монитор деген эмне?

Монитор – бул атайын механизм (codeдун бир бөлүгү) – аны менен туура иштешин камсыз кылган мутекстин үстүнөн кошумча. Анткени, an object бош эмес деп белгилөө жетишсиз, биз башка жиптер бош эмес an objectти колдонууга аракет кылбасын камсыздашыбыз керек. Java тorнде монитор ачкыч сөздү колдонуу менен ишке ашырылат synchronized. Шайкештештирилген блокту жазганда, Java компилятору аны үч code менен алмаштырат:
  1. Блоктун башында synchronizedмутексти бош эмес деп белгилеген code кошулат.
  2. Блоктун аягында synchronizedмутексти бекер деп белгилеген code кошулат.
  3. Блоктун алдында synchronizedмутекстин бош эместигин текшерген code кошулат, андан кийин жип анын бошотулушун күтүшү керек.
1-бөлүк
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION