Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

Ez egy AI által fordított bejegyzés.

제이온

[Hatékony Java] 1. elem. Próbálja meg a statikus gyári metódusokat a konstruktorok helyett.

  • Írás nyelve: Koreai
  • Referencia ország: Minden ország country-flag

Válasszon nyelvet

  • Magyar
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी

A durumis AI által összefoglalt szöveg

  • A statikus gyári módszerek számos előnnyel rendelkeznek a konstruktorokkal szemben, és hatékonyan szabályozhatják az osztály példányosítását.
  • A JDBC a statikus gyári módszerek használatának reprezentatív példája, amely a szolgáltatás-szolgáltató keretrendszer mintán keresztül rugalmas és skálázható architektúrát biztosít.
  • Bár a statikus gyári módszereknek vannak korlátaik, például a öröklődés korlátozása és a fejlesztők számára való nehéz megtalálás, ha jól használják fel, jó tervezést eredményezhetnek.

Bevezetés

A statikus gyári módszer a Java osztályok példányainak létrehozásának egyik klasszikus módja.


public class Tag {

    private String name;
    private String value;

    private Tag(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public static Tag create(String name, String value) {
        return new Tag(name, value);
    }

    public String getName() {
        return name;
    }

    public String getValue() {
        return value;
    }


Bár a nyilvános konstruktorok általában elegendőek, vannak esetek, amikor a statikus gyári módszer használata megkönnyíti a felhasználók számára, hogy helyesen példányosítsák az objektumokat az alkalmazás szándékának megfelelően.


Statikus gyári módszerek előnyei

Nevesíthetőek

Az osztály konstruktoraiban szereplő paraméterek és a konstruktorok maguk nem feltétlenül írják le megfelelően a visszaadott objektum jellegét. Például a fenti Tag osztály konstruktorában (name, value) nem világos, hogy milyen típusú Tagről van szó.


Egy metódus használatával korlátozhatjuk, hogy egyetlen aláírással hány konstruktor hozható létre, és ehelyett nevezzük el a statikus gyári metódusokat, hogy több különböző típusú objektumot adhassunk vissza azonos aláírással.


public class Tag {

    private String name;
    private String value;

    private Tag(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public static Tag createBasicTag(String name, String value) {
        return new Tag(name, value);
    }

    public static Tag createAdvancedTag(String name, String value) {
        return new Tag(name, value);
    }

    public String getName() {
        return name;
    }

    public String getValue() {
        return value;
    }


Ahelyett, hogy a konstruktor segítségével megkülönböztetnénk a TagStatus-t, az azonos aláírással rendelkező statikus gyári metódusok létrehozása lehetővé teszi a felhasználók számára, hogy a kódjuk ne legyen kétértelmű, és pontosan azon a Tag-en dolgozzanak, amelyet a feladatuk megkövetel.

Az egyik példa a JDK-ban megtalálható BigInteger osztály probablePrime() nevű statikus gyári metódusa.


public static BigInteger probablePrime(int bitLength, Random rnd) {
    if (bitLength < 2)
        throw new ArithmeticException("bitLength < 2");

    return (bitLength < SMALL_PRIME_THRESHOLD ?
            smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
            largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));


Összehasonlítva a BigInteger osztály public konstruktorával, a probablePrime() statikus gyári metódus egyértelműen "prime" névvel rendelkezik, és könnyen megérthető, hogy milyen típusú egész számot ad vissza.


Nem kell új példányt létrehozni minden egyes híváskor

A Java Boolean.valueOf() metódusa egy példa arra, hogyan lehet elkerülni, hogy minden egyes híváskor új példányt hozzon létre. Ez a metódus előzetesen tárolja a példányokat, és ezeket adja vissza, ami jelentős teljesítménynövelést eredményezhet, ha a létrehozás költséges, és a metódust gyakran hívják.


Az előbbiekben említett "Légyúszó" minta ehhez hasonló megközelítést alkalmaz.


Egy osztály, amely a statikus gyári metódus megközelítést használja az ismétlődő kérések esetén ugyanazt a példányt visszaadó metódushoz, egy példaérték-vezérelt osztály. Az ilyen osztályok szabályozhatják a példányok életciklusát, lehetővé téve az egypéldányos osztályok létrehozását, vagy a nem példányosítható osztályok létrehozását. Ezenkívül biztosíthatják az egyetlen példány létezését az immutábilis értéktípusoknál.

A példánykezelés a "Légyúszó" minta gerince, míg a felsorolási típusok biztosítják az egyetlen példány létezését.


Példa

Tegyük fel, hogy fákat kell ülteti a Minecraftba. Ha minden egyes fa objektumot új létrehozunk, akkor a memória megtelhet.

Ezért ahelyett, hogy minden egyes fánál új fát létrehoznánk, ahelyett, hogy minden egyes fánál új fát hoznánk létre, ezeket a fákat tárolhatjuk, és egyszerűen csak a pozíciójukat módosíthatjuk ahelyett, hogy új fát hoznánk létre. Természetesen a színek száma meghaladhatja a kettőt, így hatékony lenne a színek szerinti tárolás a fákat egy Map-ben tárolni.


public class Fa {

    // Egy fa a következő 3 információval rendelkezik
    private String szín;
    private int x;
    private int y;

    // Csak a szín alapján hozza létre a konstruktort.
    public Fa(String szín) {
        this.szín = szín;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    // Fáültetéskor
    public void telepítés() {
        System.out.println("A " + szín + " fát telepítettük az x:" + x + " y:" + y + " koordinátákra!");
    }
}

public class FaGyár {
    // Fákat tároló HashMap adatszerkezetet használunk a fák kezelésére
    public static final Map faTérkép = new HashMap<>();


    public static Fa getFa(String faSzín) {
        // A megadott színű fa megkeresése a térképen. Ha megvan, akkor visszaadjuk az objektumot.
        Fa fa = (Fa) faTérkép.get(faSzín); 

       // Ha még nincs megadott színű fa a térképen, akkor létrehozunk egy új objektumot, és visszaadjuk.
        if (fa == null) {
            fa = new Fa(faSzín);
            faTérkép.put(faSzín, fa);
            System.out.println("Új objektum létrehozva");
        }

        return fa;
    }
}

public class Fő {
    public static void main(String[] args) {
        Szkenner szkenner = new Szkenner(System.in);

        System.out.println("Adja meg a kívánt színt :)");
        for (int i = 0; i < 10; i++) {
            // Fa színe beolvasása
            String in = szkenner.nextLine();
            // Egy fa beszerzése a gyárból
            Fa fa = (Fa) FaGyár.getFa(in);
            // Beállítja a fa x, y koordinátáit, és
            fa.setX((int) (Math.random() * 100));
            fa.setY((int) (Math.random() * 100));
            // Elülteti a fát
            fa.telepítés();
        }
    }


Különbség a Singleton mintától

A Singleton minta megköveteli, hogy a Fa osztályban csak egy fa létezzen. Ezért, ha a Singleton mintát használjuk, akkor az egy létrehozott objektum színét meg kell változtatni. Vagyis a Singleton minta csak egy példányt engedélyez, függetlenül annak típusától.


Használati esetek

A Java String Constant Pooljában használják a Flyweight mintát.


Visszaadhat egy altípusú objektumot

Ha valaha is használtál már az Arrays osztály asList() metódusát, akkor valószínűleg érted ennek az előnyét.


public static  List asList(T... a) [
    return new ArrayList<>(a);


A metódus egy ArrayList-be csomagolja a List interfész egyik megvalósítását, és ezt adja vissza, a felhasználónak nincs szüksége a tényleges megvalósítás ismeretére. Ez azt jelenti, hogy a visszaadott objektum típusa szabadon választható, ami rugalmasságot biztosít a fejlesztőnek a megvalósítás nyilvános közzététele nélkül, így a kód a lehető legkisebb méretű marad.


Az "Interfész Statikus Metódusaival kapcsolatos megjegyzések"

A Java 8 előtt az interfészek nem tartalmazhattak statikus metódusokat, így ha egy olyan statikus gyári metódusra volt szükség, amely egy "Type" nevű interfészt ad vissza, akkor egy "Types" nevű nem példányosítható kísérő osztályt kellett létrehozni, amelyben a metódust definiálni kellett.


Egy tipikus példa erre a JCF által biztosított 45 használati segédprogram-implementáció, amelyek közül a legtöbb publikus, és amely a "java.util." osztályban található. Csak olvasható, és nincsenek nyilvánosak, így kizárólag egy statikus gyári metódus segítségével hozhatóak létre. (Természetesen ez az implementáció nem örökölhető.)


Ráadásul a 45 implementáció mindegyike nyilvános, így az API-t lényegesen kisebbre lehetett tenni.


// Interfész és kísérő osztályok példája


Egyes statikus gyári metódusokat azért használunk, hogy a metódust definiáljuk az interfészen, és így elkerüljük a kísérő osztály külön létrehozását.


Különböző altípusú objektumot adhat vissza a bemeneti paraméterek alapján

A statikus gyári metódusok használata túlmutat az altípusok visszadásán, és lehetővé teszi, hogy különböző altípusokat adjunk vissza a paraméterek alapján. Például, ha a pontszámtól függően más MemberStatus-t szeretnénk visszaadni, akkor a statikus gyári metódust a következőképpen definiálhatjuk, és összehasonlító logikát helyezhetünk el benne.


public enum MemberStatus {

    FEJLETT(80, 100),
    KÖZÉPHALADÓ(50, 79),
    ALAP(0, 49);

    private final int minimumPontszám;
    private final int maximumPontszám;

    MemberStatus(int minimumPontszám, int maximumPontszám) {
        this.minimumPontszám = minimumPontszám;
        this.maximumPontszám = maximumPontszám;
    }

    public static MemberStatus of(int pontszám) {
        return Arrays.stream(values())
                .filter(decideMemberStatus(pontszám))
                .findAny()
                .orElseThrow(() -> new NoSuchElementException("Nincs megfelelő MemberStatus objektum."));
    }

    private static Predicate decideMemberStatus(int pontszám) {
        return element -> element.minimumPontszám <= pontszám && element.maximumPontszám >= pontszám;
    }
}

@DisplayName("MemberStatus teszt")
class MemberStatusTest {

    @ParameterizedTest
    @CsvSource(value = {"0:ALAP", "30:ALAP", "50:KÖZÉPHALADÓ", "70:KÖZÉPHALADÓ", "80:FEJLETT", "100:FEJLETT"}, delimiter = ':')
    @DisplayName("Különböző MemberStatus értékeket ad vissza a pontszámtól függően.")
    void of(int input, MemberStatus expected) {
        assertThat(MemberStatus.of(input)).isEqualTo(expected);
    }

A statikus gyári metódus létrehozásának időpontjában a visszaadott objektum osztályának még nem kell léteznie.

A fenti mondatban a "visszaadott objektum osztálya" az általunk írt osztályfájl.

Megjegyzés: A Class a Class objektumot jelenti, amelyet a osztálybetöltő allokál a halom memóriaterületre, amikor a osztályt betölti. Ez a Class objektum számos metaadatot tartalmaz a általunk írt osztályról.


package algoritmus.adatszerkezet;

public abstract class StatikusGyáriMetódusTípus {

    public abstract void getNév();

    public static StatikusGyáriMetódusTípus getÚjPéldány() {
        StatikusGyáriMetódusTípus temp = null;
        try {
            Class gyerekOsztály = Class.forName("algoritmus.adatszerkezet.StatikusGyáriMetódusTípusGyerek"); // Reflexió
            temp = (StatikusGyáriMetódusTípus) gyerekOsztály.newInstance(); // Reflexió

        } catch (ClassNotFoundException e) {
           System.out.println("Az osztály nem található.");
        } catch (InstantiationException  e) {
            System.out.println("Nem hozható létre a memóriában.");
        } catch (IllegalAccessException  e) {
            System.out.println("Az osztályfájl elérési hibája.");
        }

        return temp;
    }


Ahogy a fenti kódból is látható, a metódus a generált kód segítségével hozza létre az interfész megvalósítását, és reflexiót használ a ténylegesen létrehozott példány inicializálására. Ekkor a "statikus gyári metódus megalkotásakor" a StatikusGyáriMetódusTípusChild osztálynak még nem kell léteznie.


Azonban, ha a statikus gyári metódust használó kódot futtatja, és a "algorithm.adatszerkezet.StatikusGyáriMetódusTípusGyerek" elérési útvonalon nincsenek megvalósítások, akkor egy hiba lép fel. De amikor a statikus gyári metódust írjuk, akkor nincs probléma, ezért mondjuk, hogy ez egy rugalmas megközelítés.


public interface Teszt {

    int összeg(int a, int b);

    // A Teszt egy interfész, és nincs megvalósítása, de a statikus gyári metódus létrehozásakor nincs probléma
    static Teszt create() {
        return null;
    }
}

public class Fő {

    public static void main(String[] args) {
        Teszt teszt = Teszt.create();
        System.out.println(teszt.összeg(1, 2)); // NPE kivétel lép fel
    }


Reflexió használata nélkül is elérhető ugyanez a rugalmasság. Amint látja, a Teszt interfész create() statikus gyári metódusa nem okoz problémát a metódus megírása közben, de persze az első futtatáskor NPE kivételt okoz. Ezt a rugalmasságot használja a szolgáltatói keretrendszer, amelynek egyik fő képviselője a JDBC.


  • Szolgáltató keretrendszer összetevők
    • Szolgáltatási interfész
      • Meghatározza a szolgáltatás implementációjának viselkedését
      • JDBC esetében ez a Kapcsolat
    • Szolgáltató regisztrációs API
      • Lehetővé teszi a szolgáltató számára, hogy regisztrálja az implementációját
      • JDBC esetében a DriverManager.registerDriver() használatos
    • Szolgáltatás-hozzáférési API
      • Amikor az ügyfél egy szolgáltatás példányát szeretné lekérni, és nem határoz meg feltételeket, akkor az alapértelmezett implementációt, vagy egy kompatibilis implementációt adja vissza.
      • A statikus gyári metódus ellentéte
      • JDBC esetében a DriverManager.getConnection() használatos
    • (Opcionális) Szolgáltatói interfész
      • Ha ez nincs meg, akkor reflexiót kell használni az egyes implementációk példányosításakor
      • JDBC esetében ez a Meghajtó


A szolgáltató keretrendszer minta számos változata létezik, köztük a Híd minta, és a Függőségvezérlő keretrendszer.


A JDBC egy tipikus példája:

Class.forName("oracle.jdbc.driver.OracleDriver"); 
Connection kapcsolat = null; 
kapcsolat = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORA92", "root", "root"); 


Általában a JDBC-t a fenti módon írják. A Class.forName() függvénnyel regisztráljuk a Meghajtó implementációját, amely az OracleDriver, és a DriverManager.getConnection() függvénnyel lekérjük a Kapcsolat implementációját, amely ebben az esetben az OracleDriver Meghajtó Kapcsolat.


Ebben az esetben a Kapcsolat a szolgáltatási interfész, a DriverManager.getConnection() pedig a szolgáltatás-hozzáférési API. A szolgáltató regisztrációs API, a DriverManager.registerDriver() azonban nem használatos. Ennek ellenére a Class.forName() használatával regisztrálhatjuk az OracleDriver meghajtó implementációját. De hogyan lehetséges ez?


A Class.forName() függvény működése

Ez a metódus a fizikai osztályfájl nevét veszi paraméterként, és kéri a virtuális gépet, hogy töltse be ezt az osztályt. Ezután az osztálybetöltő betölti az osztály metaadatait a metódusterületre. Ekkor a Class objektumot is kiosztja a halomterületre. Emellett, amikor az osztály betöltése befejeződik, a statikus mezők és a statikus blokkok inicializálódnak, és ebben a pillanatban történik a szolgáltató regisztrációs API használata.


public class OracleDriver implements Driver {

    static {
        defaultDriver = null;
        Timestamp timestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
        try {
            if (defaultDriver == null) {
                defaultDriver = new OracleDriver();
                DriverManager.registerDriver(defaultDriver); // OracleDriver regisztrálása
            }
        } catch (RuntimeException runtimeexception) {
        } catch (SQLException sqlexception) {
        }
    }

    ...


Valójában az OracleDriver osztályban látható, hogy a statikus blokkban a DriverManager.registerDriver() függvényt hívja meg, és így regisztrálja a meghajtó implementációját, az OracleDriver-t.


A DriverManager osztály elemzése

public class DriverManager {

    private DriverManager() {
    }

    private static final Map meghajtók = new ConcurrentHashMap();
    public static final String ALAPÉRTELMEZETT_MEGTAJTO_NEV = "alapértelmezett";

    public static void regisztráljaAzAlapértelmezettMeghajtót(Driver d) {
        System.out.println("Meghajtó regisztrálva");
        regisztrálMeghajtó(ALAPÉRTELMEZETT_MEGTAJTO_NEV, d);
    }

    public static void regisztrálMeghajtó(String név, Driver d) {
        meghajtók.put(név, d);
    }

    public static Connection getConnection() {
        return getConnection(ALAPÉRTELMEZETT_MEGTAJTO_NEV);
    }

    public static Connection getConnection(String név) {
        Driver d = meghajtók.get(név);
        if (d == null) throw new IllegalArgumentException();
        return d.getConnection();
    }


Bár a DriverManager osztály sokkal összetettebb lehet, a lényeg a fentihez hasonló. Ahogy korábban említettük, a DriverManager.registerDriver() függvény meghívása az OracleDriver statikus blokkjában regisztrálja az OracleDriver-t, és a getConnection() függvény meghívásával a felhasználó lekérheti a Kapcsolat implementációját.


Ha alaposabban megvizsgáljuk a DriverManager getConnection() metódusának tényleges JDK kódját, akkor látható, hogy a getCallerClass() metódust hívja meg, amely a getCallerClass() metódust hívja meg. Ha a Car osztály hívta a getConnection() metódust, akkor a getCallerClass() a Car osztály objektumát adja vissza.


@CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));


Először a public statikus getConnection() metódust hívják meg, és az url, Properties, és CallerClass paramétereket a private statikus getConnection() metódus paramétereiként adják át. Itt a Reflection.getCallerClass() metódus felelős azért, hogy megkapja azt az osztályt, amely a public statikus getConnection() metódust hívta. Ha például a Car osztály hívta a getConnection() metódust, akkor a Reflection.getCallerClass() meghívásával le tudja kérni az osztály objektumát.


private static Connection getConnection(String url, java.util.Properties info, Class hívóOsztály) throws SQLException {
    ClassLoader hívóCL = hívóOsztály != null ? hívóOsztály.getClassLoader() : null;
    synchronized(DriverManager.class) {
        if (hívóCL == null) {
            hívóCL = Thread.currentThread().getContextClassLoader();
        }
    }

    if(url == null) {
        throw new SQLException("Az url nem lehet null", "08001");
    }

    SQLException ok = null;
    for(DriverInfo aDriver : regisztráltMeghajtók) {
        if(isDriverAllowed(aDriver.meghajtó, hívóCL)) {
            try {
                Connection kapcsolat = aDriver.meghajtó.connect(url, info);
                if (kapcsolat != null) {
                    return (kapcsolat);
                }
            } catch (SQLException ex) {
                if (ok == null) {
                    ok = ex;
                }
            }
        }
    }

    if (ok    != null)    {
        throw ok;
    }
    throw new SQLException("A megadott url-hez nem található megfelelő meghajtó: "+ url, "08001");


Először meghívják a public statikus getConnection() metódust, és az url, a Properties és a CallerClass paramétereket átadják a private statikus getConnection() metódus paramétereiként. Itt a Reflection.getCallerClass() metódus felelős azért, hogy megkapja azt az osztályt, amely a public statikus getConnection() metódust hívta. Ha például a Car osztály hívta a getConnection() metódust, akkor a Reflection.getCallerClass() meghívásával le tudja kérni az osztály objektumát.


JDBC keretrendszer előnyei

A JDBC keretrendszer lényege, hogy a Meghajtó, a Kapcsolat interfész és a megvalósító osztályok teljesen függetlenül vannak megadva. Az interfész használatával egy sablont hozunk létre, és ennek a sablonnak megfelelően különböző implementációjú osztályokat hozhatunk létre. Ez teszi nagymértékben rugalmassá a JDBC keretrendszert.


Ha egy új adatbázis-kezelő (DBMS) jelenik meg, akkor a gyártó megadhatja a Meghajtó és a Kapcsolat interfész implementációját, így a Java-t használó fejlesztők ugyanazt a JDBC API-t használhatják a diferentes DBMS-meghajtókkal.


Statikus gyári módszerek hátrányai

Egy publikus vagy védett konstruktor szükséges az örökléshez, így a statikus gyári metódusok használata esetén nem hozhatunk létre újabb osztályokat.


Ez a korlátozás azonban arra ösztönözhet, hogy az öröklés helyett inkább kompozíciót alkalmazzunk, és ráadásul a beállíthatatlan értékek típusainak megvalósításához is szükséges.


A statikus gyári metódusokat a programozók nehezen találják meg.

Mivel ezeket nem mutatja egyértelműen az API dokumentációban, a fejlesztőknek gondoskodniuk kell arról, hogy jó API-dokumentációt írjanak, és a metódusok neveit a jól ismert konvencióknak megfelelően alakítsák ki.


Statikus gyári metódus nevezési konvenciók

  • from
    • Egy paramétert vesz fel, és a megfelelő típusú példányt adja vissza.
    • Date date = Date.from(instant);
  • of
    • Több paramétert vesz fel, és a megfelelő típusú példányt adja vissza.
    • Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
  • valueOf
    • A from és of részletesebb változata.
    • BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
  • instance vagy getInstance
    • Egy adott példányt ad vissza, amelyet a paraméterként megadtak, de nem garantálja, hogy ez azonos példány lesz.
    • StackWalker luke = StackWalker.getInstance(options);
  • create vagy newInstance
    • Az instance-hez vagy getInstance-hez hasonlóan, de garantálja, hogy mindig új példányt hoz létre.
    • Object newArray = Array.newInstance(classObject, arraylen);
  • type
    • Az getInstance-hez hasonlóan, de a metódust egy másik osztályban definiáljuk, nem pedig abban az osztályban, amelyet létrehozunk.
    • FileStore fs = Files.getFileStore(path);
  • newType
    • A newInstance-hez hasonlóan, de a metódust egy másik osztályban definiáljuk, nem pedig
제이온
제이온
제이온
제이온
[Hatékony Java] 2. elem: Ha a konstruktornak sok paramétere van, fontolja meg a Builder használatát Ha sok paraméterrel rendelkező objektumot hoz létre, a Builder minta használata segít a kód tisztabb és olvashatóbb megírásában. A kötelező paraméterekkel hozzon létre egy Builder objektumot, a setter metódusokkal állítsa be a választható paramétereket, m

2024. április 27.

[Spring] Mi a Filter, Interceptor és Argument Resolver? Fedezze fel a Spring webes alkalmazásokban a kérések feldolgozására használt szűrők, interceperek és Argument Resolver fogalmát és különbségeit. Az egyes funkciók megvalósítási módjainak, használati időpontjainak és előnyeinek/hátrányainak összehasonlító

2024. április 27.

[Hatékony Java] 3. elem: Privát konstruktor vagy felsorolási típus használatával biztosítsd a szingletonságot A Java-ban a szingletonsablon háromféleképpen valósítható meg (közönséges statikus tag, statikus gyármetódus, felsorolási típus). Bemutatjuk ezeknek a módszereknek az előnyeit és hátrányait, valamint az arra vonatkozó figyelmeztetéseket, hogy mi történik,

2024. április 27.

[Nem informatikai szakember, de fejlesztőként akarok túlélni] 14. Gyakran feltett technikai interjúkérdések összefoglalása kezdő fejlesztők számára Útmutató a kezdő fejlesztők számára a technikai interjúra való felkészüléshez. A fő memóriaterület, adatstruktúrák, RDBMS és NoSQL, eljárási és objektumorientált, átírás és túlterhelés, oldalcserélő algoritmusok, folyamatok és szálak, OSI 7-réteg, TCP és
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

2024. április 3.

Logikai adatmodellezés A logikai adatmodellezés a konceptuális adatmodellezésnek a relációs adatbázis-paradigmához igazodó átalakítása, amely magában foglalja az 1:1, 1:N, N:M relációk kezelését, valamint a normalizálás révén az adatintegritás biztosítását. A 1NF, 2NF, 3NF szak
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

2024. április 9.

Koncepcionális adatmodellezés A koncepcionális adatmodellezés az entitások elkülönítésének és az entitások közötti kapcsolatok ERD-ként való ábrázolásának folyamata. Az entitások független információs egységek, az attribútumok pedig az entitások által birtokolt adatok. Az azonosítók e
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

2024. április 8.

[Szinkronitás] Atomi művelet: Memória kerítés és memória sorrendezés Ez a bejegyzés bemutatja, hogyan kell figyelembe venni a memória sorrendet atomi műveletekben, és megmagyarázza a sorrendezési beállítások fontosságát. Bemutatja a Relaxed, Acquire, Release, AcqRel, SecCst és egyéb sorrendezési beállításokat, valamint rés
곽경직
곽경직
곽경직
곽경직
곽경직

2024. április 12.

[Javascript] Az objektum szerkezete (V8) A JavaScript objektumok a V8 motorban a gyors módnak megfelelő szerkezetek szövegéhez optimalizálódnak, vagy szótár módként működnek hash-táblaként, a állapottól függően. A gyors mód gyors, de ha új kulcsot adnak hozzá, vagy elemet törölnek, a szótár módb
곽경직
곽경직
곽경직
곽경직
곽경직

2024. március 18.

Kanban-tábla projekt 2. logikai adatmodellezés A konceptuális adatmodellezés ERD-jén alapuló logikai adatmodellezés lépésenkénti magyarázatával foglalkozik, bemutatva a normalizálás során felmerülő nehézségeket és azok megoldásait. Különösen részletesen foglalkozik a Ticket tábla author_id és responsi
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

2024. április 9.