Inteligen

Наскоро се появи поредното „революционно“ откритие, хапче наречено Inteligen, което повишавало IQ точките 2-3 пъти (ако съм със 120 ще имам IQ 300+?), повишавало концентрацията, способностите да мислиш и да запомняш. Звучи велико, направо като филм.

Но дали наистина е така? За съжаление не успях да открия точен отговор, ето фактите които успях да намеря:

  • Лекарството не е одобрено от нито една официална агенция в USA или Европа. Дори не е класифицирано.
  • Производителя твърди, че няма никакви странични ефекти, въпреки, че при две от съставките му (VINPOCETINE и ACETYL-L CARNITINE) има ясни доказателства за странични ефекти като проблем със съсирване на кръвта, главоболия, диария, проблеми с кръвното и гърчове. Тези вещества НЕ трябва да се взимат от бременни и кърмещи.
  • Лекарството се продава само по интернет  – само този факт трябва да ви е достатъчен за да започнете да се съмнявате, че нещо не наред
  • не успях да намеря нито едно независимо проучване на ефектите му, нито едно. Дори блогър който е споделил с няколко думи какво мисли. Нито едно!!!
  • Всички материали които го хвалят са стандартна маркетингова мрежа, фалшиви блогове, платени постове. Нито едно независимо мнение
  • Стъвън Хокин го бил пробвал и казал, че било уникално. Не успях да намеря никаква референция, че господин Хокин наистина го е пробвал. Дали той знае, че го е пробвал?
  • Начина на дистрибутиране, маркетинг и подтикване към покупка са опасно агресивни. Ако продукта е толкова добър колкото твърдят няма да има нужда да се напъват да продават, а ще се мъчат да направят нови производствени линии. Нито една уважаваща себе си фирма/продукт няма да сложи „Do not leave page“ JS код в страница.

Лекарството е доста скъпо, дори за западните стандарти, така че не се подвеждайте.

Но да приеме, че наистина работи. Има такива лекарства, знаят се от години, още през студената война СССР и USA правят огромни проучвания по отношение на засилване на човешките способности, и контрол над хората установявайки конкретни медикаменти които наистина са ефективни. Проблемът е, че не много далеч във времето започват много сериозни здравословни проблеми.

Дори е сега в комбинация от няколко антидепресанта в много малки дози човек може да си „изпили“ мозъка за 1-2 дни преди изпит и да покаже уникални резултати, един път ще му се размине, ама ще го направи втори, трети. Тази игра с невротрансмитерите в мозъка ще промени почти всеки баланс в тялото, което води до непредвидени резултати, но депресията е почти сигурна. И говоря за тежка клинична депресия, не за „ама днес ми нещо тъпо и не съм в настроение“

Не се подлъгвайте, ако лекарството работи и има ефекта както се твърди то ще стане хит, но оставете няколко месеца да бъде тествано и анализирано. След като се появят независими ревюта тогава човек може да се замисли. Ако не работи ще си замине като всеки подобен продукт. Така че ако почакате печелите във всеки един случай.

Научете се да се концентрирате, човешкия мозък има огромен потенциал и капацитет, овладейте го. Там няма странични ефекти, там няма химия, там няма зависимости.

Възходът на машините

Тези от вас, които ме познават по-добре, сигурно знаят, че моята страст е machine learning, или казано на български самообучаващи се машини. Това е една от най-динамично развиващите се сфери на науката в момента, която ще доведе до фундаментални промени в човешкото общество, при това доста скоро. Ще се опитам да обясня защо и как това ще се случи.

Как започва всичко

Повечето хора правят аналогия със SkyNet от „Терминатор“ или с изкуствения интелект, хуманоидните роботи или различните форми на автономни машини. Това не е напълно вярно – гореизброените са само една малка част от самообучаващите се машини. Но за да разберете по-ясно, нека да започнем от самото начало – 60-те години на 20-и век.

Тогава повечето академици са осъзнавали какво представляват компютрите, но не са били напълно сигурни къде са техните граници. Силно стимулирани от правителствени програми, учените започват да експериментират във всевъзможни посоки, много често дори и „стрелят напосоки“. Основната задача тогава е била да се види какво предимство може да предостави един компютър или програма. Все пак това е ерата на Студената война, концепцията за глупава идея не е съществувала. Американците дори изстрелват сателит, имащ за цел да провери да не би случайно Русия да прави ядрени опити на обратната страна на Луната.

Резултатите не закъсняват, математиците доста бързо разработват цял инструментариум от алгоритми, правила и напълно нови концепции и доказват, че компютрите могат да анализират информация и да взимат решения спрямо тази информация.

Но е имало два доста сериозни проблема – първият е, че компютрите са били безумно слаби, което значи непрактично много време за изпълнението на тези алгоритми, а вторият проблем е, че не са имали достатъчно данни, за да може алгоритмите да работят ефективно.

Ето ви един прост пример – искате да научите компютъра да разпознава танкове на снимки. За да се направи това, трябва да покажете на компютъра хиляди снимки с различни танкове, на различни терени, с различно разположение, за да може алгоритъмът да „разбере“ какво е танк и впоследствие да може да ги намира автоматично на други снимки. Това се нарича supervised learning и е изключително мощна техника, ако имате данните, с които да го научите.

Поради тези и някои други по-маловажни причини machine learning остава в зоната на стриктно академичната дейност, докато горепосочените проблеми започват постепенно да изчезват. Компютърната мощ се развива експоненциално, а с навлизането на Интернет и масовото споделяне (и следене) на данни се създават огромни бази данни, много често в порядъка на десетки петабайти. Това е и причината всички компании да ви предлагат да записвате своите данни в техните „облаци“ – вашите данни са храна за машините и печалба на компаниите.

Големите компании осъзнават, че може да използват това като тяхно предимство. Студената война е приключила, голяма част от света е със свободни пазари, частните компании разполагат с огромни ресурси. Какъв продукт бихте предпочели да закупите? Какъв е шансът да се разболеете? Как би се променило общественото мнение за политически кандидат X, ако се случи събитие Y и бъде представено в медиите по начин Z? Machine learning дава плашещо точни отговори на всички тези въпроси, както и на милиони други. Всички започват да инвестират милиарди в разработката на подходящ софтуер, хардуер и инфраструктура.

Какво точно са самообучаващите се машини

Има стотици различни видове самообучаващи се системи, които се използват за точно определени задачи. Искате да разберете кой от вашите клиенти е склонен да купи новия ви продукт или искате да разберете характеристиката на дадена звезда спрямо нейната светлина, или просто да препоръчате друга песен спрямо това, което потребителят е слушал до момента – тогава (най-често) се използват класифициращи алгоритми.

Искате да предвидите за колко пари ще може да продадете имот, ако го построите в определен район, или колко ще се намали замърсяването на въздуха, ако зеленият светофар свети с 10 секунди повече, или колко допълнителни самолета ще са необходими да се извозят пътниците по празниците – тогава се използват регресивни алгоритми

Искате да накарате компютъра да генерира смислен текст, да композира музика или да рисува – тогава се използват LSTM (long short-term memory) алгоритми.

Искате да научите робот да премества кутии, да кара кола, да играе шах и табла, да стои прав и да се придвижва сам – тогава се използват deep neural networks в комбинация с convolutional neural networks, deep reinforcement learning и подобни.

Горните примери са силно опростени и в действителност за някои от проблемите има повече от едно решение, както и често се правят комбинации между различните техники, но мисля, че разбирате за какво може да се използват – на практика за всичко.

Това са самообучаващите се системи – компютърен алгоритъм, използвайки данни, взима решения или вади изводи. В момента над 60% от търговията по финансовите пазари се извършва от подобни алгоритми. Те управляват логистиката на огромни куриерски фирми, контролират ядрени централи, химически заводи. Решават какви реклами да виждате, каква информация да четете, колко е вероятно да се разболеете и как бихте гласували, разбират, когато им говорите, познават къде е направена дадена снимка спрямо това, което се вижда на снимката, определят ще можете ли да си върнете кредита и още много неща, за които дори не се досещате.

Какво е нивото на самообучаващите се системи в момента

В момента, септември 2016 г. самообучаващите се системи побеждават човек в над 95% от всички възможни задачи. Единствените умения, в които хората все още сме по-добри, са разпознаването на човешка реч, най-вече когато има силен акцент, жаргон или диалект и във фантазиите. Но и това няма да „издържи“ дълго време. Вече има алгоритми, които пишат сценарии на филми (при това се справят изненадващо добре), а разпознаването на реч ще се подобри, когато се съберат достатъчно данни, за да се научат още по-добре. Въпрос на време.

Основната „спирачка“ в момента е все още слабата изчислителна мощност. Използват се специализирани видео карти, които могат да обработват огромни паралелни потоци, но дори и те са слаби. WaveNet – алгоритъм, който генерира човешки глас, напълно неразличим от истински човешки глас, отнема 90 минути изчисления за 1 секунда звук. Но законът на Мур все още работи, което значи, че след няколко години ще има изчислителна мощност, позволяваща това да става в реално време (заедно с подобряване на алгоритмите). Въпреки това компании като Google не искат да чакат и започнаха да правят TPU (Tensor Processing Unit). Това са специализирани процесори за обработка на тензори, които са съществено по-бързи от GPU. За съжаление все още няма никакви технически детайли колко са мощни, Google е изключително потаен по темата, но този прост факт дава ясна идея колко бързо се развива тази област. Същото така е ясно, че „организацията“ с по-добрите алгоритми и по-голяма изчислителна мощ ще доминира над всички други. Затова всеки хвърля милиарди в разработка.

Какво ме интересува това

Самообучаващите се системи предизвикват промяна във всяка една сфера на живота, значително по-мащабна от промяната, предизвикани от Индустриалната революция. Да, предизвикват, защото това вече се случва, при това с все по-бързи темпове.

До този момент в човешката история хората са измисляли всевъзможни инструменти и приспособления. Като започнем от лъка и ножа, преминем през напоителните системи и пътища и стигнем до самолетите и сателитите. Но всички тези открития правят само едно нещо – увеличават човешките възможности. Машините са по-бързи, по-точни, по-мощни. Но те само разширяват уменията на човека.

Революцията, която става в момента, е коренно различна и силно се надявам да го разберете. Самообучаващите системи не са просто по-силни, по-бързи, по-точни – те са по-умни.

За първи път човекът създава „уред“, който е независим, който се учи и развива сам, който развива напълно различен тип интелигентност, който често ние хората не можем да възприемем.

Да, последното не е никаква спекулация или научна фантастика – самообучаващите се системи се приближават максимално до дефиницията за интелект, която имаме, с тази разлика, че този интелект работи по съвсем различни правила. И най-притеснителното е, че често НЕ може да разберем какви са тези правила.

Последствията ще са мащабни. До 2025-2028 г. транспортът на стоки и хора ще се извърша от автономни превозни средства. На много места дори ще бъде забранено хора да управляват автомобили.

Всяка „ниско квалифицирана“ работа ще бъде заместена от машини – в резултат ще има огромен социален срив. Очаква се над 60% от работните места да изчезнат. Сами може да се досетите какъв удар ще понесат социално-осигурителните системи.

Земеделието и животновъдството ще е 100% автоматизирано.

Вследствие на голямото отпадане на хора от работните процеси нуждата от администрация във фирмите ще намалее значително, а и голяма част ще бъде автоматизирана.

Ако смятате, че това са глупости, това е ваш избор, но например Foxconn, една огромна компания за производство на електроника в Китай, уволни 5 милиона свои служители и ги замени с роботи.

Роботът не се разболява, роботът не участва в синдикати, роботът няма почивка, за да спи, яде или да си види роднините. Всички големи корпорации инвестират в самоуправляеми превозни средства и те може да се видят по улиците на Америка, Китай, Германия и Русия (в Русия все още ги тестват на закрити полигони). Boston Dynamics демонстрираха неведнъж автономни роботи, способни да се ориентират сами, да преместват обекти, отварят врати и дори да готвят и чистят.

Ясно е какво ще стане, ясно е, че може да стане, просто трябва малко подобрение на алгоритмите и малко по-голяма изчислителна мощност.

Затова ако тепърва избирате вашето професионално развитие, помислете накъде искате да се развиете и помислете няколко пъти, ако изборът ви присъства в долния списък:

  • доставки и транспорт
  • индустриално земеделие и животновъдство
  • индустриално производство
  • грижа за болни и стари хора
  • строителство
  • административни услуги
  • обслужване на клиенти и продажби
  • охрана и контрол
  • минно дело и преработка.

Позициите които няма да бъдат силно засегнати до 2030 г. са:

  • мениджмънт и бизнес
  • компютърни и инженерни науки
  • образование
  • юридически услуги
  • изкуство
  • медицински специалности като хирургия и терапия*.

Ние сме 100 години назад

Някой ще си каже, че докато това дойде в България, ще изтече много вода. А какъв телефон използвате в момента? Този, който се продава в целия свят, най-вероятно последен модел. Какви сериали гледате? Тези, които се гледат навсякъде. Какви компютри, софтуер и инструменти използвате сега? Същите, които се използват навсякъде.

Не сме 100 години назад.

Промените носят огромни икономии на фирмите. Тези, които откажат да ги приемат, просто няма да бъдат конкурентни и ще бъдат заменени от фирми, използващи новите технологии и способи.

Не очаквайте всичко да стане за една вечер, това не е революция в смисъла, че някой ще стреля с пушка и ще развее едно знаме. Нещата стават постепенно, но с бързи темпове. Тенденцията е ясна, всички почват да се адаптират и подготвят. Няма да ни подмине.

Как ще се промени обществото

Тук мога само да спекулирам. Много групи се опитват да предвидят в детайли, но дори и академици, отдали се на това с години, заявяват, че не могат да отговорят с точност. Но за едно всички са съгласни – личното пространство ще бъде намалено почти до нула, контролът върху масите ще бъде силно засилен, но не явен. Ще бъде „тих тоталитаризъм“. Нашето развитие като личности и професионалисти ще се определя от много фактори, върху които нямаме пряк контрол. След първоначалния шок и стрес хората ще консумират повече, но с по-малък избор. Ще има огромни неразбиваеми монополи – тези, които държат знанията и инфраструктурата на самообучаващите се системи. Ще започне изравняване на социалния статус. Ще има една много малка група с почти неограничена власт и една група от „средна класа“. Бедността и мизерията (в развитите страни) ще е минимална. Масите ще започнат да деградират културно и интелектуално. До 2050 г. населението на Земята ще спадне под 5 милиарда души.

*Диагностицирането и лабораторната работа ще е почти напълно автоматизирана, но решенията за лечение ще се взимат от хора спрямо препоръка на машини.

Deep WEB, Dark WEB и TOR

Няколко човека в последните два дни ми зададоха един и същи въпрос – какво е TOR и какво е Deep WEB, ще се опитам простичко да обясня какво представляват и да внеса малко разбиране. Нека да започнем от най-простото:

Нормалният Интернет (Surface Internet)

Как намирате информация в страница? В над 90% от случаите търсите в google (а ако имате странно психическо заболяване Bing или Yahoo). Google и останалите непрекъснато сканират страниците в мрежата, записват тяхната информация на техните сървъри и в последствие алгоритмите им се опитват да ви покажат най-релевантните резултати. Често успяват, най-вече с рекламите. Но ето тук е важния момент – как се сканират всички страници?

От самото създаване на WEB основната концепция са „хиперлинковете“, или както ги наричаме накратко линкове. За да намери страница google трябва да намери линк за нея. Няма значени от къде идва линка, важното е да сочи към страница (или информация). Ако никой никъде не сочи към дадена страница тя НЕ може да бъде намерена от никоя търсеща система, тя не съществува в нормалния интернет, не може да бъде индексирана. За това една от основните техники при SEO е link building, тоест да сложите линкове към определена страница на достатъчно места, така че google да може да я посети. Нарочно избягвам детайлите като качество на линковете и подобни, това си е цяла отделна наука, но принципа е прост, някъде някой трябва да сочи към страницата.

Това е нормалния интернет  – всичко, което може да бъде индексирано от търсещите системи.

Дълбокият Интернет (Deep WEB)

Предполагам вече се досещате какво представлява „дълбокия интернет“ – това са всички страници (и информация) която не може да бъде директно достъпена. Вие трябва да знаете, че съществува и къде съществува, за да я намерите. Много често е необходимо да предоставите пароли или друга форма за оторизация. Но в тази категория не влизат само някакви тайни хакерски криминални страници, напротив. Дори и Facebook е в дълбокия интернет, понеже много от информацията в сайта не е директно достъпна. Да не говорим за информация от държавни институции, лаборатории, търговски сайтове, форуми и фондации. Според проучванията (които са относителни) само 0.03% от всичко в мрежата е достъпно през търсещи системи. Останалите 99.97% се намират зад пароли, всевъзможни форми за ограничаване на достъпа, липса на линкове или директна цензура. Имайте предвид, че дълбокия интернет работи по същия начин както останалия интернет. Можете да бъдете проследени, остават записи, ползват се стандартните протоколи за комуникация и стандартни инструменти за достъп. По тази причина в дълбокия интернет не се срещат толкова много нелегални или престъпни дейности. Има ги, но ако някой ги намери не е особено сложно за някоя агенция да установи посетители, собственици, локация.

Тъмния Интернет (Dark WEB)

Тук нещата вече загрубяват. Тъмния интернет е място в мрежата, което не е достъпно чрез стандартните протоколи и инструменти. Той използва инфраструктурата на интернет за транспорт (мрежови кабели, рутери, машротизатори) но това място е абсолютно тотално изолирано от нормалния интернет. Има няколко такива „места“. Най-известното е TOR мрежата, която се достъпва чрез специален браузър наречен TOR browser (за него по-надолу).

Идеята на тези „мрежи“ е да предоставят най-високата възможна анонимност на всички участници в тях. Къде физически се намират сървърите, кой е техният собственик, кой ги посещава… всичко това остава анонимно (поне на теория).

По тази причина в тези мрежи може да намерите най-извратените, неморални, незаконни, безумни, опасни и тотално идиотски неща за които може да си представите. Всякаква форма на порнография, насилие, оръжие, наркотици, поръчки за убийства, крадени стоки…

Но не само. Тези мрежи имат и хубава страна, те позволяват на хора анонимно да обменят информация. Да приемем, че сте в Китай, или друга подобна държава, и имате различни политически възгледи от общо-приетите. Не може да общувате свободно, ще ви вкарат в затвора, ако сте късметлия ще ви застрелят. Но TOR (и останалите мрежи) позволяват да намерите съмишленици и да обменяте информация по начин недостъпен за „службите“ (на теория)

Това е прост пример, но ясно показва, че монетата винаги има две страни. Анонимността е голяма сила, и може да се използва за хубави или лоши неща.

TOR Browser

Това е специален браузър базирана на Firefox, който знае как да комуникира с TOR мрежата. Всеки може да си го изтегли и използва, напълно безплатен е и е абсолютно легален по всеки един параграф. Самото му използване не означава, че сте виновни за нещо.

TOR browser може да се използва и за достъп до нормалния интернет. Може да влезете във Facebook с него, да използвате google, но имайте предвид, че някой услуги може да не работят както очаквате да работят.

Реално това което прави този браузър е да прекара целия ви трафик (независимо какво достъпвате) през така наречения Onion routing. Това е протокол с няколко слоя (като слоевете на лука) и всеки слой е криптиран отделно. Информацията се изпраща винаги криптирана и задължително минава през специални рутери наречени onion routers, които могат да декриптират само един от слоевете на протокола. По този начин рутера вижда на къде да насочи информацията, но не знае от къде идва и какво съдържа. Респективно крайната точка (получателя) получава информацията, но си няма и на идея от къде е дошла. Това е доста силно опростяване на сложната математика и CS на протокола, но мисля, че разбирате идеята. Това дава силната анонимност на TOR мрежата, никой по целия път не може да вземе едновременно кой е изпращача, кой е получателя и каква е информацията.

Ако искате да видите какво има в тъмния интернет трябва да използвате спецални адреси за страниците, които завършват с разширението .onion. Няма да ви казвам как да си ги намерите, ако толкова сте ентусиазирани ще си намерите някоя „входяща“ точка, която има списък със onion сайтове, или търсещи системи. Да, има няколко доста сериозни търсещи системи специално за onion мрежите, и естествено те са достъпни само през TOR browser.

Ако решите да използвате TOR за нормалния интернет не се изненадвайте ако google и други сайтове започнат да си мислят, че се намирате в Испания, USA, Русия, Камбоджа… Това е следствие от анонимността, зависи от кой onion router ще излезете в нормалния интернет. Реално всяка заявка излиза през различен рутер (на теория).

Сигурност на TOR мрежата

TOR е най-известната такава мрежа, една от най-масовите и една от най-богатите на гадости, но трябва да разберете, че TOR не ви гарантира абсолютна сигурност. TOR е компрометирана мрежа, и въпреки, че е много трудно да се следи в нея, не е невъзможно. Има няколко вектора на атака които се използват. Единия е компрометиране на някой от onion routers, най-вече на граничните такива и с леки модификации определен сървър или посетител може да бъде локализиран.

Както казах, не е тривиално, но ако някой се заинтересува доста от вас и целенасочено почнат да ви търсят ще ви намерят дори да ползвате VPN към машина в друга държава, и от там да влизате в TOR мрежата.

Сегашното състояние на TOR мрежата е, че ресурса необходим за проследяването и задържането на някой е голям. Но ако почнете да правите големи золуми и стане оправдано намирането ви, ще бъдете намерени.

Това го казвам от личен опит. Преди време бях част от група която издирваше един определен тип потребители в TOR мрежата. За под 1 ден бяха локализирани и започнаха стандартните полицейски практики по събиране на информация и последващ арест. Не мога да споделя детайли, нямам NDA, но не мисля, че хората, които в момента са в затвори в няколко държави в EU ще се радват да ме видят.

Така че помислете си добре какви глупости ще правите там.

От години термина „Пълна анонимност“ не съществува!

 

 

 

Още една причина поради която избягвам използването на NodeJS

Не, няма да хейтя, въпреки че NodeJs има толкова матял за хейт и сърказъм.

Проблемът за който искам да споделя не е бъг, а е фундаментална грешка в NodeJS, която едва ли някога ще се оправи. Говоря за асинхронността, и най-вече, че според NodeJS религията всичко трябва да бъде асинхронно.

Тази псевдо асинхронност (nodejs работи само на една нишка) често помага и много процеси са изградени и модифицирани за да се „възползват“ максимално от нея, обаче има едни ситуации в които става кошмарно. Нека да ви дам реалистична постановка.

Да приемем, че имаме библиотека, която има метода addAgent(). На този метод трябва да се подаде външен обект, писан от мен, който има метода invoke(param1,param2). Библиотеката в даден момент ще извика този мой метод с тези параметри и очаква отговор от него. Важното в случая е, че библиотеката очаква точно определен отговор (обект) с който да може да работи веднага.

До тук всичко е прекрасно, нали? Обаче аз искам в метода invoke() да направя мрежова заявка за да мога да си свърша работата. Обаче в NodeJs мрежата е асинхронна, което означава, че метода invoke() връща веднага с null, което чупи всичко. Отново казвам, че библиотеката чака отговор и иска да работи веднага с него. NodeJS няма решим на синхронна мрежова заявка, така в която метода чака или както е правилно да се каже „да блокира“.

Естествено, аз не съм експерт в NodeJS и започнах да разпитвам хората които уж го разбират. Много е интересна демографията на NodeJS програмистите, това си е за отделна тема, но всеки започна да ми обяснява, че не трябва да го правя синхронно, това било много грешно.

Отне ми доста усилия да обясня, че самата библиотека, алгоритъма и целия процес които правя фундаментално е синхронен и НЕ може да се направи асинхронно. Ако успея да го направя най-вероятно ще съм решил Halting problem, само че е доказано, че това е невъзможно.

Разбира се, предложиха се опции. Едната е да се използват Promises, проблема обаче е, че метода ще върне Promise а не обект с който библиотеката да може да работи веднага. Не става.

Предложиха да се използва yield, само че yield ще върне генератор, а не отговора. Имаше и други забавни, креативни и умни предложения, но нито едно не става, просто защото проблема е в това, че фундаментално синхронна операция се опитваме да я изпълним асинхронно.

Накрая ми казаха да пренапиша библиотеката – сериозно? Да пренаписвам библиотека заради това? Ок, да приемем, че реша да го направя, тогава ще трябва да почна да работя с Promise, което значи, че аз трябва да пренапиша абсолютно цялата библиотека почти от 0 и резултата ще бъде, че тя ще изпълнява последователни операции, ама всяка една от тях ще е асинхронна, и докато асинхронната операция върви, всичко ще чака тя да свърши. Сериозно?

Естествено започнаха да ми обясняват, че този който е писал библиотеката нищо не разбира от програмиране и целия и дизайн явно е объркан, щом не я е предвидим да работи асинхронно. Не знам защо, ама това е много типично поведение за NodeJS програмист, щом не става по неговия начин значи е грешния начин. Само че тази библиотека и реализацията и е синхронна защото решава синхронен проблем. Не ми се мисли колко комплексно ще стане всичко с Promises или callbacks, предвид факта, че има и динамично програмиране в нея. А и имам сериозни основания да смятам авторите на библиотеката за доста сериозни и кадърни хора, много по-добри програмисти от мен.

Накратко – асинхронността на NodeJS може да е полезна в много случай, но не и във всички случай, и когато човек удари такъв случай няма оправяне. Идеално би било да дадат възможността на програмиста да решава дали да изпълнява нещо по асинхронен или синхронен начин. Има синхронни файлови операции, нали? Защо са ги направили? Ами нали искат всичко да е асинхронно, да ги махнат, пък да видим тогава реване и гимнастика как ще пишат елементарни програми за работа с файлове…

Един от отговорите които получих на този въпрос бе „Ами като не им даваме възможност програмистите се учат да пишат асинхронно и не правят глупости и не се карат кое как да е“. На това аз ще отговоря следното – NodeJS има претенции да е general purpuse mature programing language. Ако иска да е такъв трябва да позволява да се правят general purpose неща, а не да ограничава практики доказвани над 60 години от академици.

Накрая намерих решение, на някой му е писнало от тези простотии и е написал nodejs модул на C++, който прави синхронни мрежови заявки. Казва се netlinkwrapper.

След приключването на този proof of concept по който работя се махам от nodejs и не искам и да го погледна повече. 4 дни прекарах в търсене на начин за една шибана синхронна операция…

Дори и хората които правят CUDA оставят възможност за синхронност, а те са водещите в момента по отношение на паралелизъм и асинхронност.

 

 

 

Когато популизмът стане наистина опасен

Рядко пиша за политика и гледам да седя далеч от тези теми в този блог – политиката си е за политиците. Обаче великият неповторим стожер на България, единственият и ненадминат вокален експериментатор, завършил колеж за непорочни девици, винаги правият Слави Трифонов, започва да бута нещата към много, ама много опасна пропаст.

Естествено говоря за прочутия му референдум и най-вече факта, че част от въпросите ще бъдат изпратени за тълкуване от Конституционния съд. И този господин с цялата си медийна власт обяснява колко ужасно лошо е това и как цялото управление (включително и опозицията) се опитвали да пренебрегнат „желанието на народа“.

Нека да изясним няколко неща – първо, не народът е измислил тези въпроси, а някой от неговия екип (надявам се). Референдум ще има, това е ясно, даже и датата е ясна. Никой не прескача никого и нищо. Не съм психиатър или психолог, но нещата малко ми приличат на шизофренична параноя. 20+ години този господин само обяснява как някой го мачка, респективно народа, как все има конспирация срещу него, следователно срещу народа, как все някой нещо нередно прави, разглеждайки частни случаи, махайки контекста на глобалното… Как един път не похвали някого…

Обаче този господин, който, както предполагам се досещате, не уважавам, излиза с тежки тези и тълкувания и цитира чл. 1 на Конституцията, който гласи:

Цялата държавна власт произтича от народа. Тя се осъществява от него непосредствено и чрез органите, предвидени в тази Конституция.

Неговото тълкование е, че щом властта произлиза от народа, народът може да си прави каквото си иска, обаче обърнете внимание на второто изречение:

Тя се осъществява от него непосредствено и чрез органите, предвидени в тази Конституция

Тоест, най-важният закон казва ясно, че властта на народа НЕ е абсолютно директна, а преминава през органите, които спазват правилата на тази конституция. И в същата тази конституция (и законите произтичащи от нея) пише много ясно, че референдум НЕ може да се свиква по въпроси от компетенцията на Велико народно събрание. Следователно, ако трябва да се спазва закона, за което този господин непрекъснато реве, референдум по някои от въпросите не може да се проведе, защото самият референдум ще наруши конституцията и всеки българин гласувал по тези въпроси ще наруши Закона.

Ето за това има конституционен съд, съставен от юристи с достатъчно опит и разбиране, за да могат да решават да или не. Не разбирам как сезирането на законен орган по въпрос от компетенцията му, може да се интерпретира като опит за манипулация.

Какво толкова ще си кажете, някой си реве, кое му е опасното, референдумите са хубаво нещо. Ами конкретно 3 въпроса са изключително опасни, и ще се опитам да ви обясня моето лаишко виждане на на нещата.

Въпрос 1

Подкрепяте ли народните представители да се избират с мажоритарна избирателна система с абсолютно мнозинство в два тура?

Ох боже, даже не знам от къде да започна. Може би като обясня какво ще стане, ако това се приеме – това означава (най-грубо), че ще се гласува за конкретни хора а не за партии. Това е най-краткият път за създаване на феодално управление. Някой „богаташ“ в по-малък град ще „помогне“ на някоя „личност“ да бъде избрана и тази личност, която в никакъв случай няма да бъде в зависимост и конфликт на интереси, директно заминава за парламента, без значение от коя партия е. Прекрасно, и в един момент ще имаме 240 човека, които обслужват директно интересите на някой местен батка с авангардни маниери и съмнителни интереси. Не всички са такива, но проблемът е, че се разбива едно основно звено в сегашната политическа система – политическите партии и тяхната сила да взимат единно решение.

В момента партията излиза с политики, единна позиция и лидери. Представете си консенсус между 240 човека, които директно обслужват интересите на точно определени хора в различни части на страната? Е, аз не виждам как ще стане.

Но нали все пак това е идеята? Тези хора да се грижат за интересите на народа и районите, от които са избрани? Така е, само че понякога има форсмажор, външна политика, приоритети и какво ли още не, което изисква ЕДИННОСТ.

На една сграда пише „Съединението прави силата„. Приемането на този въпрос няма да доведе до съединение, а до дърпане и късане на малки парчета от това, което е останало. Опитайте се да разберете колко фундаментална промяна е това, погледнете малко историята. Доста по-малки промени в управлението са водели до ужасни последствия.

Въпрос 2

Подкрепяте ли броят на народните представители да бъде намален на 120

Не, не, и НЕ. Намалянето на броя на депутатите ще доведе до по-трудно формиране на мнозинство, колкото и противоречиво да ви звучи. Помислете си само, при 240 депутата един пръст обърна цялата политика на България преди години. Говоря за Волен Сидеров и последвалите безумия. Статистиката и простата математика са доста ясни тук, при 120 човека НЕ може да има ефективно работеща система.

Може би ще изтъкнете аргумента, че в някой по-големи държави от нас имат по-малко депутати, и сте прави, но те имат други закони, правила и интереси. Тази цифра не е измислена от нищо. Тя е съобразена с законите, народа и политиката. Аз лично бих гласувал броят им да се увеличи, вместо да се намаля. И не, депутатските заплати и премии не са толкова много на фона на общите държавни разходи.

Този въпрос в комбинация с първия означава даването на властта на една много малка група хора, която може да седи в сянка. Точно обратното на това за което се бори двуметровият еродит.

Въпрос 6

Подкрепяте ли директорите на областните дирекции на МВР и началниците на районните управления в областните дирекции на МВР да се избират с мажоритарна избирателна система с абсолютно мнозинство в два тура

Ох боже мои, искам да разбера по какви логически пътища са достигнали до този въпрос, може би съм прост и не разбирам, но ако това се приеме, отново означава, че не може да се прилагат общи политики на национално ниво, а всеки локален феодал ще си дърпа чергата към него.

Представете си малък град , 1-2 човека са богати, те са „помогнали“ за издигането на шефове на репресивните органи  в техния район и да кажем, че някой от тези господа е решил да се прибере пиян с новия си джип и прави инцидент. Този, който ще трябва да го съди/разследва/арестува, е този, който е в зависимост от него. Има ли смисъл да продължавам? Имате виждане за действителността в България, имате и въображение. Помислете…

Комбинацията от тези 3 въпроса реално правят така, че местни феодали ще имат абсолютна власт и ще са тотално недосегаеми. Останалите въпроси от референдума за мен са напълно нормални, но тези 3 са меко казано опасни.

Може би някой ще изтъкне аргумента, че щом изборът ще е директно от народа, феодалът няма да може да сложи негови хора. Ако това е вашият аргумент, не знам под каква скала сте живели. В един малък град едно предприятие може да дава основния поминък. Какво ли ще стане, ако шефът на това предприятие „помоли“ всички свой служители да подкрепят опреден човек? Не, това не може да се случи, нали? Ха, Ха, Ха!

Една маймуна не се пуска от клона докато не се е хванала за друг. Това което се предлага е не да се пуснем от клона без да се държим за друг, а направо да си теглим куршума сами.

От кога куцо, кьораво и сакато си мисли, че може да представлява народа?

Какво представлява Dependency Injection (DI)

Този пост е инспириран от коментар в предишен пост където започна лека дискусия относно създаването на нови инстанции на обекти в самите обекти. Но нека да започнем от самото начало:

Какво точно е DI

DI е част от общо приети добри практики в програмирането подобно на S.O.L.I.D, които не са абсолютни и задължителни, но съобразяването с тях, доколкото е възможно, води до по-добра архитектура, намалява „спагети код“, премахва скритите зависимости, позволява по-доброто преизползване на код и много други хубави работи. D в S.O.L.I.D е за  Dependency Injection.

D в S.O.L.I.D е за Dependency inversion, което е различно от DI.
Много имплементации обединяват Dependency Injection и Dependency Inversion в едно.

Идеята е изключително проста, DI позволява класовете да не се интересуват от създаването на своите зависимости, а да ги получават на готово. Нека да видим следния код:

class Payment{    
    public function __construct(){
        $this->gataway = new PayPal();
        $this->db = new MySQLDB();
        $this->invoice = new Invoice();
    }
} 

Примера е изкуствено опростен, но мисля че се вижда ясно какво се опитваме да направим – да извършим плащане през PayPal, да го отразим в базата и да издадем фактура, като за това се грижи бизнес логиката в класа Payment, или още по-просто казано – имаме обект, който за да си свърши работата има нужда от външни за него ресурси.

И точно тук имаме огромен проблем, самият клас Payment създава всички свой зависимости в себе си, които от своя страна може да имат свой собствени зависимости. Това е изключително лоша практика поради много причини, но някой от основните са, че ние сме създали пряка зависимост – този клас за да работи трябва да има достъп до другите класове с техния namespacе и тяхната конкретна имплементация. Този клас може да бъде използван само в тази „среда“, ако решим да го изнесем като библиотека ще трябва да вземем и останалите класове от които зависи и да задължим потребителя който ще го използва да използва и нашите класове за DB, Invoice, PayPal. Това е кошмарно, никой уважаващ себе си софтуерен архитект не би допуснал това да се случи.

Другият, според мен, по-голям проблем е, че няма лесен начин за подмяна на имплементация. Какво ще стане ако имаме нужда в определена ситуация да използваме друг payment процесор, примерно Stripe? Останалата логика е еднаква, разликата е кой ще обработи плащането. Единия вариант е да правим различни „магии“ с наследяването или не дай си боже с рефлекции и магически методи (не го правете, така ще се застреляте, че няма оправяне). Другата опция е следната „класика“:

class Payment{    
    public function __construct($gataway){
        if($gataway=="PayPal"){
            $this->gataway = new PayPal();
        }
        else{
            $this->gataway =n ew Stripe();
        }        
        $this->db=new MySQLDB();
        $this->invoice = new Invoice();
    }
}

Изглежда сякаш проблемът е решен, но не е. Даже напротив, създали сме още по-лоша ситуация при която страдаме от всички недостатъци на предишния подход но сме добавили и допълнителни зависимости. Не е особено трудно да си представите какво ще стане с този конструктор след няколко итерации на продукта, добавяне на нови изисквания и имплементации – конструктор с прекалено много IF/ELSE и тотален кошмар при поддръжка, разширяване и тестване.

Инжектиране на зависимости

Значи излиза, че проблемът е в създаването на обекти в самия обект, добре, какво ще стане ако тези зависимости ги предаваме като параметри:

class Payment{    
    public function __construct($gataway,$db,$invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Изглежда сякаш проблемът е решен, обекта вече чака на готово зависимостите, но това е просто прехвърляне на сложността от едно място на друго. Преди сложността бе в самия обект, сега е задължение на този, който ще използва обекта да знае всичките му зависимости и да се съобрази с тях.

Кода написан по следния начина по-горе има и друг проблем, специфичен за слабо типизираните езици като PHP – конструктора приема някаква променлива, но тя може да е всичко, не сме задължили предаването на точно определен тип. Какво ще стане ако за $db се подаде String? Ами всичко ще гръмне. Конкретно в PHP това се решава така:

class Payment{    
    public function __construct(PayPal $gataway,MySQLDB $db,Invoice $invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Така задължаваме използването на точно определени класове, не може да подадем String или нещо друго в конструктора. Обаче все още не е решен друг проблем – какво правим ако искаме да сменим имплементацията, примерно искаме да използваме Stripe? Не може да подадем Stripe обект защото конструктора очаква PayPal обект. Едната опция, която в някой частни случай е добра, но като цяло трябва да се избягва е да имаме общ базов клас:

class PaymentProcessor{
    
    public function pay(){}
}

class PayPal extends PaymentProcessor{}

class Stripe extends PaymentProcessor{}

class Payment{
    
    public function __construct(PaymentProcessor $gataway,MySQLDB $db,Invoice $invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Забележете, че вече Payment не очаква Paypal или Stripe, а очаква PaymentProcessor. По този начин, ако някой реши да си прави негов си процесор трябва само да наследи базовия клас PaymentProcessor и всичко ще работи, защото ние гарантирано, че метода pay() ще е наличен. Искам отново да отбележа, че това са изкуствено опростени примери, в реална ситуация може би ще е по-добре да се използва абстрактен клас, но всичко зависи от конкретните нужди.

Изглежда има напредък, махнахме зависимостите от самия обект, също така позволихме подмяна на имплементацията използвайки базови класове, но и това не е идеален вариант. Все още има зависимост към базовия клас – PaymentProcessor. Ако искаме да изнесем класа си в библиотека ще трябва да включим и PaymentProcessor заедно с неговите зависимости. Може да не ви се струва много, но колкото по-малко зависимости имаме, толкова по-добре. При по-комплексни системи тези „малки“ зависимости ескалират много неприятно.

Кодиране спрямо интерфейс

Нека да помислим какво е необходимо на класа Payment, като се съсредоточим конкретно за payment процесора, същите правила важат и а останалите класове.

Единственото необходимо е инстанцията която се предава да има серия от точно определени методи за да гарантираме, че когато Payment се опита да извика метода pay() той ще съществува. Как може да го направим като не използваме базови/абстрактни класове? Ами много е просто – интерфейси.

Ако не сте запознати (а трябва) интерфейсите са договор. Те нямат имплементация, те задължават класа който ги имплементира да има методите описани в интерфейса. Доста по-просто е отколкото звучи:

interface PaymentProcessor{
    
    public function pay(){}
}

class PayPal implements PaymentProcessor{}

class Stripe implements PaymentProcessor{}

class Payment{
    
    public function __construct(PaymentProcessor $gataway,MySQLDB $db,Invoice $invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Разгледайте кода по-горе внимателно, разликите са много малки, но много съществени. Създаваме интерфейс PaymentProcessor който задължава всеки клас който го имплеметира да има метода pay(). След което казваме на класа Payment, че ще приема само и единствено обекти, които са имплементирали интерфейса PaymentProcessor. По този начин е гарантирано, че обекта ще има метода pay() и няма да изгърми с МethodNotFound  или подобно.

Но най-голямото предимство на кодирането спрямо интерфейс е, че ние нямаме зависимост спрямо имплементация. Когато се използва базов/абстрактен клас ние имаме серия от методи, които имат конкретна имплементация (в базовия клас) и задължаваме всички да се съобразяват с нея. А това е излишно. Единственото от което се интересува класа Payment е да има обект, който има метод pay() който ще извърши плащането и евентуално ще върне резултат. Каква е имплементацията на pay() няма значение.

И сега ако искаме да изнесем класа си в библиотека ще е лесно, ще трябва да включим само интерфейсите и никаква конкретна задължаваща имплеменация. Това е основата на така наречения Dependency Inversion, някъде може да срещнете абревиатурата IoC (Inversion of Control) което е същото нещо, като изключим семантичните разлики и дефиниции, но това не е DI, това е техника която работи много добре с DI.

Още проблеми

До момента решихме един от проблемите, а именно как да премахнем ненужните зависимости като кодираме спрямо интерфейс, и това само по себе си е много добре, но все още остава сложността по създаването на обектите – за да направим нова инстанция на Payment ще трябва да направим нова инстанция на класове за PaymentProcessor, Invoice и DB. На пръв поглед това не е кой знае какъв проблем, все пак всичко е ясно и стриктно. Обаче не е точно така. Нека разгледаме следната ситуация, на много места в програмата ни ще имаме нужда от база данни, и ако сме добри програмисти ще сме кодирали базата данни спрямо интерфейс, и там където трябва база данни ще си правим конкретна инстанция и ще я предаваме на различните обекти. Примерно:

interface iDB{
    
    public function select(){}
    public function insert(){}
}

class MySQLDB implements iDB{}

class PostgresqlDB implements iDB{}

class User{
    public function __construct(iDB $db){}
}

class Account{
    public function __construct(iDB $db){}
}

$db = new MySQLDB();
$user = new User($db);
$account = new Account($db);

Едва ли някой някога някъде ще реализира DB по този начин, но опитайте се да разберете идеята, а не конкретната имплементация.

Правим инстанция на конкретен клас и го предаваме на всички обекти, по този начин, ако решим в един момент да използваме PostgresqlDB само ще трябва да сменим инстанцията. Обаче на практика нещата не са толкова прости. Имаме стотици обекти със своите зависимости, ако трябва да сменим имплементацията ще трябва да отидем ръчно да я сменим на много места. Предполагам веднага се досещате, че може да използваме нещо като Registry или „глобална“ променлива, която ще държи инстанцията на DB. Тоест, само на едно място правим new iDB и всички които зависят от нея използват тази „променлива“. Така ще се наложи да сменим кода само на едно място. Звучи логично, но практиката сочи друго.

Използването на глобални променливи и Registry само по себе си води до проблеми, но най-вече ако се избере този подход какво правим, ако различните класове имат нужда от различни инстанции. Един и същи клас, просто различни инстанции. Понеже държим само една инстанция в глобална променлива (или някъде другаде) всички ще ползват една и съща инстанция, което често е нежелано.

Също така често се случва да правим инстанция на клас и да предаваме зависимостите му, които обаче също имат зависимости, които също имат зависимости….

Много бързо може да попаднем в ситуация при която е много трудно да напишем код за нова инстанция. Не защото нещо не е ясно, а защото е много „замотано“ и управлението на всички тези инстанции може лесно да се превърне в една голяма безумна серия от IF/ELSE забутани в някой файл с коментар от типа на:

While writing this code only me and god knew hоw it works. Now only god knows

DI в действие

DI е механизъм, който (най-често) използва кодиране спрямо интерфейси за да оправи цялата сложност по създаването на новите инстанции и тяхното инжектиране. Различните езици и библиотеки имат различни имплементации, но всички се свеждат до следните прости стъпки:

  • Пишете си кода спрямо интерфейси
  • Декларирайте зависимости на обект като опишете интерфейсите в конструктора на обекта
  • Дефинирайте коя конкретна имплементация трябва да се използва е момента (най-често в конфигурационен файл) и решете какво да е поведението и, дали да е само една, или всеки път да се прави нова инстанция

Това е, нищо сложно, понеже DI контейнера се грижи за всичко останало.

Ще се опитам да дам донякъде реалистичен (силно опростен) пример от света на PHP и Laravel как точно се случват нещата, но всички езици и frameworks имат множество DI библиотеки, които се различават и имат различни възможности.

interface SessionStorage{
  public function get( $key );
  public function set( $key, $value );
}

class FileSession implements SessionStorage{

  public function get( $key ){}

  public function set( $key, $value ){}
}

class MysqlSession implements SessionStorage{

  
  public function get( $key ){}

  public function set( $key, $value ){}
}

class Session{

  protected $session;

  public function __construct( SessionStorage $session ){
    $this->session = $session;
  }
}

App:bind( 'SessionStorage', 'MysqlSession' );

$session = $this->app->make('Session');

Нека да видим какво точно се случва тук. Първо правим интерфейс какво трябва да може да прави  всеки един SessionStorage клас. След това декларираме конкретните имплементации. До тук е ясно. Магията е в последните два реда.

App:bind( 'SessionStorage', 'MysqlSession' );

Тук казваме на Laravel, че когато нещо някъде има нужда от SessionStorage ще използва MysqlSession

$session = $this->app->make('Session');

А така караме DI контейнера да направи нова инстанция на Session, която зависи от интерфейса SessionStorage. В този случай обекта Session ще получи автоматично MysqlSession в конструктора си. Ако в последствие решим, че искаме да използваме FileSession ще трябва да сменим само един ред:

App:bind( 'SessionStorage', 'FileSession' );

Разбира се, това е много елементарен пример, но показва ясно колко работа може да си спестим. Този подход работи много добре с тестване, continuous integration и автоматизация, защото кое какво използва се определя на едно място, което може да е конфигурационен файл.

Също така повечето хубави DI контейнери имат много възможности, добавяне на условия кога коя имплементация да се използва, дали да е една за всички или не, тагове, рециклиране…. Но ако разберете тази проста идея няма да имате затруднения в разбирането на останалите детайли.

Някой от вас ще си кажат, че това може да го постигнете и с нещо като Factory. Има допирни точки, но при Factory шаблона трябва да се опишете всичко на ръка, което ще доведе до безумна серия от IF/ELSE или нещо подобно. С DI този процес е автоматизиран. Също така в PHP света (и не само) има тенденция да се правят спецификации и стандарти за интерфейси. Примерно какви са интерфейсите за кеширане, за HTTTP заявки и подобни, и всички библиотеки започват да пишат спрямо тях. При използване на DI и общи интерфейси може да подмените огромна подсистема само с един ред код.

Недостатъци на DI

Това не е панацея, DI има своите проблеми и недостатъци, но ситуацията е, че тези недостатъци са по-малкото зло, а и някой от тях може да се премахнат или намалят използвайки добри практики. Ето някой от основните критики.

Кода ни е силно зависим от самата DI библиотека Не може лесно да сменим DI контейнера. Иронично DI, който се бори със зависимостите, създава зависимост. Но според мен това не винаги е проблем, от гледна точка, че DI е част от framework-а който използваме, Ако имаме причина да подменяме целия framework явно имаме по-големи проблеми от DI контейнера.

Често може да се загубим от интерфейси, особено при по-големи проекти. Решението на този проблем е добра софтуерна архитектура – нещо което така или иначе трябва да се прави независимо от езика и проекта.

Честа критика е, че DI реално скрива сложността и създава нов слой между частите на приложението ни. Еми, то тази сложност трябва да отиде някъде, нека поне да е на място където може да се контролира.

Изисква повече знания  – ами то сложен професионален проект така или иначе си ги изисква.

Забавя производителността – понеже DI ползва (най-често) рефлекция има известно забавяне понеже всеки обект трябва да се провери, да се види от какво зависи и да се вземе конкретната имплементация. В зависимост от конкретната реализация това време може да е доста сериозно. Също така има нужда от малко повече RAM. Но добрите DI контейнери са силно оптимизирани и отнемат само няколко милисекунди. Може да видите сравнение между различните DI в света на PHP  в този много детайлен пост (цък)

Заключение

Dependency injection е механизъм който се е доказал като успешна практика за големи дълги проекти, които се развиват с години. Концепцията е тествана в битки на много езици и като изключим някой части на чистото функционално програмиране, се препоръчва да се използва винаги когато може.

Времето за научаване на конкретен DI контейнер не е голямо, по-големият проблем е програмистите да сменят мисленето си и да започнат да пишат кода в контекста на DI.

Дори и да не се използва DI, писането спрямо интерфейси ще е полезно за проекта за напред. Много хора критикуват Java, че прекаляват с OOP и интерфейсите, но това е начина по който може да държите проект от няколко милиона реда код 10 години, който се пише от 1000 различни екипа и все още да работи и да се развива.

Разбира се, ако не сте фенове може да минете на чисто функционално програмиране 🙂

Уточнение:

В статията разглеждам две концепции, Dependency Injection и Dependency Inversion. Двете работят много добре заедно, но не е задължително винаги да се използват в комбинация. Може да имаме Dependency Injection без да пишем спрямо интерфейси, а примерно с абстрактни класове, също така може да пишем спрямо интерфейси и да не използваме Dependency Injection.

Как е подреден IT сектора в България

Забелязвам, че често хората, най-вече начинаещите, не са напълно наясно, че в България има 3 основни типа фирми в IT и ще се опитам да дам малко яснота. В никакъв случай тази статия не претендира за пълнота, идеята и е да опиша сбито основните сектори и техните основни разлики. Това не са абсолютни граници, някои фирми и проекти често не могат да се определят категорично в някой от секторите.

StartUp

Всеки е чувал този термин, ако сте поне малко на ти с компютрите малко вероятно е да нямате поне един познат, който да се е занимавал с някакъв StartUp. Но какво точно представлява това? Най-общо казано StartUp е новосъздаден продукт (независимо дали говорим за услуга или физически продукт) който получава финансиране от някой инвеститор в замяна на процент от компанията. StarUp фирмите често пробват новаторски и интересни идеи, които понякога успяват, понякога не. Самият бизнес модел е много комплексен и аз не смятам, че имам необходимите познания да го разисквам в детайли, но това не е целта на тази статия. Най-важното което трябва да разберат хората е, че инвеститори подпомагат новаторски идеи, при това не една и две. Голяма част от тези идеи няма да успеят, но инвеститорите са наясно с това. На тях е необходимо само малък процент наистина да успеят. Никой няма да се сърди, че 10 идеи са пропаднали, но 11-та се е оказала SnapChat. Това правят инвеститорите, хвърлят мрежата и виждат какво ще се улови в нея. Само че мрежата е много добре премислена, пресметната и анализирана.

Какви качества са необходими за да работите в StartUp

Основната идея на StartUp е максимално бързо да се извади продукт на пазара. Не е задължително той да бъде напълно завършен или перфектен. Най-важното е времето – всичко трябва да стане бързо. По тази причина основния тип програмисти които се търсят са средно и напреднало ниво. Може би най-характерното за този тип компании е тяхната нагласа и желание да „променят света“, да извадят следващия продукт който ще се използва от всички, или ще реши някой сериозен проблем. По тази причина се търсят хора, които вярват в тази идея, мотивирани са това да се случи, и са склонни да отделят повече от своето време и енергия, отколкото принципно се изисква.

Какви са заплатите в StartUp

Няма как да обобщя заплатите в толкова разнороден сектор, също така много зависи в кой етап от развитието си е проекта, но често се предлагат по-ниски заплати в замяна на процент от фирмата. А понякога заплатите са по-ниски само срещу обещание за бъдеща по-голяма заплата при „гарантирания“ успех на продукта. Може да мислите за това сякаш служителя влага собственото си време и умения в продукта, а не средства, както инвеститора. Ако продукта стане успешен тогава заплатите ще зависят от конкретната политика на фирмата.

Предимства

  • Често се започва от самото начало, без наследен код и технологии
  • Решенията се взимат от екипа
  • Често се експериментира и се използват най-новите технологии, които дори не са се доказали. Всичко е на гребена на вълната
  • Силно мотивирани хора
  • Реална възможност за сериозни приходи, ако продуктът успее

Недостатъци

  • Всичко се променя в движение
  • Динамиката и натоварването са доста големи, което за някои хора може да не е комфортно
  • Рискът за провал не е малък. Не кода и техническата реализация са основната причина за „провал“ на StartUp

Продуктово-ориентирани фирми

Много фирми имат екипи, които разработват един или няколко продукта, които обслужват самите фирми. Типичен пример е компания, която разработва счетоводен и ТРЗ софтуер. Това е продуктът, всички работят по него, компанията го продава. Разбира се, има много вариации, може да се разработва продукт който обслужва нуждите на други фирми. Обикновено всички решения за развитието на този продукт се взимат от фирмата която го разработва. Това позволява по-детайлно планиране и управление на процеси и ресурси.

Какви качества са необходими за да работите в продуктово-ориентираните фирми

Тук няма ясни тенденции, има всякакви примери. Поради недостиг на персонал много фирми имат стажове, обучителни програми или цели академии. Не е рядкост в тези компании да започват хора с малко знания и практика като се залага на потенциала на кандидата. Точно за това са тези стажове и обучения, за да се преценят кандидатите в които ще бъде инвестирано. В момента продуктово-ориентираните фирми са предпочитани от повечето старши програмисти заради множеството предимства и по-балансираната работна среда и условия на труд.

Какви са заплатите в продуктово-ориентираните фирми

Това е сектора с най-високи заплати. Отново правя уточнението, че това е обобщено. Винаги има изключения. Причината е, че самите фирми са заинтересовани да задържат служителите си, които са запознати със спецификата, някои от тях са станали тесни специалисти. Никой не иска да сменя части на добре работеща машина. Някой компании имат точно обратния подход, те са организирали процеса си така, че ако има голямо текучество на персонал, това да не повлияе на приходите, но по мои наблюдения тези фирми не са толкова много. В тези фирми заплатите са по-ниски.

Предимства

  • Добро заплащане
  • Инвестиции в професионалното развитие. Платени курсове, платени билети за конференции и подобни
  • В повечето случаи добре подреден работен процес
  • Ясни отговорности, задължения и задачи
  • Ясна визия какво трябва да се случи
  • Дългосрочни отношения
  • Специализиране и развиване на сериозни умения в точно определени технологии. За някой това може да е недостатък, но аз го намирам за предимство.

Недостатъци

  • Много рутинна работа и еднообразие. За някой това може да е желано.
  • Свръх тясната специализация закърнява други умения. По тази причина някои компании периодично сменят задачите на служителите си за да може да се развиват  и в други технологии
  • Често се работи с наследен код и технологии, чиято подмяна е трудна, ако въобще е възможно.

Аутсорс и дигитални агенции

Това е най-големият сектор в България, който буквално се къса по шевовете. Най-голямото търсене на специалисти е точно тук. Ако не сте запознати с термина, аутсорсинг, най-грубо може да се опише като наемане на група от специалисти за решаването на точно определена задача. Не е необходимо да бъде цялостен проект, може да бъде една малка част от по-голям проект. Някои компании предлагат цялостен пакет услуги, от дизайн, разработка, поддръжка, SEO … Най-голямата особеност на този сектор е, че клиентите често не са технически лица. За пример, местна пицария иска страница и мобилно приложение. Те са добри в пиците, не в IT, за това се свързват с някоя дигитална агенция, която изгражда всичко необходимо. Друг пример е голяма компания разделя свой проект на по-малки части и ги разпределя на няколко екипа по света, като всеки екип прави само малка част. Това се прави за намаляване на риска, намаляване на разходите и отпадането от поддържането на голям IT отдел.

Какви качества са необходими за да работите в аутсорс и дигитални агенции

България е предпочитана локация за по-бързо реализуеми проекти. Разбира се има и изключения, но повечето поръчки са за малки локални проекти и временни нужди на маркетинга. Поради тази причина, заедно с факта че липсват над 33 000 специалиста, в аутсорс сектора повечето хора са начинаещи или напреднали. Никой няма да откаже на старши програмист или старши дизайнер, но  тенденцията е старшите да се махат от аутсорса започвайки свой бизнес (startup или freelance) или минавайки в продуктово-базирани фирми. Това е най-лесният сектор в който начинаещ програмист може да влезе в „играта“ и да започне да трупа реални умения и практика. Искам да спомена за една малка група фирми в България, които са аутсорс, но са се специализирали в дългосрочни, сложни и мащабни проекти. При тях обикновено се взимат старши специалисти и управлението им се доближава до това на продуктово-базираните фирми.

Предимства

  • Лесно се започва работа в тези компании.
  • Обикновено се работи с модерни и актуални технологии. Може да ги видите как работят на практика.
  • Има голямо разнообразие, понеже екипите и проектите се сменят често. За някой това може да е недостатък.
  • Често е необходимо да имате множество умения в различни технологии и можете да прилагате и развивате тези умения.
  • Отговорността на служителя е ниска. За някой това може би е недостатък.

Недостатъци

  • Ниско заплащане с ограничена възможност за растеж. Заплата на служителя е пряко свързана с цената на която е нает. Разбира се, има и изключения, ако фирмата е договорила по-високи цени на час.
  • Клиентите често не са технически лица. Комуникацията с тях е проблематична и често заданията са неясни или технически невъзможни. Добре организираните компании имат PM и AM които седят между клиента и програмиста, но често има фрустрация.
  • Работи се с голяма динамика. Клиентът е платил за точно определени часове, които са договорени преди началото на проекта. Предоговарянето на цената и крайните срокове е  труден процес.
  • Текучеството на хора е голямо.
  • Ограничено кариерно развитие. Тук също има изключения.
  • Понякога има проект чието задание е да се оправят „белите“ от предишна аутсорс фирма. Пренаписването не е опция. Клиентът вече е инвестирал сериозна сума и е трудно да му се обясни защо трябва да дава същите пари за същото нещо отново.

Няма да разглеждам другите два „сектора“ – R&D и freelance, понеже R&D в България е наистина малко, а freelance е толкова индивидуално, че ще е глупаво да се опитам да слагам някакви граници. Но все пак ще спомена с няколко думи, че при freelance всичко зависи от вашите умения да намерите добрия клиент. Има freelance които взимат по $50 – $100 на час, но има и такива които работят за $5 на час. Всичко зависи от вашите умения, контакти и имидж. Най-специфичното при freelance е, че вие сте човека армия, вие сте мениджър на себе си, вие сте PM, вие сте AM, вие сте изпълнителя. Мит е, че при freelance нямате шефове и разполагате с времето си напълно. Най-трудното нещо е да намерите правилните клиенти и да изградите подходящото доверие, за да може да започнете да взимате високото заплащане. Но ако успеете може да вадите изключително високи доходи, високи не за България, а високи за която и да е точка на света. Не е рядка практиката няколко приятеля с различни умения да работят заедно като freelance по общи проекти, и така да започнете свой бизнес. Един full-stack разработчик, един дизайнер и можете да започвате.

Заключение

Опитах се максимално сбито да посоча предимствата и недостатъците на сектора, но сами виждате, че някой от нещата могат да бъдат определени като добри или лоши в зависимост от вашата нагласа. Със сигурност има пропуснати детайли, и ще се радвам да ги споделите в коментарите. Няма знатни правила, няма ясни граници. Всичко се свежда до конкретна фирма. Ако нито едно от горните не ви допада, винаги има опцията да опитате да направите нещо свое. StartUp не е единствената опция за започване на собствен бизнес.