Objektorientētā programmēšanā alus pudelēm pārāk bieži ir tendence pašām sevi attaisīt un izdzerties.
Taisnīguma dēļ jāpiebilst, ka procedurālā programmēšanā pārāk bieži mēģina izdzert neattaisītu alus pudeli.
Objektorientētā programmēšanā alus pudelēm pārāk bieži ir tendence pašām sevi attaisīt un izdzerties.
Taisnīguma dēļ jāpiebilst, ka procedurālā programmēšanā pārāk bieži mēģina izdzert neattaisītu alus pudeli.
Pirms kāda laika tika ieguldīts darbs, lai GCC kompilētos ar C++ kompilatoru, nevis C kompilatoru – jo C++ kompilators veic striktākas pārbaudes. Tagad pašā GCC drīkstēs lietot C++. Un tas vienā no svarīgākajām un lielākajām GNU programmām, kas rakstītas C. Nevar saprast – vai nu C++ ir sasniedzis pietiekamu brieduma pakāpi vai GNU projektus pārņem “svaigas asinis”.

Jāsagaida GCC C++ vadlīnijas, lai redzētu, ko C++ kompilatora autori uzskatīs par “pieņemamo” C++ iespēju komplektu. Googles C++ vadlīnijas tādā ziņā vietām ir arhaiskas. Piemēram – “nelietot izņēmumus (exceptions) un RTTI”, lai gan var arī saprast viņu argumentāciju.
Skaisti:
It is not about solving puzzles and being the brightest kid in the class. It is about realizing that the complexity of software dwarfs even the most brilliant human; that cleverness cannot win. The only weapons we have are simplicity and convention.
The quick death: Invented by 1 person, used by 1 person, dies within a year.
Python kods, kas ģenerē python kodu, kas ģenerē PL/SQL kodu.
Bet atslodzei python kods, kas ģenerē SQL.
Jo rakstīt kodu ir pārāk vienkārši.
Ja augstāk minētie burtu salikumi ir pazīstami…
Jau pagājuši pāris gadi kopš dienas gaismu ieraudzīja manis rakstīta Oracle OCI bibliotēka un šobrīd tā turpina savu izplatību gandrīz visā jaunajā kompānijas kodā. (Pat ja objektorientēta programmēšana ir atbilde, C++ un ORM īpaši nedraudzējas).
Šonakt bibliotēka beidzot tika pie īsta CLOB/BLOB atbalsta, ļaujot iznīdēt pēdējos PRO*C bastionus. Un dara to, manuprāt, elegantāk par savu paraugu OTL. No ārpuses tas ir tikpat vienkārši kā kā OTL darbs VARCHAR2 laukiem, toties iekšpusē… ir OCI data interface ar dinamiskiem bind/define mainīgajiem un piecewise operācijas. Maģija.
Interesanti būs pēc gadiem trim paskatīties uz to, kas paliks pāri no visām (“katram izstrādātājam sava”) NoSQL datubāzēm.
Oracle MERGE priekšraksts (jeb upsert) ļauj ar vienu operāciju izmainīt ierakstu vai pievienot to, ja šāds ieraksts vēl neeksistē. Apmēram:
IF ieraksts atrasts
THEN UPDATE
ELSE
INSERT;
Kas nav acīmredzams, bet patiesībā loģisks rezultāts: veicot operāciju ar primāro atslēgu “ON” daļā ir iespējams iegūt kļūdu “ORA-00001: unique constraint (…) violated”. Respektīvi – starp brīdi, kad Oracle noskaidro, ka ieraksts neeksistē un veic INSERT, kāds cits process, veicot MERGE operāciju, var paspēt izpildīt INSERT pirmais.
Lasot kārtējo daily WTF/LOL, atcerējos vecu GCC un Linux kernel saraksti par vairākpavedienu programmām. Kas ir vēl viens pierādījums, ka vairākpavedienu programmas C++ nav nekāda medusmaize. Taisnību sakot, medusmaize tā nav arī citās valodās. If someone uses “instantly understand” and “threading” in the same sentence, my brain rewrites that sentence to say “doesn’t really understand threading.”
Atbilstoši C/C++ standartiem, kompilatoram no šķietami pareiza koda ir tiesības ģenerēt dīvainu rezultātu, ko tas arī dara.
#include <pthread.h>
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int acquires_count = 0;
int
trylock()
{
int res;
res = pthread_mutex_trylock(&mutex);
if (res == 0) {
++acquires_count;
}
return res;
}
Kompilēšanas rezultāts ir ekvivalents šādam kodam:
int
trylock()
{
int res;
int tmp;
res = pthread_mutex_trylock(&mutex);
tmp = acquires_count;
if (res == 0) {
++tmp;
}
acquires_count = tmp;
return res;
}
EPIC FAIL!
Palīdzēt var ar volatile vai skaitītāja palielināšanu liekot citā funkcijā. Bet svarīgi atcerēties, ka vairākpavedienu programmās būs jācīnās ne tikai ar algoritma kļūdām, paralēlu izpildi gan vairāku procesoru, gan viena procesora out-of-order izpildes līmenī, procesora spekulācijām, bet arī ar kompilatora optimizācijām.
Gallery of Processor Cache Effects sevišķi interesants ir 6. piemērs par vairākpavedienu programmām. Nevajag vienu globālu mainīgo, lai programmā radītu šauro vietu – pietiek ar to, ka mainīgie, ko izmanto dažādi pavedieni, atrodas tuvu viens otram atmiņā. Procesoriem būs darba pilnas rokas, sinhronizējot savas kešatmiņas.
Tad vēl fonā klausos Python vs. Ruby: A Battle to The Death, rakstu Lua smilšu kasti un mācu darboties ar Tuxedo datu tipiem.
Mazliet pārfrāzējot: programmētājam bija ātrdarbības problēma un viņš nespēja atrast risinājumu. “Zinu,” viņš teica, “es lietošu vairākus pavedienus.” Tagad programmētājam bija divas problēmas.
Ik pa brīdim uzrodas kāda diskusija par Python GIL likvidēšu. Tā ir “ļaunuma sakne”, kuras dēļ Python vairākpavedienu programmas nespēj izmantot vairākus procesorus, jo vienlaicīgi tiek izpildīta tikai viena instrukcija un darbojas viens pavediens. Oficiālā atbilde šādos gadījumos ir lietot Jython vai neatkarīgus procesus pavedienu vietā.
Arī jaunākajā Python 3k versijā GIL joprojām ir, bet ar dažiem uzlabojumiem. Ja piever acis uz tehnisko realizāciju, šajā prezentācijā ir pāris interesanti fakti:
Tāpēc, ja vien programmas šaurā vieta nav I/O (bieži ir), tad par vairākiem pavedieniem Python programmās ir jāaizmirst.
Kaut kur pusceļā starp RDBMS un NoSQL atrodas FcukSQL pasaule.
No vienas puses FcukSQL grib izmantot SQL, nevis manuāli rakstītu meklēšanas/grupēšanas/summēšanas kodu, grib vairākus(!) indeksus, ACID transakcijas un RDBMS administrēšanas rīkus. Un pilnībā pietiek ar viena datu bāzes servera jaudu. No otras puses – grib “lidojumā” maināmas datu struktūras, glabāt nestrukturētus datus (schema-less) un taisīt indeksus šiem nestrukturētajiem datiem.
Tad rodas risinājumi, kas “izvaro” RDBMS un glabā serializētus datus vai tabulas ar key-value pārīšiem. Bet kaut ko tādu nākas redzēt pirmo reizi: