(function(w,d,s,l,i){w[l]=w[l]|||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=? 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); Kā nenogalināt projektu ar sliktu kodēšanas praksi? - The Codest
The Codest
  • Par mums
  • Pakalpojumi
    • Programmatūras izstrāde
      • Frontend izveide
      • Backend izstrāde
    • Staff Augmentation
      • Frontend izstrādātāji
      • Backend izstrādātāji
      • Datu inženieri
      • Mākoņa inženieri
      • QA inženieri
      • Citi
    • Tā Konsultatīvais dienests
      • Audits un konsultācijas
  • Nozares
    • Fintech un banku darbība
    • E-commerce
    • Adtech
    • Healthtech
    • Ražošana
    • Loģistika
    • Automobiļu nozare
    • IOT
  • Vērtība par
    • CEO
    • CTO
    • Piegādes vadītājs
  • Mūsu komanda
  • Case Studies
  • Zināt, kā
    • Blogs
    • Tikšanās
    • Tiešsaistes semināri
    • Resursi
Karjera Sazinieties ar mums
  • Par mums
  • Pakalpojumi
    • Programmatūras izstrāde
      • Frontend izveide
      • Backend izstrāde
    • Staff Augmentation
      • Frontend izstrādātāji
      • Backend izstrādātāji
      • Datu inženieri
      • Mākoņa inženieri
      • QA inženieri
      • Citi
    • Tā Konsultatīvais dienests
      • Audits un konsultācijas
  • Vērtība par
    • CEO
    • CTO
    • Piegādes vadītājs
  • Mūsu komanda
  • Case Studies
  • Zināt, kā
    • Blogs
    • Tikšanās
    • Tiešsaistes semināri
    • Resursi
Karjera Sazinieties ar mums
Atpakaļ bultiņa ATGRIEZTIES ATPAKAĻ
2019-04-24
Programmatūras izstrāde

Kā nenogalināt projektu ar sliktu kodēšanas praksi?

The Codest

Bartošs Slišs (Bartosz Slysz)

Software Engineer

Daudzi programmētāji, kas sāk savu karjeru, uzskata, ka mainīgo, funkciju, failu un citu komponentu nosaukumu piešķiršana nav īpaši svarīga. Rezultātā viņu projektēšanas loģika bieži vien ir pareiza - algoritmi darbojas ātri un rada vēlamo efektu, bet var būt tikko salasāmi. Šajā rakstā mēģināšu īsi aprakstīt, pēc kā vajadzētu vadīties, nosaucot dažādus koda elementus, un kā nenonākt no vienas galējības otrā.

Kāpēc nosaukuma piešķiršanas posma ignorēšana paildzinās (dažos gadījumos - ļoti būtiski) jūsu projekta izstrādi?

Pieņemsim, ka jūs un jūsu komanda pārņem kods no citiem programmētājiem. Portāls projekts jūs mantojat tika izstrādāta bez jebkādas mīlestības - tā darbojās labi, taču katru tās elementu varēja uzrakstīt daudz labāk.

Ja runa ir par arhitektūru, koda mantošanas gadījumā tā gandrīz vienmēr izraisa naidu un dusmas no programmētāju puses, kas to ieguvuši. Dažreiz tas ir saistīts ar izmirstošu (vai izmirstošu) tehnoloģiju izmantošanu, dažreiz ar nepareizu domāšanu par lietojumprogrammu izstrādes sākumā, bet dažreiz vienkārši ar atbildīgā programmētāja zināšanu trūkumu.

Jebkurā gadījumā, projekta laikam ritot, ir iespējams nonākt līdz brīdim, kad programmētāji dusmojas uz arhitektūrām un tehnoloģijām. Galu galā, katrā lietojumprogrammā pēc kāda laika ir jāpārraksta dažas daļas vai vienkārši jāveic izmaiņas konkrētās daļās - tas ir dabiski. Taču problēma, kas programmētājiem sarauj matus, ir grūtības lasīt un saprast mantoto kodu.

Īpaši ekstrēmos gadījumos, kad mainīgie tiek nosaukti ar atsevišķiem, bezjēdzīgiem burtiem un funkcijas ir pēkšņs radošuma uzplūds, kas nekādā veidā nav saskaņots ar pārējo lietojumprogrammu, jūsu programmētāji var pārsteigt. Šādā gadījumā jebkurai koda analīzei, ko varētu veikt ātri un efektīvi, ja tiktu izmantoti pareizi nosaukumi, ir nepieciešama papildu analīze, piemēram, algoritmiem, kas ir atbildīgi par funkcijas rezultāta iegūšanu. Un šāda analīze, lai arī neuzkrītoša, - izšķiež milzum daudz laika.

Jaunu funkcionalitāšu ieviešana dažādās lietojumprogrammas daļās nozīmē iziet cauri murgam, analizējot to, pēc kāda laika jums ir jāatgriežas pie koda un jāanalizē tas vēlreiz, jo tā nolūki nav skaidri, un iepriekšējais laiks, kas pavadīts, mēģinot saprast tā darbību, ir bijis veltīgs, jo jūs vairs neatceraties, kāds bija tā mērķis.

Tādējādi mēs ieslīdam nekārtības tornado, kas valda lietojumprogrammā un lēnām aprij katru tās izstrādes dalībnieku. Programmētāji ienīst projektu, projektu vadītājiem nepatīk skaidrot, kāpēc tā izstrādes laiks sāk nepārtraukti pieaugt, bet klients zaudē uzticību un kļūst nikns, jo nekas nenotiek atbilstoši plānam.

Kā no tā izvairīties?

Atzīsim - dažas lietas nevar izlaist. Ja projekta sākumā esam izvēlējušies noteiktas tehnoloģijas, mums jāapzinās, ka ar laiku tās vai nu vairs netiks atbalstītas, vai arī arvien mazāk programmētāju pratīs izmantot pirms dažiem gadiem radītās tehnoloģijas, kas pamazām noveco. Dažas bibliotēkas savos atjauninājumos prasa vairāk vai mazāk saistošas izmaiņas kodā, kas bieži vien rada atkarību virpuli, kurā var iestrēgt vēl vairāk.

No otras puses, tas nav tik melns scenārijs; protams, tehnoloģijas noveco, taču faktors, kas noteikti palēnina ar tām saistīto projektu izstrādes laiku, ir lielākoties neglīts kods. Un, protams, šeit jāpiemin Roberta K. Martina grāmata - tā ir programmētāju bībele, kurā autors iepazīstina ar daudz labās prakses piemēriem un principiem, kas jāievēro, lai radītu uz pilnību tiecošos kodu.

  1. Nosaucot mainīgos, galvenais ir skaidri un vienkārši izteikt to nolūku. Tas izklausās pavisam vienkārši, taču dažkārt daudzi cilvēki to neievēro vai ignorē. Labs nosaukums norādīs, ko tieši mainīgajam ir paredzēts saglabāt vai ko funkcijai ir paredzēts darīt - to nedrīkst nosaukt pārāk vispārīgi, bet, no otras puses, tas nedrīkst kļūt par garu sliņķi, kura vienkārša nolasīšana sagādā smadzenēm pamatīgu izaicinājumu. Pēc kāda laika ar labu kvalitātes kods, mēs izjūtam iegremdēšanas efektu, kad mēs varam zemapziņā organizēt nosaukšanas un nodošanas dati funkcijai tā, lai tas viss neradītu ilūzijas par to, kāds nolūks to virza un kāds ir sagaidāmais rezultāts pēc tās izsaukšanas.
  2. Vēl viena lieta, ko var atrast JavaScript, cita starpā ir mēģinājums pārāk optimizēt kodu, kas daudzos gadījumos padara to nelasāmu. Ir normāli, ka dažiem algoritmiem ir nepieciešama īpaša rūpība, kas bieži vien atspoguļo to, ka koda nolūks var būt mazliet sarežģītāks. Tomēr gadījumi, kad nepieciešama pārmērīga optimizācija, ir ārkārtīgi reti vai vismaz tie, kuros mūsu kods ir netīrs. Ir svarīgi atcerēties, ka daudzas ar valodu saistītas optimizācijas notiek nedaudz zemākā abstrakcijas līmenī; piemēram, V8 dzinējs, veicot pietiekami daudz iterāciju, var ievērojami paātrināt cilpas. Jāuzsver tas, ka mēs dzīvojam 21. gadsimtā un nerakstām programmas Apollo 13 misijai. Mums ir daudz lielākas manevrēšanas iespējas resursu jomā - tie ir tur, lai tos izmantotu (vēlams, saprātīgā veidā :>).
  3. Dažreiz koda sadalīšana daļās patiešām dod daudz. Ja operācijas veido ķēdi, kuras mērķis ir veikt darbības, kas ir atbildīgas par konkrētu datu modifikāciju, - ir viegli apmaldīties. Tāpēc vienkāršā veidā, tā vietā, lai visu darītu vienā virknē, var sadalīt atsevišķās koda daļās, kas atbild par kādu konkrētu lietu, atsevišķos elementos. Tas ne tikai padarīs skaidru atsevišķu darbību nolūku, bet arī ļaus testēt koda fragmentus, kas atbild tikai par vienu lietu un kurus var viegli izmantot atkārtoti.

Daži praktiski piemēri

Manuprāt, visprecīzāk dažus no iepriekš minētajiem apgalvojumiem būs parādīt, kā tie darbojas praksē - šajā punktā es mēģināšu izklāstīt dažas sliktas koda prakses, kuras vairāk vai mazāk var pārveidot par labām. Norādīšu, kas dažos brīžos traucē koda lasāmību un kā to novērst.

Viena burta mainīgo bauslis

Briesmīga prakse, kas diemžēl ir diezgan izplatīta pat universitātēs, ir mainīgo nosaukšana ar vienu burtu. Grūti nepiekrist, ka reizēm tas ir diezgan ērts risinājums - mēs izvairāmies no liekas domāšanas, kā noteikt mainīgā nolūku, un tā vietā, lai nosaukumā izmantotu vairākus vai vairākus burtus, izmantojam tikai vienu burtu - piemēram, i, j, k.

Paradoksāli, bet dažas šo mainīgo definīcijas ir apveltītas ar daudz garāku komentāru, kas nosaka, ko autors ir domājis.

Labs piemērs šeit varētu būt iterācija pār divdimensiju masīvu, kas satur atbilstošās vērtības kolonnas un rindas krustpunktā.

const array = [[0, 1, 2], [3, 4, 5], [6, 7, 8]];

// diezgan slikti
for (let i = 0; i < array[i]; i++) {
  for (let j = 0; j < array[i][j]; j++) {
    // šeit ir saturs, bet katru reizi, kad tiek izmantoti i un j, man ir jāatgriežas un jāanalizē, kam tie tiek izmantoti
  }
}

// joprojām slikti, bet smieklīgi
let i; // rinda
let j; // sleja

for (i = 0; i < array[i]; i++) {
  for (j = 0; j < array[i][j]; j++) {
    // šeit ir saturs, bet katru reizi, kad tiek izmantoti i un j, man ir jāatgriežas un jāpārbauda komentāri, kam tie tiek izmantoti
  }
}

// daudz labāk
const rowCount = array.length;

for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
  const row = array[rowIndex];
  const columnCount = row.length;

  for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
    const column = row[columnIndex];

    // vai kādam ir šaubas par to, kas ir kas?
  }
}

Viltīga pārmērīga optimizācija

Kādu skaistu dienu es sastapos ar ļoti sarežģītu kodu, ko uzrakstīja kāds programmatūras inženieris. Šis inženieris bija noskaidrojis, ka lietotāja atļauju sūtīšanu kā virknes, kurās norādītas konkrētas darbības, var ievērojami optimizēt, izmantojot dažus bitu līmeņa trikus.

Iespējams, šāds risinājums būtu labs, ja mērķis būtu Commodore 64, bet šī koda mērķis bija vienkārša. tīmekļa vietne lietojumprogramma, kas rakstīta JS. Ir pienācis laiks pārvarēt šo dīvainību:
Pieņemsim, ka lietotājam visā sistēmā ir tikai četras satura modificēšanas iespējas: izveidot, lasīt, atjaunināt, dzēst. Tas ir diezgan dabiski, ka mēs vai nu nosūtām šīs atļaujas JSON formā kā objekta atslēgas ar stāvokļiem, vai kā masīvu.

Tomēr mūsu gudrais inženieris pamanīja, ka binārajā attēlojumā skaitlis četri ir maģiska vērtība, un izdomāja to šādi:

slikti koda ieradumi

Visā iespēju tabulā ir 16 rindas, bet es esmu uzskaitījis tikai 4, lai parādītu šo atļauju izveides ideju. Atļauju lasīšana notiek šādi:

const user = { atļaujas: 11 };

const canCreate = Boolean(user.permissions & 8); // true
const canRead = Boolean(user.permissions & 4); // false
const canUpdate = Boolean(user.permissions & 2); // true
const canDelete = Boolean(user.permissions & 1); // true

Tas, ko redzat iepriekš, nav WebAssembly kods. Es nevēlos, lai mani pārprastu - šāda optimizācija ir normāla lieta sistēmās, kur noteiktām lietām ir nepieciešams ļoti maz laika vai atmiņas (vai abas). No otras puses, tīmekļa lietojumprogrammas noteikti nav vieta, kur šādai pārmērīgai optimizācijai ir pilnīga jēga. Es negribu vispārināt, bet front-end izstrādātāju darbā sarežģītākas operācijas, kas sasniedz bitu abstrakcijas līmeni, tiek veiktas reti.

Tas vienkārši nav lasāms, un programmētājs, kas spēj veikt šāda koda analīzi, noteikti brīnīsies, kādas neredzamas priekšrocības ir šim risinājumam un kas var tikt bojāts, ja. izstrādes komanda vēlas to pārrakstīt uz saprātīgāku risinājumu.

Vēl vairāk - man ir aizdomas, ka, nosūtot atļaujas kā parastu objektu, programmētājs varētu nolasīt nodomu 1-2 sekundēs, savukārt visas šīs lietas analīze no sākuma prasīs vismaz dažas minūtes. Projektā būs vairāki programmētāji, katram no viņiem nāksies saskarties ar šo koda gabalu - viņiem nāksies to analizēt vairākas reizes, jo pēc kāda laika viņi aizmirsīs, kāda maģija tur notiek. Vai ir vērts saglabāt šos dažus baitus? Manuprāt, nē.

Sadal un valdi

Tīmekļa izstrāde strauji pieaug, un nekas neliecina, ka drīzumā šajā ziņā varētu kaut kas mainīties. Jāatzīst, ka pēdējā laikā ir ievērojami palielinājusies front-end izstrādātāju atbildība - viņi ir pārņēmuši loģikas daļu, kas atbild par datu attēlojumu lietotāja saskarnē.

Dažreiz šī loģika ir vienkārša, un objekti, ko nodrošina API ir vienkārša un viegli lasāma struktūra. Tomēr dažkārt, lai tos pielāgotu dažādām vietām lapā, ir jāveic dažāda veida kartēšana, šķirošana un citas darbības. Un šī ir vieta, kur mēs varam viegli iekrist purvā.

Daudzas reizes esmu pieķēris sevi pie tā, ka dati operācijās, ko veicu, ir praktiski nelasāmi. Neraugoties uz pareizu masīva metožu lietošanu un pareizu mainīgo nosaukumu piešķiršanu, operāciju ķēdes dažos punktos gandrīz zaudēja kontekstu tam, ko es vēlējos panākt. Turklāt dažas no šīm operācijām dažkārt bija jāizmanto citur, un dažkārt tās bija pietiekami globālas vai sarežģītas, lai būtu nepieciešams rakstīt testus.

const ierīces = [
  { id: '001', version: 1, owner: { location: 'Texas', age: 21 } },
  { id: '002', versija: 2, īpašnieks: { atrašanās vieta: 'Texas', vecums: 27 gadi } },
  { id: '003', versija: 3, īpašnieks: { atrašanās vieta: 'Arizona', vecums: 27 gadi } },
  { id: '004', versija: 2, īpašnieks: { atrašanās vieta: 'Čikāga', vecums: 24 gadi } },
  { id: '005', versija: 2, īpašnieks: { atrašanās vieta: 'Arizona', vecums: 19 gadi }. },
  { id: '006', versija: 3, īpašnieks: { atrašanās vieta: 'Teksasa', vecums: 42 gadi } },
];

// diezgan sarežģīti
(() => {
  const locationAgeMap = devices
    .map(device => device.owner)
    .reduce((map, item) => {
      if (!map[item.location]) {
        map[item.location] = item.age;
      } else {
        map[item.location] += item.age;
      }

      return map;
    }, {});

  const locationLegalAgeOwnersMap = devices
    .map(device => device.owner)
    .filter(īpašnieks => īpašnieks.vecums >= 21)
    .reduce((map, item) => {
      if (!map[item.location]) {
        map[item.location] = [item];
      } citādi {
        map[item.location].push(item);
      }

      return map;
    }, {});

  console.log({ locationAgeMap, locationLegalAgeOwnersMap });
})();

// joprojām sarežģīti, bet kompaktāki
(() => {
  const locationOwnersMap = devices
  .map(device => device.owner)
  .reduce((map, item) => {
    if (!map[item.location]) {
      map[item.location] = [item];
    } else {
      map[item.location].push(item);
    }

    return map;
  }, {});

  const locationAgeMap = Object.fromEntries(
    Object.entries(locationOwnersMap).map(([location, owners]) => {
      const ownersAge = owners.map(owner => owner.age).reduce((a, b) => a + b);

      return [location, ownersAge];
    })
  );

  const locationLegalAgeOwnersMap = Object.fromEntries(
    Object.entries(locationOwnersMap).map(([location, owners]) => {
      const filteredOwners = owners.filter(owner => owner.age >= 21);

      return [location, filteredOwners];
    }).filter(([_lokācija, īpašnieki]) => {
      return owners.length > 0;
    })
  );

  console.log({ locationAgeMap, locationLegalAgeOwnersMap });
})();

Es zinu, es zinu - tas nav triviāls koda gabaliņš, kas viegli ilustrē to, ko es vēlos parādīt. Un es arī zinu, ka abu piemēru skaitļošanas sarežģītība ir nedaudz atšķirīga, bet 99% gadījumos mums par to nav jāuztraucas. Atšķirība starp algoritmiem ir vienkārša, jo abi sagatavo atrašanās vietu un ierīču īpašnieku karti.

Pirmais šo karti sagatavo divas reizes, bet otrais - tikai vienu reizi. Un visvienkāršākais piemērs, kas parāda mums ka otrais algoritms ir pārnesamāks, slēpjas faktā, ka mums ir jāmaina šīs kartes izveides loģika attiecībā uz pirmo algoritmu un, piemēram, jāizslēdz noteiktas vietas vai citas dīvainas lietas, ko sauc par biznesa loģiku. Otrā algoritma gadījumā mēs modificējam tikai kartes iegūšanas veidu, bet visas pārējās datu modifikācijas, kas notiek nākamajās rindās, paliek nemainīgas. Pirmā algoritma gadījumā mums ir jāmaina katrs kartes sagatavošanas mēģinājums.

Un šis ir tikai piemērs - praksē ir daudz šādu gadījumu, kad mums ir nepieciešams pārveidot vai pārveidot noteiktu datu modeli visā lietojumprogrammā.

Labākais veids, kā izvairīties no sekošanas līdzi dažādām izmaiņām uzņēmējdarbībā, ir sagatavot globālus rīkus, kas ļauj mums iegūt interesējošo informāciju diezgan vispārīgā veidā. Pat uz to rēķina, ka mēs varam zaudēt tās 2-3 milisekundes, ko varam zaudēt uz deoptimizācijas rēķina.

Kopsavilkums

Būt programmētājam ir tāda pati profesija kā jebkura cita - katru dienu mēs mācāmies jaunas lietas un bieži vien pieļaujam daudz kļūdu. Svarīgākais ir mācīties no šīm kļūdām, kļūt labākam savā profesijā un neatkārtot šīs kļūdas nākotnē. Nevar ticēt mītam, ka mūsu darbs vienmēr būs nevainojams. Tomēr jūs varat, pamatojoties uz citu pieredzi, attiecīgi samazināt trūkumus.

Es ceru, ka šī raksta izlasīšana palīdzēs jums izvairīties no vismaz dažiem no slikta kodēšanas prakse ko esmu pieredzējis savā darbā. Ja jums rodas jautājumi par labākajām kodēšanas praksēm, varat sazināties ar The Codest apkalpe ārā, lai konsultētos par savām šaubām.

Lasīt vairāk:

Datu iegūšanas stratēģijas NextJS

Web lietojumprogrammu drošība - XSS ievainojamība

Tīmekļa lietotņu drošība. Target=”_blank” ievainojamība

*Virsraksta grafika nāk no speednet.pl

Saistītie raksti

Ilustrācija viedtālruņa veselības aprūpes lietotnei ar sirds ikonu un pieaugošo veselības diagrammu, kas apzīmēta ar The Codest logotipu, kurš pārstāv digitālās veselības un HealthTech risinājumus.
Programmatūras izstrāde

Veselības aprūpes programmatūra: Mārketinga programmatūra: veidi, izmantošanas gadījumi

Šodien veselības aprūpes organizāciju rīcībā esošie rīki vairs neatgādina papīra diagrammas, kas tika izmantotas pirms vairākiem gadu desmitiem. veselības aprūpes programmatūra tagad atbalsta veselības aprūpes sistēmas, pacientu aprūpi un mūsdienīgu veselības aprūpes sniegšanu klīniskajās un...

TĀKĀDĒJAIS
Abstrakta ilustrācija ar lejupejošu joslu diagrammu ar augošu bultiņu un zelta monētu, kas simbolizē izmaksu efektivitāti vai ietaupījumus. Augšējā kreisajā stūrī redzams The Codest logotips ar saukli "In Code We Trust" uz gaiši pelēka fona.
Programmatūras izstrāde

Kā paplašināt izstrādātāju komandu, nezaudējot produkta kvalitāti

Palielināt izstrādātāju komandu? Uzziniet, kā augt, nezaudējot produkta kvalitāti. Šajā rokasgrāmatā aplūkotas pazīmes, kas liecina, ka ir pienācis laiks paplašināt komandu, komandas struktūra, pieņemšana darbā, vadība un rīki, kā arī tas, kā The Codest var...

TĀKĀDĒJAIS
Programmatūras izstrāde

Uz nākotni noturīgu tīmekļa lietojumprogrammu veidošana: The Codest ekspertu komandas ieskats

Uzziniet, kā The Codest izceļas mērogojamu, interaktīvu tīmekļa lietojumprogrammu izveidē, izmantojot modernākās tehnoloģijas un nodrošinot viengabalainu lietotāja pieredzi visās platformās. Uzziniet, kā mūsu zināšanas veicina digitālo transformāciju un biznesa...

TĀKĀDĒJAIS
Programmatūras izstrāde

Top 10 Latvijā bāzēti programmatūras izstrādes uzņēmumi

Mūsu jaunākajā rakstā uzziniet vairāk par Latvijas labākajiem programmatūras izstrādes uzņēmumiem un to inovatīvajiem risinājumiem. Uzziniet, kā šie tehnoloģiju līderi var palīdzēt uzlabot jūsu biznesu.

thecodest
Uzņēmumu un mērogošanas risinājumi

Java programmatūras izstrādes pamati: A Guide to Outsourcing Successfully

Izpētiet šo būtisko rokasgrāmatu par veiksmīgu outsourcing Java programmatūras izstrādi, lai uzlabotu efektivitāti, piekļūtu speciālajām zināšanām un sekmīgi īstenotu projektus ar The Codest.

thecodest

Abonējiet mūsu zināšanu bāzi un saņemiet jaunāko informāciju par IT nozares pieredzi.

    Par mums

    The Codest - starptautisks programmatūras izstrādes uzņēmums ar tehnoloģiju centriem Polijā.

    Apvienotā Karaliste - Galvenā mītne

    • 303B birojs, 182-184 High Street North E6 2JA
      Londona, Anglija

    Polija - Vietējie tehnoloģiju centri

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Krakova
    • Brain Embassy, Konstruktorska
      11, 02-673 Varšava, Polija

    The Codest

    • Sākums
    • Par mums
    • Pakalpojumi
    • Case Studies
    • Zināt, kā
    • Karjera
    • Vārdnīca

    Pakalpojumi

    • Tā Konsultatīvais dienests
    • Programmatūras izstrāde
    • Backend izstrāde
    • Frontend izveide
    • Staff Augmentation
    • Backend izstrādātāji
    • Mākoņa inženieri
    • Datu inženieri
    • Citi
    • QA inženieri

    Resursi

    • Fakti un mīti par sadarbību ar ārējo programmatūras izstrādes partneri
    • No ASV uz Eiropu: Kāpēc Amerikas jaunuzņēmumi nolemj pārcelties uz Eiropu?
    • Tehnoloģiju ārzonas attīstības centru salīdzinājums: Tech Offshore Eiropa (Polija), ASEAN (Filipīnas), Eirāzija (Turcija)
    • Kādi ir galvenie CTO un CIO izaicinājumi?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Autortiesības © 2026 The Codest. Visas tiesības aizsargātas.

    lvLatvian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian es_ESSpanish nl_NLDutch etEstonian elGreek pt_PTPortuguese cs_CZCzech lt_LTLithuanian is_ISIcelandic lvLatvian