portaldacalheta.pt
  • Glavni
  • Trendi
  • Orodja In Vaje
  • Življenjski Slog
  • Oblikovanje Blagovne Znamke
Tehnologija

Lahka toleranca sočasnosti in napak: Vadnica Akka s primeri



Izziv

Pisanje sočasni programi je težko. Obravnavanje niti, ključavnic, dirkalnih pogojev itd. Je zelo nagnjeno k napakam in lahko vodi do kode, ki jo je težko prebrati, preizkusiti in vzdrževati.

Mnogi se zato raje izogibajo večnitnosti. Namesto tega uporabljajo izključno enonitne procese, pri čemer se zanašajo na zunanje storitve (kot so zbirke podatkov, čakalne vrste itd.) Za obdelavo vseh potrebnih sočasnih ali asinhronih operacij. Čeprav je ta pristop v nekaterih primerih legitimna alternativa, obstaja veliko scenarijev, v katerih preprosto ni izvedljiva možnost. Številni sistemi v realnem času - na primer trgovalne ali bančne aplikacije ali igre v realnem času - nimajo razkošja, da bi čakali, da se postopek z enim navojem zaključi (odgovor potrebujejo zdaj!). Drugi sistemi so tako zahtevni za računalnike ali vire, da bi jim trajal neomejen čas (v nekaterih primerih ure ali celo dnevi), ne da bi v njihovo kodo uvedli paralelizacijo.



Eden dokaj pogostih enonitnih pristopov (pogosto uporabljen v Node.js svetu) na primer uporabiti paradigmo, ki ne blokira dogodkov. Čeprav to pomaga pri zmogljivosti z izogibanjem stikalom, zaklepanjem in blokiranjem konteksta, še vedno ne obravnava težav pri sočasni uporabi več procesorjev (če bi to zahtevalo zagon in usklajevanje več neodvisnih procesov).



c corporation vs s corporation na w9

Torej to pomeni, da vam ni preostalo drugega, kot da potujete globoko v drobovje niti, ključavnic in dirkalnih pogojev, da ustvarite sočasno aplikacijo?



Zahvaljujoč ogrodju Akka je odgovor ne. Ta vadnica predstavlja primere Akka in raziskuje načine, kako olajšuje in poenostavlja izvajanje sočasnih porazdeljenih aplikacij.

Kaj je Akka Framework?

Ta objava predstavlja Akko in raziskuje načine, kako olajšuje in poenostavlja izvajanje sočasnih porazdeljenih aplikacij.

Akka je komplet orodij in izvajalno okolje za izdelavo zelo sočasnih, porazdeljenih in odpornih aplikacij na JVM. Akka je napisan v jeziku Lestev , z jezikovnimi vezmi, zagotovljenimi tako za Scalo kot za Javo.



Akkin pristop k sočasni obravnavi temelji na Igralski model . V sistemu, ki temelji na igralcu, je vse igralec, podobno kot je vse predmet v objektno usmerjenem oblikovanju. Ključna razlika, ki je še posebej pomembna za našo razpravo, je, da je bil igralski model posebej zasnovan in oblikovan tako, da služi kot sočasni model, medtem ko objektno usmerjeni model ni. Natančneje, v sistemu igralcev Scala igralci sodelujejo in si izmenjujejo informacije brez kakršne koli predpostavke zaporednosti. Mehanizem, s katerim si akterji izmenjujejo informacije in si nalagajo drug drugega, je posredovanje sporočil.

Vsa zapletenost ustvarjanja in razporejanja niti, sprejemanja in odpošiljanja sporočil ter ravnanja z dirkalnimi pogoji in sinhronizacijo je za pregledno obdelavo prenesena v ogrodje.

Akka ustvarja plast med igralci in osnovnim sistemom, tako da morajo igralci preprosto obdelovati sporočila. Vsa zapletenost ustvarjanja in razporejanja niti, sprejemanja in odpošiljanja sporočil ter ravnanja z dirkalnimi pogoji in sinhronizacijo je za pregledno obdelavo prenesena v ogrodje.



Akka se dosledno drži Reaktivni manifest . Cilj reaktivnih aplikacij je nadomestiti tradicionalne večnitne programe z arhitekturo, ki izpolnjuje eno ali več naslednjih zahtev:

  • Nagnjeni k dogodkom. Z uporabo igralcev lahko napišemo kodo, ki asinhrono obravnava zahteve in uporablja izključno neblokirajoče operacije.
  • Prilagodljivo. V programu Akka je dodajanje vozlišč brez spreminjanja kode možno tako zaradi prenosa sporočil kot tudi zaradi preglednosti lokacije.
  • Odporna. Vsaka aplikacija bo v določenem trenutku naletela na napake in odpovedala. Akka ponuja strategije nadzora (odpornosti na napake), da olajša sistem samozdravljenja.
  • Odziven. Številne današnje visoko zmogljive in hitre odzivne aplikacije morajo uporabniku dati hitre povratne informacije, zato se morajo na dogodke odzvati izjemno pravočasno. Akkova strategija, ki ne blokira in temelji na sporočilih, pomaga doseči to.

Kaj je igralec v Akki?

Igralec v bistvu ni nič drugega kot objekt, ki sprejema sporočila in ukrepa z njimi. Ločeno je od vira sporočila in njegova edina odgovornost je pravilno prepoznati vrsto sporočila, ki ga je prejelo, in ustrezno ukrepati.



Po prejemu sporočila lahko igralec izvede eno ali več od naslednjih dejanj:

  • Izvedite nekatere operacije sami (na primer izvajanje izračunov, trajnih podatkov, klicanje zunanje spletne storitve itd.)
  • Sporočilo ali izpeljano sporočilo posreduje drugemu igralcu
  • Instancirajte novega igralca in mu posredujte sporočilo

Igralec se lahko odloči, da bo sporočilo popolnoma prezrl (tj. Lahko izbere nedejavnost), če se mu to zdi primerno.



Za izvedbo igralca je treba razširiti lastnost akka.actor.Actor in uporabiti metodo sprejemanja. Način sprejema igralca se prikliče (Akka), ko se temu igralcu pošlje sporočilo. Njegova tipična izvedba je sestavljena iz ujemanja vzorcev, kot je prikazano v naslednjem primeru Akka, za prepoznavanje vrste sporočila in ustrezno odzivanje:

import akka.actor.Actor import akka.actor.Props import akka.event.Logging class MyActor extends Actor { def receive = { case value: String => doSomething(value) case _ => println('received unknown message') } }

Ujemanje vzorcev je sorazmerno elegantna tehnika za obdelavo sporočil, ki ponavadi ustvari 'čistejšo' in enostavnejšo navigacijo po kodi kot primerljiva izvedba, ki temelji na povratnih klicih. Razmislite na primer o poenostavljeni izvedbi zahteve / odgovora HTTP.



Najprej izvedimo to z uporabo paradigme, ki temelji na povratnem klicu v JavaScript:

route(url, function(request){ var query = buildQuery(request); dbCall(query, function(dbResponse){ var wsRequest = buildWebServiceRequest(dbResponse); wsCall(wsRequest, function(wsResponse) { sendReply(wsResponse); }); }); });

Zdaj pa primerjajmo to z izvedbo, ki temelji na ujemanju vzorcev:

msg match { case HttpRequest(request) => { val query = buildQuery(request) dbCall(query) } case DbResponse(dbResponse) => { var wsRequest = buildWebServiceRequest(dbResponse); wsCall(dbResponse) } case WsResponse(wsResponse) => sendReply(wsResponse) }

Čeprav je koda JavaScript, ki temelji na povratnem klicu, sicer kompaktna, jo je vsekakor težje brati in krmariti. V primerjavi s kodo, ki temelji na ujemanju vzorcev, je takoj videti, kateri primeri se obravnavajo in kako se z njimi ravna.

Igralski sistem

Če zapletemo problem in ga rekurzivno razdelimo na manjše podprobleme, je na splošno dobra tehnika reševanja problemov. Ta pristop je lahko še posebej koristen v računalništvu (v skladu z Načelo enotne odgovornosti ), saj ponavadi daje čisto modularizirano kodo z malo ali nič odvečnosti, ki jo je relativno enostavno vzdrževati.

Pri zasnovi, ki temelji na igralcu, uporaba te tehnike olajša logično organizacijo igralcev v hierarhično strukturo, znano kot Igralski sistem . Sistem igralcev zagotavlja infrastrukturo, prek katere igralci medsebojno komunicirajo.

Primer načina delovanja sistema igralcev v okviru Akka.

V Akki je edini način za komunikacijo z igralcem prek ActorRef. An ActorRef predstavlja sklic na igralca, ki drugim predmetom preprečuje neposreden dostop do notranjosti in stanja tega igralca ali njegovo manipulacijo. Sporočila lahko igralcu pošljete prek ActorRef z uporabo enega od naslednjih sintaksnih protokolov:

  • ! (“Povej”) - pošlje sporočilo in se takoj vrne
  • ? (»Vprašaj«) - pošlje sporočilo in vrne a Prihodnost predstavlja možen odgovor

Vsak igralec ima nabiralnik, v katerega so dostavljena njegova dohodna sporočila. Izbirate lahko med več izvedbami nabiralnikov, privzeta izvedba pa je FIFO.

Igralec vsebuje veliko spremenljivk primerka za vzdrževanje stanja med obdelavo več sporočil. Akka zagotavlja, da vsak primerek igralca deluje v svoji lahki niti in da se sporočila obdelujejo eno za drugo. Na ta način je mogoče zanesljivo vzdrževati stanje vsakega igralca, ne da bi se moral razvijalec izrecno skrbeti za sinhronizacijo ali dirkalne pogoje.

Vsakemu igralcu so prek Akka Actor API na voljo naslednje koristne informacije za izvajanje njegovih nalog:

  • sender: an ActorRef pošiljatelju sporočila, ki se trenutno obdeluje
  • context: informacije in metode, ki se nanašajo na kontekst, v katerem deluje izvajalec (vključuje na primer actorOf metodo za ustvarjanje novega akterja)
  • supervisionStrategy: določa strategijo, ki se uporablja za obnovo po napakah
  • self: ActorRef za samega igralca
Akka zagotavlja, da vsak primerek igralca deluje v svoji lahki niti in da se sporočila obdelujejo eno za drugo. Na ta način je mogoče zanesljivo vzdrževati stanje vsakega igralca, ne da bi se moral razvijalec izrecno skrbeti za sinhronizacijo ali dirkalne pogoje.

Za lažje povezovanje teh vadnic si oglejmo preprost primer štetja števila besed v besedilni datoteki.

Za namene našega primera Akka bomo problem razložili na dve podopravili; in sicer (1) naloga otroka za štetje števila besed v eni vrstici in (2) naloga nadrejenega seštevanja števila besed v vrstici, da dobimo skupno število besed v datoteki.

Nadrejeni igralec bo naložil vsako vrstico iz datoteke in nato nadrejenemu igralcu dodal nalogo štetja besed v tej vrstici. Ko je otrok končan, bo staršu poslal sporočilo z rezultatom. Nadrejeni bo prejel sporočila s številom besed (za vsako vrstico) in obdržal števec celotnega števila besed v celotni datoteki, ki ga bo po zaključku vrnil klicatelju.

(Upoštevajte, da so spodaj navedeni vzorci učnih kod Akka namenjeni zgolj didaktični in se zato ne nanašajo nujno na vse robne pogoje, optimizacije zmogljivosti itd. V nadaljevanju je na voljo tudi celotna združljiva različica vzorčnih kod, prikazana spodaj to bistvo .)

Oglejmo si najprej vzorčno izvedbo otroka StringCounterActor razred:

case class ProcessStringMsg(string: String) case class StringProcessedMsg(words: Integer) class StringCounterActor extends Actor { def receive = { case ProcessStringMsg(string) => { val wordsInLine = string.split(' ').length sender ! StringProcessedMsg(wordsInLine) } case _ => println('Error: message not recognized') } }

Ta igralec ima zelo preprosto nalogo: porabi ProcessStringMsg sporočila (ki vsebujejo vrstico besedila), preštejte število besed v določeni vrstici in vrnite rezultat pošiljatelju prek StringProcessedMsg sporočilo. Upoštevajte, da smo svoj razred uvedli tako, da uporablja ! (»Povej«) za pošiljanje StringProcessedMsg sporočilo (tj. poslati sporočilo in se takoj vrniti).

V redu, zdaj se osredotočimo na starša WordCounterActor razred:

1. case class StartProcessFileMsg() 2. 3. class WordCounterActor(filename: String) extends Actor { 4. 5. private var running = false 6. private var totalLines = 0 7. private var linesProcessed = 0 8. private var result = 0 9. private var fileSender: Option[ActorRef] = None 10. 11. def receive = { 12. case StartProcessFileMsg() => { 13. if (running) { 14. // println just used for example purposes; 15. // Akka logger should be used instead 16. println('Warning: duplicate start message received') 17. } else { 18. running = true 19. fileSender = Some(sender) // save reference to process invoker 20. import scala.io.Source._ 21. fromFile(filename).getLines.foreach { line => 22. context.actorOf(Props[StringCounterActor]) ! ProcessStringMsg(line) 23. totalLines += 1 24. } 25. } 26. } 27. case StringProcessedMsg(words) => { 28. result += words 29. linesProcessed += 1 30. if (linesProcessed == totalLines) { 31. fileSender.map(_ ! result) // provide result to process invoker 32. } 33. } 34. case _ => println('message not recognized!') 35. } 36. }

Tu se dogaja veliko stvari, zato jih podrobneje preučimo (upoštevajte, da številke vrstic, navedene v razpravi, ki sledi, temeljijo na zgornjem vzorcu kode) ...

Najprej opazite, da se ime datoteke, ki jo želite obdelati, posreduje na WordCounterActor konstruktor (vrstica 3). To pomeni, da se igralec uporablja samo za obdelavo ene datoteke. To razvijalcu tudi poenostavi nalogo kodiranja, tako da se izogne ​​potrebi po ponastavitvi spremenljivk stanja (running, totalLines, linesProcessed in result), ko je opravilo končano, ker se primerek uporablja samo enkrat (tj. za obdelavo ene datoteke) in nato zavrže.

Nato opazite, da WordCounterActor obravnava dve vrsti sporočil:

naštej in razloži tri pravila zaznavne organizacije
  • StartProcessFileMsg (vrstica 12)
    • Prejeto od zunanjega akterja, ki na začetku sproži WordCounterActor.
    • Ko prejme, WordCounterActor najprej preveri, ali ne prejema odvečne zahteve.
    • Če je zahteva odvečna, WordCounterActor ustvari opozorilo in nič več se ne naredi (vrstica 16).
    • Če zahteva ni odvečna:
      • WordCounterActor sklic na pošiljatelja shrani v fileSender spremenljivka primerka (upoštevajte, da je to Option[ActorRef] in ne Option[Actor] - glejte vrstico 9). To ActorRef je potreben za kasnejši dostop do njega in odziv nanj pri obdelavi končnega StringProcessedMsg (ki ga prejme otrok StringCounterActor, kot je opisano spodaj).
      • WordCounterActor nato prebere datoteko in, ko je vsaka vrstica v datoteki naložena, StringCounterActor otrok se ustvari in mu se posreduje sporočilo, ki vsebuje vrstico, ki jo je treba obdelati (vrstice 21-24).
  • StringProcessedMsg (vrstica 27)
    • Prejeto od otroka StringCounterActor ko zaključi z obdelavo vrstice, ki mu je dodeljena.
    • Ko prejme, WordCounterActor poveča števec vrstic za datoteko in, če so vse vrstice v datoteki obdelane (tj. ko so totalLines in linesProcessed enake), pošlje končni rezultat izvirniku fileSender (vrstice 28-31).

Še enkrat opazimo, da je v Akki edini mehanizem za komunikacijo med akterji prenašanje sporočil. Sporočila so edina stvar, ki si jo delijo igralci, in ker lahko igralci lahko istočasno dostopajo do istih sporočil, je pomembno, da so nespremenljivi, da bi se izognili dirkalnim pogojem in nepričakovanemu vedenju.

Razredi primerov v Scali so redni razredi, ki z ujemanjem vzorcev zagotavljajo mehanizem rekurzivne razgradnje.

Zato je običajno, da sporočila posredujemo v obliki razredov primerov, saj so privzeto nespremenljiva in zaradi tega, kako neopazno se integrirajo z ujemanjem vzorcev.

Zaključimo primer z vzorcem kode za zagon celotne aplikacije.

object Sample extends App { import akka.util.Timeout import scala.concurrent.duration._ import akka.pattern.ask import akka.dispatch.ExecutionContexts._ implicit val ec = global override def main(args: Array[String]) { val system = ActorSystem('System') val actor = system.actorOf(Props(new WordCounterActor(args(0)))) implicit val timeout = Timeout(25 seconds) val future = actor ? StartProcessFileMsg() future.map { result => println('Total number of words ' + result) system.shutdown } } } Pri sočasnem programiranju je 'prihodnost' v bistvu nadomestni objekt za rezultat, ki še ni znan.

Opazite, kako je tokrat ? za pošiljanje sporočila. Na ta način lahko klicatelj uporabi vrnjeno Prihodnost za tiskanje končnega rezultata, ko je ta na voljo, in za izhod iz programa z izklopom sistema ActorSystem.

Akka odpornost na napake in nadzorniške strategije

V igralčevem sistemu je vsak igralec nadzornik svojih otrok. Če igralec ne obdeluje sporočila, začasno ustavi sebe in vse svoje otroke in nadzorniku pošlje sporočilo, običajno v obliki izjeme.

V programu Akka so nadzorniške strategije primarni in enostaven mehanizem za določanje odpornega vedenja vašega sistema.

V Akki je način, na katerega se nadzornik odzove in obravnava izjeme, ki jih prenašajo njegovi otroci, omenjen kot strategija nadzornika. Supervizijske strategije so primarni in enostaven mehanizem, s katerim določite obnašanje vašega sistema, odpornega proti napakam.

Ko sporočilo, ki pomeni napako, prispe do nadzornika, lahko izvede eno od naslednjih dejanj:

  • Nadaljujte z otrokom (in njegovimi otroki), pri čemer ohranite njegovo notranje stanje. To strategijo je mogoče uporabiti, kadar podrejena država zaradi napake ni bila poškodovana in lahko še naprej pravilno deluje.
  • Znova zaženite otroka (in njegove otroke), tako da počistite njegovo notranje stanje. To strategijo lahko uporabimo v nasprotnem scenariju od pravkar opisanega. Če je podrejeno stanje napaka poškodovala, morate ponastaviti njegovo stanje, preden ga lahko uporabite v prihodnosti.
  • Otroka (in njegove otroke) ustavite trajno. To strategijo lahko uporabimo v primerih, ko ni verjetno, da bi stanje napake bilo mogoče popraviti, vendar ne ogroža preostalega dela, ki se izvaja, ki ga je mogoče dokončati v odsotnosti neuspešnega otroka.
  • Ustavite se in stopnjujte napako. Zaposlen, ko nadzornik ne ve, kako odpraviti napako, in jo tako poveča na svojega nadzornika.

Poleg tega se igralec lahko odloči, da bo to akcijo uporabil samo za propadle otroke ali za svoje brate in sestre. Za to obstajata dve vnaprej določeni strategiji:

  • OneForOneStrategy: Uporabi določeno dejanje samo za neuspešnega otroka
  • AllForOneStrategy: Uporabi določeno dejanje za vse njegove podrejene elemente

Tu je preprost primer z uporabo OneForOneStrategy:

import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import scala.concurrent.duration._ override val supervisorStrategy = OneForOneStrategy() { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: IllegalArgumentException => Stop case _: Exception => Escalate }

Če nobena strategija ni določena, se uporabi naslednja privzeta strategija:

  • Če je pri inicializaciji igralca prišlo do napake ali če je bil igralec ubit, se igralec ustavi.
  • Če je obstajala kakšna druga izjema, se igralca preprosto znova zažene.

Izvajanje te privzete strategije, ki jo dobavlja Akka, je naslednje:

final val defaultStrategy: SupervisorStrategy = { def defaultDecider: Decider = { case _: ActorInitializationException ⇒ Stop case _: ActorKilledException ⇒ Stop case _: Exception ⇒ Restart } OneForOneStrategy()(defaultDecider) }

Akka omogoča izvajanje nadzorniške strategije po meri , vendar, kot opozarja dokumentacija Akka, to storite previdno, saj lahko nepravilne izvedbe povzročijo težave, kot so blokirani sistemi igralcev (tj. trajno izključeni igralci).

Prosojnost lokacije

Arhitektura Akka podpira preglednost lokacije , ki igralcem omogoča, da so popolnoma agnostični, od kod izvirajo sporočila, ki jih prejmejo. Pošiljatelj sporočila lahko prebiva v istem JVM kot igralec ali v ločenem JVM (bodisi da se izvaja na istem vozlišču ali drugem vozlišču). Akka omogoča, da se vsak od teh primerov obravnava na način, ki je igralcu (in torej tudi razvijalcu) popolnoma pregleden. Edino opozorilo je, da je treba sporočila, poslana prek več vozlišč, serializirati.

Arhitektura Akka podpira preglednost lokacij, kar omogoča igralcem, da so popolnoma agnostični, od kod izvirajo sporočila, ki jih prejmejo.

Sistemi igralcev so zasnovani tako, da delujejo v porazdeljenem okolju, ne da bi za to potrebovali posebno kodo. Akka zahteva le prisotnost konfiguracijske datoteke (application.conf), ki določa vozlišča, ki jim želite pošiljati sporočila. Tu je preprost primer konfiguracijske datoteke:

kako pišeš kodo
akka { actor { provider = 'akka.remote.RemoteActorRefProvider' } remote { transport = 'akka.remote.netty.NettyRemoteTransport' netty { hostname = '127.0.0.1' port = 2552 } } }

Nekaj ​​nasvetov za ločitev ...

Videli smo, kako ogrodje Akka pomaga doseči sočasnost in visoko zmogljivost. Vendar, kot je poudarjeno v tej vadnici, morate pri načrtovanju in izvajanju sistema upoštevati nekaj točk, da boste v celoti izkoristili moč Akke:

  • V največji možni meri je treba vsakemu igralcu dodeliti najmanjšo možno nalogo (kot smo že omenili v nadaljevanju Načelo enotne odgovornosti )
  • Igralci bi morali dogodke (tj. Obdelovati sporočila) obravnavati asinhrono in jih ne bi smeli blokirati, sicer se bodo zgodila stikala konteksta, ki lahko negativno vplivajo na uspešnost. Natančneje, najbolje je izvajati blokirne operacije (IO itd.) V prihodnosti, da ne bi blokirali igralca; tj .:

    case evt => blockingCall() // BAD case evt => Future { blockingCall() // GOOD }
  • Prepričajte se, da so vsa vaša sporočila nespremenljiva, saj bodo vsi akterji, ki jih prenašajo drug drugemu, hkrati tekli v svojih nitih. Spremenljiva sporočila bodo verjetno povzročila nepričakovano vedenje.
  • Ker morajo biti sporočila, poslana med vozlišči, mogoče serializirati, je treba upoštevati, da večja kot so sporočila, dlje jih bo treba serializirati, poslati in deserializirati, kar lahko negativno vpliva na uspešnost.

Zaključek

Akka, napisano v Lestev , poenostavlja in olajša razvoj zelo hkratnih, porazdeljenih in odpornih aplikacij, pri čemer veliko zahtevnosti skriva pred razvijalcem. Za popolno pravičnost Akke bi bilo treba veliko več kot le ta vadnica, vendar upamo, da so bili ta uvod in njegovi primeri dovolj privlačni, da ste želeli prebrati več.

Amazon, VMWare in CSC je le nekaj primerov vodilnih podjetij, ki aktivno uporabljajo Akko. Obiščite uradno spletno mesto Akka če želite izvedeti več in raziskati, ali je Akka lahko pravi odgovor tudi za vaš projekt.

Kako lahko okreten talent spremeni vašo rastno miselnost

Agile Talent

Kako lahko okreten talent spremeni vašo rastno miselnost
Blockchain, IoT in prihodnost transporta: Razumevanje kovanca Motoro

Blockchain, IoT in prihodnost transporta: Razumevanje kovanca Motoro

Back-End

Priljubljene Objave
Poglobljen pogled na JSON v primerjavi z XML, 1. del: Zgodovina vsakega standarda
Poglobljen pogled na JSON v primerjavi z XML, 1. del: Zgodovina vsakega standarda
Vodnik po korakih za oblikovanje ilustracij po meri brez predhodnih izkušenj
Vodnik po korakih za oblikovanje ilustracij po meri brez predhodnih izkušenj
Grow Growth: S to odprtokodno kodo izvedite svojo analizo kohort
Grow Growth: S to odprtokodno kodo izvedite svojo analizo kohort
Vzdržujte tanke okvire PHP MVC z večplastno strukturo
Vzdržujte tanke okvire PHP MVC z večplastno strukturo
Meritve preživetja: Kako se spoprijeti s hitrostjo zagona
Meritve preživetja: Kako se spoprijeti s hitrostjo zagona
 
Uvod v sočasno programiranje: vodnik za začetnike
Uvod v sočasno programiranje: vodnik za začetnike
Bodite mirni in prehod k novi razvojni skupini
Bodite mirni in prehod k novi razvojni skupini
Ali je Agile Talent odgovor za oblikovanje vgrajenih sistemov?
Ali je Agile Talent odgovor za oblikovanje vgrajenih sistemov?
10 najpogostejših napak v jeziku C ++, ki jih naredijo razvijalci
10 najpogostejših napak v jeziku C ++, ki jih naredijo razvijalci
Izdelava REST API-ja za starejše PHP projekte
Izdelava REST API-ja za starejše PHP projekte
Priljubljene Objave
  • kaj je rtl-sdr
  • vprašanja o skrbnosti
  • programski program c++
  • nadomestilo za člane svetovalnega sveta
  • okvir spletne aplikacije node js
Kategorije
  • Trendi
  • Orodja In Vaje
  • Življenjski Slog
  • Oblikovanje Blagovne Znamke
  • © 2022 | Vse Pravice Pridržane

    portaldacalheta.pt