JavaRush /Java Blog /Random-TK /Bolşy ýaly seriallaşdyrmak. 1-nji bölüm
articles
Dereje

Bolşy ýaly seriallaşdyrmak. 1-nji bölüm

Toparda çap edildi
Bir seretseň, seriallaşdyrma ownuk bir proses ýaly bolup görünýär. Hakykatdanam, has ýönekeý näme bolup biler? Interfeýsi durmuşa geçirmek üçin synpy yglan etdi java.io.Serializable- we hut şu. Synpy kynçylyksyz seriallaşdyryp bilersiňiz. Bolşy ýaly seriallaşdyrmak.  1-nji bölümNazary taýdan bu hakykat. Iş ýüzünde inçelikler köp. Olar öndürijilik, deserializasiýa, synp howpsuzlygy bilen baglanyşykly. Moreene-de köp taraplar bilen. Şeýle inçelikler ara alnyp maslahatlaşylar. Bu makalany aşakdaky böleklere bölmek bolar:
  • Mehanizmleriň inçelikleri
  • Näme üçin zerur?Externalizable
  • Çykyş
  • emma beýleki tarapdan
  • Maglumat howpsuzlygy
  • Obýektiň seriýallaşdyrylmagySingleton
Birinji bölüme geçeliň -

Mehanizmleriň inçelikleri

Ilki bilen çalt sorag. Obýekti seriallaşdyrmak üçin näçe ýol bar? Amaly görkezýär, işläp düzüjileriň 90% -den gowragy bu soraga takmynan birmeňzeş jogap berýär (sözleme çenli) - diňe bir ýol bar. Bu aralykda, olaryň ikisi bar. Hemmesi ikinjisini ýada salmaýar, aýratynlyklary barada düşnükli bir zat aýtmasyn. Bu usullar haýsylar? Her kim birinjisini ýada salýar. Bu eýýäm agzalan ýerine ýetiriş java.io.Serializablewe hiç hili tagallany talap etmeýär. Ikinji usul hem interfeýsi durmuşa geçirmek, ýöne başga bir usul : java.io.Externalizable. Mundan tapawutlylykda java.io.Serializable, durmuşa geçirilmeli iki usul bar - writeExternal(ObjectOutput)we readExternal(ObjectInput). Bu usullarda serializasiýa / deserializasiýa logikasy bar. DüşündirişGeljekde, käwagt ýerine ýetiriş bilen standartlaşdyrma we uzaldylan ýerine ýetiriş bilen serializasiýa Serializablediýerin . ExternalizableBaşga biriteswir. readObjectKesgitlemek we writeObject, sebäbi ýaly adaty seriallaşdyrma gözegçilik opsiýalaryna bilgeşleýin degemok Bu usullar birneme nädogry diýip pikir edýärin. Bu usullar interfeýsde kesgitlenmedi Serializablewe aslynda çäklendirmeleriň üstünde işlemegi we adaty seriallaşdyrmagy çeýe etmegi teklip edýär. ExternalizableÇeýeligi üpjün edýän usullar ilkibaşdan olara gurulýar . Moreene bir sorag bereliň. Adaty seriallaşdyrma hakykatda nähili işleýär java.io.Serializable? We Reflection API arkaly işleýär. Bular. synp meýdanlaryň toplumy hökmünde jikme-jikleşdirilýär, olaryň her biri çykyş akymyna ýazylýar. Bu amalyň ýerine ýetiriş nukdaýnazaryndan amatly däldigi aýdyňdyr. Näçe soňundan anyklarys. Mentionedokarda agzalan iki seriallaşdyrma usulynyň arasynda başga bir uly tapawut bar. Desagny, deserializasiýa mehanizminde. Ulanylanda Serializabledeserializasiýa şeýle ýüze çykýar: bir obýekt üçin ýat bölünýär, şondan soň meýdanlary akymyň bahalary bilen doldurylýar. Obýektiň konstruktory diýilmeýär. Bu ýerde bu ýagdaýa aýratyn garamalydyrys. Bolýar, synpymyz seriallaşdyrylyp bilner. Ene-atasy? Doly islege bagly! Mundan başga-da, bir synpdan miras alsaň Object- ​​ene-atasy hökman serial däl. Meýdanlar hakda hiç zat bilmesek -de Object, olar öz ene-atalarymyzda bolup biler. Olara näme bolar? Serializasiýa akymyna girmezler. Deserializasiýa edenlerinde haýsy gymmatlyklary alarlar? Geliň, bu mysala seredeliň:
package ru.skipy.tests.io;

import java.io.*;

/**
 * ParentDeserializationTest
 *
 * @author Eugene Matyushkin aka Skipy
 * @since 05.08.2010
 */
public class ParentDeserializationTest {

    public static void main(String[] args){
        try {
            System.out.println("Creating...");
            Child c = new Child(1);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            c.field = 10;
            System.out.println("Serializing...");
            oos.writeObject(c);
            oos.flush();
            baos.flush();
            oos.close();
            baos.close();
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            System.out.println("Deserializing...");
            Child c1 = (Child)ois.readObject();
            System.out.println("c1.i="+c1.getI());
            System.out.println("c1.field="+c1.getField());
        } catch (IOException ex){
            ex.printStackTrace();
        } catch (ClassNotFoundException ex){
            ex.printStackTrace();
        }
    }

    public static class Parent {
        protected int field;
        protected Parent(){
            field = 5;
            System.out.println("Parent::Constructor");
        }
        public int getField() {
            return field;
        }
    }

    public static class Child extends Parent implements Serializable{
        protected int i;
        public Child(int i){
            this.i = i;
            System.out.println("Child::Constructor");
        }
        public int getI() {
            return i;
        }
    }
}
Aç-açan - bizde seriallaşdyrylmaýan ene-atalar synpy we serializasiýa edilip bilinýän çaga synpy bar. Ine, şeýle bolýar:
Creating...
Parent::Constructor
Child::Constructor
Serializing...
Deserializing...
Parent::Constructor
c1.i=1
c1.field=5
Desagny deserializasiýa wagtynda ene-atanyň NON-serializable synpynyň parametrleri bolmadyk konstruktor diýilýär . Şeýle konstruktor ýok bolsa, deserializasiýa wagtynda ýalňyşlyk ýüze çykar. Çaga desgasynyň konstruktory, ýokarda aýdylyşy ýaly atlandyrylmaýar. Ulanylanda adaty mehanizmleriň özüni alyp barşy Serializable. Ulanylanda Externalizableýagdaý başgaçarak. Ilki bilen parametrleri bolmadyk konstruktor diýilýär, soň bolsa ähli maglumatlary okaýan döredilen obýektde “ReadExternal” usuly çagyrylýar. Şonuň üçin “Externalizable” interfeýsini durmuşa geçirýän islendik synpda parametrleri bolmadyk köpçülikleýin konstruktor bolmaly! Mundan başga-da, şunuň ýaly synpyň ähli nesilleri interfeýsi durmuşa geçirmek üçin hasap ediljekdigi sebäpli Externalizable, olarda parametrsiz konstruktor hem bolmaly! Geliň. Aaly meýdan üýtgediji bar transient. Bu meýdanyň seriallaşdyrylmaly däldigini aňladýar. Şeýle-de bolsa, özüňizem düşünşiňiz ýaly, bu görkezme diňe adaty seriallaşdyryş mehanizmine täsir edýär. Ulanylanda, Externalizablehiç kim bu ugry seriallaşdyrmak, aýyrmak ýaly azar bermeýär. Bir meýdan wagtlaýyn diýlip yglan edilse, obýekt deserializasiýa edilende, deslapky bahany alýar. Anotherene bir inçe nokat. Adaty seriallaşdyrma bilen, üýtgediji bolan meýdanlar staticseriýalaşdyrylmaýar. Şoňa laýyklykda deserializasiýa edilenden soň bu meýdan gymmatyny üýtgetmeýär. Elbetde, durmuşa geçirilende Externalizablehiç kim bu ugry seriallaşdyrmak we deserializasiýa etmek bilen gyzyklanmaýar, ýöne muny etmezligi maslahat berýärin, sebäbi inçe ýalňyşlyklara sebäp bolup biler. Üýtgediji meýdanlar finalyzygiderli bolşy ýaly seriýalaşdyrylýar. Bir kadadan çykma bilen - “Externalizable” ulanylanda deserializasiýa edilip bilinmez. Sebäbi final-поляolar konstruktorda başlamaly we şondan soň “ReadExternal” -da bu meýdanyň bahasyny üýtgetmek mümkin bolmaz. Şoňa görä-de, meýdany bolan bir obýekti seriallaşdyrmak zerur bolsa final, diňe standart seriallaşdyrma ulanmaly bolarsyňyz. Köp adamyň bilmeýän başga bir nokady. Standart seriallaşdyrma meýdanlaryň synpda yglan ediliş tertibini göz öňünde tutýar. Her niçigem bolsa, öňki wersiýalarda şeýle bolupdy; Oracle ýerine ýetirişiniň JVM 1.6 wersiýasynda buýruk indi möhüm däl, meýdanyň görnüşi we ady möhümdir. Usullaryň düzümi, meýdanlaryň köplenç üýtgewsiz galyp biljekdigine garamazdan, adaty mehanizme täsir etmegi gaty ähtimal. Munuň öňüni almak üçin aşakdaky mehanizm bar. Interfeýsi amala aşyrýan her bir klasa Serializable, jemleme tapgyrynda ýene bir meýdan goşulýar -private static final long serialVersionUID. Bu meýdan seriallaşdyrylan synpyň özboluşly wersiýa kesgitleýjisini öz içine alýar. Synpyň mazmuny - meýdanlar, beýannama tertibi, usullary, beýannama tertibi esasynda hasaplanýar. Şoňa laýyklykda synpdaky islendik üýtgeşiklik bilen bu meýdan gymmatyny üýtgeder. Bu meýdan synp seriallaşdyrylanda akym üçin ýazylýar. staticTheeri gelende aýtsak, bu , bir meýdan seriýaly edilende maňa mälim bolan ýeke-täk ýagdaýdyr . Deserializasiýa wagtynda bu meýdanyň gymmaty wirtual maşynyň synpy bilen deňeşdirilýär. Gymmatlyklar gabat gelmese, şuňa meňzeş kadadan çykma atylýar:
java.io.InvalidClassException: test.ser2.ChildExt;
    local class incompatible: stream classdesc serialVersionUID = 8218484765288926197,
                                   local class serialVersionUID = 1465687698753363969
Şeýle-de bolsa, bu aýlawy aldamak üçin bir ýol bar. Synp meýdanlarynyň toplumy we tertibi eýýäm kesgitlenen bolsa, peýdaly bolup biler, ýöne synp usullary üýtgäp biler. Bu ýagdaýda seriýalaşdyrmak howp astynda däl, ýöne adaty mehanizm üýtgedilen synpyň kod koduny ulanyp maglumatlaryň deserializasiýa edilmegine ýol bermez. , Öne aýdyşym ýaly, ony aldap bolar. .Agny, synpdaky meýdany el bilen kesgitläň private static final long serialVersionUID. Aslynda, bu ugurdaky baha düýbünden islendik zat bolup biler. Käbir adamlar koduň üýtgedilen senesine deň goýmagy makul bilýärler. Käbirleri hatda 1L ulanýarlar. Adaty bahany (içerde hasaplanylýan) almak üçin, SDK-a goşulan serwer hyzmatyny ulanyp bilersiňiz. Bu ýol kesgitlenenden soň, meýdanyň gymmaty kesgitlener, şonuň üçin deserializasiýa elmydama rugsat berler. Mundan başga-da, 5.0 wersiýasynda resminamalarda takmynan aşakdakylar peýda boldy: seriallaşdyrylýan synplaryň hemmesine bu ugry aç-açan yglan etmek maslahat berilýär, sebäbi deslapky hasaplama, düzüjiniň ýerine ýetirilişine baglylykda üýtgäp bilýän synp gurluşynyň jikme-jikliklerine gaty duýgur, we şeýlelik bilen garaşylmadyk InvalidClassExceptionnetijelere sebäp bolýar. Bu ugry yglan etmek has gowudyr private, sebäbi diňe yglan edilen klasa degişlidir. Modifikator spesifikasiýada görkezilmedik bolsa-da. Geliň indi bu meselä seredeliň. Bu synp gurluşymyz bar diýeliň:
public class A{
    public int iPublic;
    protected int iProtected;
    int iPackage;
    private int iPrivate;
}

public class B extends A implements Serializable{}
Başgaça aýdylanda, seriallaşdyrylmaýan ene-atadan miras galan synpymyz bar. Bu synpy seriallaşdyrmak mümkinmi we munuň üçin näme gerek? Ene synpynyň üýtgeýänleri bilen näme bolar? Jogap şu. Hawa, Bsynpyň mysalyny seriallaşdyryp bilersiňiz. Munuň üçin näme gerek? Emma synpda Aparametrleri bolmadyk konstruktor bolmaly, publicýa-da protected. Soňra deserializasiýa wagtynda ähli konstruktor Abu konstruktoryň kömegi bilen başlar. Synp üýtgeýjileri Byzygiderli maglumat akymynyň bahalary bilen başlar. BNazary taýdan, synpda başda readObjectwe writeObject- başynda synp üýtgeýjileriniň seriallaşdyrylmagyny (soňundan), soňra bolsa elýeterli üýtgeýänleriň seriýalaşdyrylmagyny ýerine Býetiren in.defaultReadObject/out.defaultWriteObjectusullarymy kesgitlemek mümkin. synpdan A(biziň ýagdaýymyzda bular iPublic, iProtectedwe şol bir paketde bolsa iPackage) . Şeýle-de bolsa, meniň pikirimçe, munuň üçin giňeldilen serializasiýa ulanmak has gowudyr. Indiki degip geçmek isleýän zadym, birnäçe obýektiň seriallaşdyrylmagy. Aşakdaky synp gurluşymyz bar diýeliň: BA
public class A implements Serializable{
    private C c;
    private B b;
    public void setC(C c) {this.c = c;}
    public void setB(B b) {this.b = b;}
    public C getC() {return c;}
    public B getB() {return b;}
}
public class B implements Serializable{
    private C c;
    public void setC(C c) {this.c = c;}
    public C getC() {return c;}
}
public class C implements Serializable{
    private A a;
    private B b;
    public void setA(A a) {this.a = a;}
    public void setB(B b) {this.b = b;}
    public B getB() {return b;}
    public A getA() {return a;}
}
Bolşy ýaly seriallaşdyrmak.  1-nji bölümSynpyň mysalyny seriýalasaň näme bolýar A? Synpyň bir mysaly boýunça süýrär , bu bolsa öz gezeginde mysaly salgylanmasy bolan , hemmesiniň başlanan görnüşi bilen Bsüýrär . Erbet tegelek we çäksiz gaýtalanma? Bagtymyza, ýok. Aşakdaky synag koduna seredeliň: CA
// initiaizing
A a = new A();
B b = new B();
C c = new C();
// setting references
a.setB(b);
a.setC(c);
b.setC(c);
c.setA(a);
c.setB(b);
// serializing
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(a);
oos.writeObject(b);
oos.writeObject(c);
oos.flush();
oos.close();
// deserializing
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
A a1 = (A)ois.readObject();
B b1 = (B)ois.readObject();
C c1 = (C)ois.readObject();
// testing
System.out.println("a==a1: "+(a==a1));
System.out.println("b==b1: "+(b==b1));
System.out.println("c==c1: "+(c==c1));
System.out.println("a1.getB()==b1: "+(a1.getB()==b1));
System.out.println("a1.getC()==c1: "+(a1.getC()==c1));
System.out.println("b1.getC()==c1: "+(b1.getC()==c1));
System.out.println("c1.getA()==a1: "+(c1.getA()==a1));
System.out.println("c1.getB()==b1: "+(c1.getB()==b1));
Biz näme edýäris? Sapaklaryň mysalyny döredýäris Awe olara biri-birine baglanyşyk berýäris, soňra bolsa olaryň hersini seriallaşdyrýarys B. CSoň bolsa olary deserializasiýa edýäris we birnäçe barlag geçirýäris. Netijede näme bolar:
a==a1: false
b==b1: false
c==c1: false
a1.getB()==b1: true
a1.getC()==c1: true
b1.getC()==c1: true
c1.getA()==a1: true
c1.getB()==b1: true
Bu synagdan näme öwrenip bilersiňiz? Ilki bilen. Deserializasiýa edilenden soň obýekt salgylanmalary, ozalky salgylanmalardan tapawutlanýar. Başgaça aýdylanda, serializasiýa / deserializasiýa wagtynda obýekt göçürildi. Bu usul käwagt obýektleri klonlamak üçin ulanylýar. Ikinji netije has möhümdir. Haçanda salgylanmalary bolan birnäçe obýekti seriallaşdyrmak / deserializasiýa etmekde, bu salgylanmalar deserializasiýa edilenden soň güýje girýär. Başga bir söz bilen aýdylanda, seriallaşdyrmazdan ozal bir obýekti görkezen bolsalar, deserializasiýa edilenden soň bir obýekti hem görkezerler. Muny tassyklamak üçin başga bir kiçijik synag:
B b = new B();
C c = new C();
b.setC(c);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(b);
oos.writeObject(c);
oos.writeObject(c);
oos.writeObject(c);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
B b1 = (B)ois.readObject();
C c1 = (C)ois.readObject();
C c2 = (C)ois.readObject();
C c3 = (C)ois.readObject();
System.out.println("b1.getC()==c1: "+(b1.getC()==c1));
System.out.println("c1==c2: "+(c1==c2));
System.out.println("c1==c3: "+(c1==c3));
Synp obýektinde Bsynp obýektine salgylanma bar C. Seriallaşdyrylanda, bsynpyň mysaly bilen bilelikde seriýalaşdyrylýar С, şondan soň şol bir mysal c üç gezek seriýalanýar. Deserializasiýa edilenden soň näme bolýar?
b1.getC()==c1: true
c1==c2: true
c1==c3: true
Görşüňiz ýaly, deserializasiýa edilen dört jisimiň hemmesi aslynda bir obýekti aňladýar - oňa salgylanmalar deňdir. Serializasiýa edil öňküsi ýaly. ExternalizableAnotherene bir gyzykly nokat - şol bir wagtyň özünde durmuşa geçirsek näme bolar Serializable? Bu soragdaky ýaly - pil bilen kit - kim ýeňer? .Eňer Externalizable. Seriýalaşdyrmak mehanizmi ilki bilen onuň barlygyny, soň bolsa diňe barlygyny barlaýar. SerializableŞeýlelik bilen, ýerine ýetirýän B synpy Serializable, ýerine ýetirýän A synpyndan miras galan bolsa Externalizable, B synpyň meýdanlary seriýalaşdyrylmaz. Iň soňky nokat miras. Durmuşa geçirýän synpdan miras alanyňyzda Serializablegoşmaça çäreler görülmeli däldir. Seriýalaşdyrma çaga synpyna-da girer. Durmuşa geçirýän synpdan miras alanyňyzda Externalizable, ene synpyň “ExEternal” we “ExEternal” usullaryny ýok etmeli. Otherwiseogsam, çaga synpynyň meýdanlary seriallaşdyrylmaz. Bu ýagdaýda ene-atanyň usullaryny çagyrmagy ýatdan çykarmaly bolarsyňyz, ýogsam ene meýdanlary seriallaşdyrylmaz. * * * Jikme-jiklikler bilen tamamlan bolmagymyz ahmal. Şeýle-de bolsa, dünýä häsiýetine degmedik bir mesele bar. Elyagny -

Näme üçin “Externalizable” gerek?

Näme üçin asla ösen serializasiýa gerek? Jogap ýönekeý. Birinjiden, has çeýeligi berýär. Ikinjiden, köplenç yzygiderli maglumatlaryň göwrümi taýdan ep-esli girdeji berip biler. Üçünjiden, aşakda gürleşjek ýerine ýetiriş ýaly bir tarap bar . Hemme zat çeýeligi bilen düşnükli ýaly. Hakykatdanam, synpdaky islendik üýtgeşmelerden garaşsyz bolýan serializasiýa we deserializasiýa proseslerine gözegçilik edip bileris (ýokarda aýdyşym ýaly, synpdaky üýtgeşmeler deserializasiýa täsir edip biler). Şonuň üçin göwrümiň artmagy barada birnäçe söz aýdasym gelýär. Aşakdaky synpymyz bar diýeliň:
public class DateAndTime{

  private short year;
  private byte month;
  private byte day;
  private byte hours;
  private byte minutes;
  private byte seconds;

}
Galanlary möhüm däl. Meýdanlar int görnüşinden ýasalyp bilner, ýöne bu diňe mysalyň täsirini ýokarlandyrar. Aslynda meýdanlar intöndürijilik sebäpleri bilen ýazylyp bilner. Her niçigem bolsa, mesele aýdyňdyr. Synp senäni we wagty aňladýar. Ilki bilen seriallaşdyrma nukdaýnazaryndan gyzykly. Perhapshtimal, iň aňsat zat ýönekeý wagt belligini saklamakdyr. Uzyn görnüşli, ýagny seriallaşdyrylanda 8 baýt gerek bolar. Mundan başga-da, bu çemeleşme komponentleri bir baha we yza öwürmek usullaryny talap edýär, ýagny. - öndürijiligiň ýitmegi. Bu çemeleşmäniň artykmaçlygy, 64 bitde ýerleşip bilýän düýbünden däli sene. Bu, hakykatdanam hakykatda zerur däl ägirt uly aralyk. Aboveokarda berlen synp 2 + 5 * 1 = 7 baýt alar. Mundan başga-da synp we 6 meýdança. Bu maglumatlary gysmagyň usuly barmy? Elbetde. Sekuntlar we minutlar 0-59 aralygynda. olary görkezmek üçin 8 bit ýerine 6 bit ýeterlikdir. Sagatlar - 0-23 (5 bit), günler - 0-30 (5 bit), aýlar - 0-11 (4 bit). Jemi, ýyly göz öňünde tutman hemme zat - 26 bit. Int ululygyna henizem 6 bit galdy. Nazary taýdan, käbir ýagdaýlarda bu bir ýyl ýeterlik bolup biler. Notok bolsa, başga bir baýt goşmak, maglumatlar meýdanynyň göwrümini 14 bite çenli ýokarlandyrýar, bu bolsa 0-16383 aralygy berýär. Bu hakyky programmalarda ýeterlik däl. Umuman, zerur maglumatlary saklamak üçin zerur maglumatlaryň göwrümini 5 baýt azaltdyk. 4-e ýetmese, ýetmezçiligi öňki ýagdaýdaky ýaly - eger senäni gaplanan görnüşde saklasaň, öwürmek usullary zerurdyr. Iöne muny şeýle etmek isleýärin: ony aýratyn meýdanlarda saklaň we gaplanan görnüşde seriýalaň. Ulanyşyň manysy şu Externalizable:
// data is packed into 5 bytes:
//  3         2         1
// 10987654321098765432109876543210
// hhhhhmmmmmmssssssdddddMMMMyyyyyy yyyyyyyy
public void writeExternal(ObjectOutput out){
    int packed = 0;
    packed += ((int)hours) << 27;
    packed += ((int)minutes) << 21;
    packed += ((int)seconds) << 15;
    packed += ((int)day) << 10;
    packed += ((int)month) << 6;
    packed += (((int)year) >> 8) & 0x3F;
    out.writeInt(packed);
    out.writeByte((byte)year);
}

public void readExternal(ObjectInput in){
    int packed = in.readInt();
    year = in.readByte() & 0xFF;
    year += (packed & 0x3F) << 8;
    month = (packed >> 6) & 0x0F;
    day = (packed >> 10) & 0x1F;
    seconds = (packed >> 15) & 0x3F;
    minutes = (packed >> 21) & 0x3F;
    hours = (packed >> 27);
}
Aslynda bu hemmesi. Seriýalaşandan soň, her synp üçin iki meýdan (6 ýerine) we 5 baýt maglumat alýarys. Bu eýýäm ep-esli gowudyr. Goşmaça gaplama ýöriteleşdirilen kitaphanalara galdyrylyp bilner. Berlen mysal gaty ýönekeý. Esasy maksady, seriallaşdyrmagyň näderejede ulanylyp bilinjekdigini görkezmek. Seriýalaşdyrylan maglumatlaryň göwrüminde bolup biljek girdeji esasy artykmaçlykdan uzak bolsa-da, meniň pikirimçe. Çeýelige goşmaça esasy artykmaçlyk ... (indiki bölüme aňsatlyk bilen geçiň ...) Çeşmä baglanyşyk: Serializasiýa
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION