{"id":32848,"date":"2019-10-31T21:49:16","date_gmt":"2019-10-31T18:49:16","guid":{"rendered":"https:\/\/prohoster.info\/blog\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\/"},"modified":"2019-10-31T21:49:16","modified_gmt":"2019-10-31T18:49:16","slug":"vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","title":{"rendered":"Zav\u00e1d\u011bjte statickou anal\u00fdzu do procesu, m\u00edsto abyste ji pou\u017e\u00edvali k hled\u00e1n\u00ed chyb","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Napsat tento \u010dl\u00e1nek m\u011b inspirovalo velk\u00e9 mno\u017estv\u00ed materi\u00e1l\u016f o statick\u00e9 anal\u00fdze, kter\u00e9 se st\u00e1le \u010dast\u011bji objevuj\u00ed. Za prv\u00e9, je to <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/\">blog PVS-studio<\/a><\/noindex>, kter\u00fd se aktivn\u011b propaguje na Habru skrze p\u0159ehledy chyb nalezen\u00fdch jejich n\u00e1strojem v projektech s otev\u0159en\u00fdm k\u00f3dem. Ned\u00e1vno PVS-studio implementovalo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/436496\/\">podporu Java<\/a><\/noindex>, a samoz\u0159ejm\u011b, v\u00fdvoj\u00e1\u0159i IntelliJ IDEA, jejich\u017e vestav\u011bn\u00fd analyz\u00e1tor je dnes pravd\u011bpodobn\u011b t\u00edm nejpokro\u010dilej\u0161\u00edm pro Java, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/JetBrains\/blog\/436278\/\">nemohli z\u016fstat stranou<\/a><\/noindex>. <\/p>\n<p>P\u0159i \u010dten\u00ed takov\u00fdch p\u0159ehled\u016f vznik\u00e1 pocit, \u017ee jde o kouzeln\u00fd elix\u00edr: stiskn\u011bte tla\u010d\u00edtko a voil\u00e0 \u2014 seznam defekt\u016f je p\u0159\u00edmo p\u0159ed v\u00e1mi. Zd\u00e1 se, \u017ee s rozvojem analyz\u00e1tor\u016f budou chyby automaticky nach\u00e1zeny st\u00e1le v\u00edce a v\u00edce a produkty, kter\u00e9 tyto roboty proch\u00e1zej\u00ed, se st\u00e1vaj\u00ed st\u00e1le lep\u0161\u00edmi, bez jak\u00fdchkoliv na\u0161ich \u00fasil\u00ed.<\/p>\n<p>Ale kouzeln\u00e9 elix\u00edry neexistuj\u00ed. R\u00e1d bych promluvil o tom, o \u010dem se obvykle nemluv\u00ed v p\u0159\u00edsp\u011bvc\u00edch typu \u201etady je, co n\u00e1\u0161 robot m\u016f\u017ee naj\u00edt\u201c: co analyz\u00e1tory nikdy nebudou schopny ud\u011blat, jak\u00e1 je jejich skute\u010dn\u00e1 role a m\u00edsto v procesu dod\u00e1vky softwaru a jak je spr\u00e1vn\u011b implementovat.<\/p>\n<p><img decoding=\"async\" alt=\"Zav\u00e1d\u011bjte statickou anal\u00fdzu do procesu, m\u00edsto abyste ji pou\u017e\u00edvali k hled\u00e1n\u00ed chyb\" src=\"\/wp-content\/uploads\/2019\/05\/2a0339f10edcaed3310676ab6e2f975a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Hravost (zdroj: <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A5%D1%80%D0%B0%D0%BF%D0%BE%D0%B2%D0%BE%D0%B9_%D0%BC%D0%B5%D1%85%D0%B0%D0%BD%D0%B8%D0%B7%D0%BC#\/media\/File:Sperrklinke_Schema.svg\">wikipedia<\/a><\/noindex>).<\/i><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Co nikdy nebudou schopny statick\u00e9 analyz\u00e1tory<\/h2>\n<p>\nCo je z praktick\u00e9ho hlediska anal\u00fdza zdrojov\u00e9ho k\u00f3du? Dod\u00e1me ur\u010dit\u00e9 zdroje a b\u011bhem kr\u00e1tk\u00e9 doby (daleko krat\u0161\u00ed ne\u017e pr\u016fb\u011bh test\u016f) z\u00edsk\u00e1me jist\u00e9 informace o na\u0161em syst\u00e9mu. Z\u00e1sadn\u00ed a matematicky neodvratn\u00e9 omezen\u00ed spo\u010d\u00edv\u00e1 v tom, \u017ee t\u00edmto zp\u016fsobem m\u016f\u017eeme z\u00edskat pouze pom\u011brn\u011b \u00fazkou t\u0159\u00eddu informac\u00ed.<\/p>\n<p>Nejzn\u00e1m\u011bj\u0161\u00edm p\u0159\u00edkladem \u00falohy, kterou nelze vy\u0159e\u0161it pomoc\u00ed statick\u00e9 anal\u00fdzy, je <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Halting_problem\">probl\u00e9m zastaven\u00ed<\/a><\/noindex>: to je v\u011bta, kter\u00e1 dokazuje, \u017ee nelze vyvinout obecn\u00fd algoritmus, kter\u00fd by podle zdrojov\u00e9ho k\u00f3du programu ur\u010dil, zda se program zasekne nebo skon\u010d\u00ed v kone\u010dn\u00e9m \u010dase. Roz\u0161\u00ed\u0159en\u00edm t\u00e9to v\u011bty je <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Rice%27s_theorem\">Riceova v\u011bta<\/a><\/noindex>, tvrd\u00edc\u00ed, \u017ee pro libovolnou netrivi\u00e1ln\u00ed vlastnost v\u00fdpo\u010detn\u00edch funkc\u00ed je ur\u010den\u00ed, zda libovoln\u00fd program po\u010d\u00edt\u00e1 funkci s takovou vlastnost\u00ed, algoritmicky ne\u0159e\u0161iteln\u00fdm \u00fakolem. Nap\u0159\u00edklad nen\u00ed mo\u017en\u00e9 napsat analyz\u00e1tor, kter\u00fd by na z\u00e1klad\u011b jak\u00e9hokoliv zdrojov\u00e9ho k\u00f3du ur\u010dil, zda analyzovan\u00fd program implementuje algoritmus, kter\u00fd po\u010d\u00edt\u00e1 nap\u0159\u00edklad umocn\u011bn\u00ed cel\u00e9ho \u010d\u00edsla na druhou.<\/p>\n<p>T\u00edmto zp\u016fsobem m\u00e1 funk\u010dnost statick\u00fdch analyz\u00e1tor\u016f neodstraniteln\u00e9 omezen\u00ed. Statick\u00fd analyz\u00e1tor nikdy nebude schopen ve v\u0161ech p\u0159\u00edpadech ur\u010dit takov\u00e9 v\u011bci, jako nap\u0159\u00edklad vznik \"null pointer exception\" v jazyc\u00edch, kter\u00e9 umo\u017e\u0148uj\u00ed hodnotu null, nebo ve v\u0161ech p\u0159\u00edpadech ur\u010dit vznik \"attribute not found\" v jazyc\u00edch s dynamick\u00fdm typov\u00e1n\u00edm. V\u0161echno, co m\u016f\u017ee i ten nejdokonal\u011bj\u0161\u00ed statick\u00fd analyz\u00e1tor, je vy\u010dlenit zvl\u00e1\u0161tn\u00ed p\u0159\u00edpady, jejich\u017e po\u010det mezi v\u0161emi mo\u017en\u00fdmi probl\u00e9my s va\u0161\u00edm zdrojov\u00fdm k\u00f3dem je, bez exaggeraci, kapka v mo\u0159i.<\/p>\n<h2>Statick\u00e1 anal\u00fdza nen\u00ed hled\u00e1n\u00edm chyb.<\/h2>\n<p>\nZ v\u00fd\u0161e uveden\u00e9ho vypl\u00fdv\u00e1 z\u00e1v\u011br: statick\u00e1 anal\u00fdza nen\u00ed n\u00e1strojem na sni\u017eov\u00e1n\u00ed po\u010dtu defekt\u016f v programu. Dovol\u00edm si tvrdit, \u017ee kdy\u017e je poprv\u00e9 aplikov\u00e1na na v\u00e1\u0161 projekt, najde v k\u00f3du \"zaj\u00edmav\u00e1\" m\u00edsta, ale pravd\u011bpodobn\u011b nenajde \u017e\u00e1dn\u00e9 defekty, kter\u00e9 by ovlivnily kvalitu \u010dinnosti va\u0161eho programu.<\/p>\n<p>P\u0159\u00edklady defekt\u016f, kter\u00e9 byly automaticky nalezeny analyz\u00e1tory, jsou ohromuj\u00edc\u00ed, ale nesm\u00edme zapom\u00ednat, \u017ee tyto p\u0159\u00edklady byly nalezeny pomoc\u00ed skenov\u00e1n\u00ed velk\u00e9ho souboru velk\u00fdch k\u00f3dov\u00fdch z\u00e1kladen. Na stejn\u00e9m principu hacke\u0159i, kte\u0159\u00ed maj\u00ed mo\u017enost proch\u00e1zet n\u011bkolik jednoduch\u00fdch hesel na velk\u00e9m po\u010dtu \u00fa\u010dt\u016f, nakonec najdou ty \u00fa\u010dty, na kter\u00fdch je jednoduch\u00e9 heslo.<\/p>\n<p>Znamen\u00e1 to, \u017ee statickou anal\u00fdzu nen\u00ed t\u0159eba pou\u017e\u00edvat? Samoz\u0159ejm\u011b, \u017ee ne! A to z p\u0159esn\u011b stejn\u00e9ho d\u016fvodu, pro\u010d stoj\u00ed za to zkontrolovat ka\u017ed\u00e9 nov\u00e9 heslo, zda se ocit\u00e1 na seznamu \"jednoduch\u00fdch\" hesel.<\/p>\n<h2>Statick\u00e1 anal\u00fdza je v\u00edce ne\u017e hled\u00e1n\u00ed chyb.<\/h2>\n<p>\nVe skute\u010dnosti jsou prakticky \u0159e\u0161iteln\u00e9 \u00fakoly anal\u00fdzou mnohem \u0161ir\u0161\u00ed. V\u017edy\u0165 obecn\u011b statick\u00e1 anal\u00fdza je jak\u00e1koli kontrola zdrojov\u00fdch k\u00f3d\u016f, kter\u00e1 se prov\u00e1d\u00ed p\u0159ed jejich spu\u0161t\u011bn\u00edm. Zde je n\u011bkolik v\u011bc\u00ed, kter\u00e9 lze d\u011blat:<\/p>\n<ul>\n<li> Kontrola stylu k\u00f3dov\u00e1n\u00ed v \u0161irok\u00e9m smyslu slova. Toto zahrnuje jak kontrolu form\u00e1tov\u00e1n\u00ed, tak i vyhled\u00e1v\u00e1n\u00ed pr\u00e1zdn\u00fdch\/nepot\u0159ebn\u00fdch z\u00e1vorek, stanoven\u00ed prahov\u00fdch hodnot metrik, jako je po\u010det \u0159\u00e1dk\u016f\/cyklomatick\u00e1 slo\u017eitost metody atd. \u2014 celkov\u011b v\u0161e, co potenci\u00e1ln\u011b zt\u011b\u017euje \u010ditelnost a udr\u017eovatelnost k\u00f3du. V Jav\u011b je t\u00edmto n\u00e1strojem Checkstyle, v Pythonu \u2014 flake8. Programy tohoto typu se obvykle naz\u00fdvaj\u00ed \u201elintery\u201c.<\/li>\n<li>Anal\u00fdze nemus\u00ed podl\u00e9hat pouze spou\u0161t\u011bc\u00ed k\u00f3d. Soubory s prost\u0159edky, jako jsou JSON, YAML, XML, .properties, mohou (a m\u011bly by!) b\u00fdt automaticky kontrolov\u00e1ny na platnost. Nakonec je lep\u0161\u00ed zjistit, \u017ee struktura JSON byla naru\u0161ena kv\u016fli n\u011bjak\u00fdm nep\u00e1rov\u00fdm uvozovk\u00e1m v ran\u00e9 f\u00e1zi automatick\u00e9 kontroly Pull Requestu, ne\u017e p\u0159i spu\u0161t\u011bn\u00ed test\u016f nebo v dob\u011b b\u011bhu? Odpov\u00eddaj\u00edc\u00ed n\u00e1stroje jsou k dispozici: nap\u0159\u00edklad, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/adrienverge\/yamllint\">YAMLlint<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zaach\/jsonlint\">JSONLint<\/a><\/noindex>.<\/li>\n<li> Kompilace (nebo anal\u00fdza pro dynamick\u00e9 programovac\u00ed jazyky) je tak\u00e9 druhem statick\u00e9 anal\u00fdzy. Obecn\u011b plat\u00ed, \u017ee kompil\u00e1tory jsou schopny vyd\u00e1vat varov\u00e1n\u00ed signalizuj\u00edc\u00ed probl\u00e9my s kvalitou zdrojov\u00e9ho k\u00f3du, a ty by nem\u011bly b\u00fdt ignorov\u00e1ny.<\/li>\n<li>N\u011bkdy kompilace nen\u00ed pouze kompilac\u00ed spou\u0161t\u011bc\u00edho k\u00f3du. Nap\u0159\u00edklad, pokud m\u00e1te dokumentaci ve form\u00e1tu <noindex><a rel=\"nofollow\" href=\"https:\/\/asciidoctor.org\/\">AsciiDoctor<\/a><\/noindex>, pak v okam\u017eiku, kdy je p\u0159evedena na HTML\/PDF, m\u016f\u017ee zpracovatel AsciiDoctor (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/asciidoctor\/asciidoctor-maven-plugin\">Maven plugin<\/a><\/noindex>) vyd\u00e1vat varov\u00e1n\u00ed, nap\u0159\u00edklad o poru\u0161en\u00fdch intern\u00edch odkazech. A to je v\u00e1\u017en\u00fd d\u016fvod, pro\u010d nep\u0159ijmout Pull Request s \u00fapravami dokumentace.<\/li>\n<li>Kontrola pravopisu je tak\u00e9 druhem statick\u00e9 anal\u00fdzy. N\u00e1stroj <noindex><a rel=\"nofollow\" href=\"http:\/\/aspell.net\/\">aspell<\/a><\/noindex> je schopen kontrolovat pravopis nejen v dokumentaci, ale tak\u00e9 v zdrojov\u00fdch k\u00f3dech program\u016f (v koment\u00e1\u0159\u00edch a liter\u00e1lech) v r\u016fzn\u00fdch programovac\u00edch jazyc\u00edch, v\u010detn\u011b C\/C++, Javy a Pythonu. Chyba pravopisu v u\u017eivatelsk\u00e9m rozhran\u00ed nebo dokumentaci je tak\u00e9 defekt!<\/li>\n<li>Konfigura\u010dn\u00ed testy (o tom, co to je \u2014 viz <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=KaeEjsAjV6A&amp;index=30&amp;list=PLsVTVVvrKX9tuYyCtL8mASB6IOaa-kRCA&amp;t=0s\">tento<\/a><\/noindex> a <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=Tk_nmV-mWOA\">tento<\/a><\/noindex> reporty), i kdy\u017e se prov\u00e1d\u011bj\u00ed v prost\u0159ed\u00ed spou\u0161t\u011bn\u00ed modulov\u00fdch test\u016f typu pytest, jsou ve skute\u010dnosti tak\u00e9 druhem statick\u00e9 anal\u00fdzy, jeliko\u017e nepou\u0161t\u011bj\u00ed zdrojov\u00e9 k\u00f3dy b\u011bhem sv\u00e9ho prov\u00e1d\u011bn\u00ed.<\/li>\n<\/ul>\n<p>\nJak vid\u00edme, hled\u00e1n\u00ed chyb v tomto seznamu hraje nejm\u00e9n\u011b d\u016fle\u017eitou roli, zat\u00edmco v\u0161e ostatn\u00ed je dostupn\u00e9 pomoc\u00ed bezplatn\u00fdch open source n\u00e1stroj\u016f.<\/p>\n<p>Kter\u00e9 z t\u011bchto typ\u016f statick\u00e9 anal\u00fdzy byste m\u011bli pou\u017e\u00edvat ve va\u0161em projektu? Samoz\u0159ejm\u011b, \u010d\u00edm v\u00edce, t\u00edm l\u00e9pe! Hlavn\u00ed je spr\u00e1vn\u011b je implementovat, o \u010dem\u017e se budeme bavit d\u00e1le.<\/p>\n<h2>Dodavatelsk\u00fd kan\u00e1l jako v\u00edcestup\u0148ov\u00fd filtr a statick\u00e1 anal\u00fdza jako jeho prvn\u00ed kask\u00e1da<\/h2>\n<p>\nKlasickou metaforou kontinu\u00e1ln\u00ed integrace je potrub\u00ed (pipeline), kter\u00fdm proch\u00e1zej\u00ed zm\u011bny \u2013 od zm\u011bny zdrojov\u00e9ho k\u00f3du a\u017e po dod\u00e1n\u00ed do produkce. Standardn\u00ed po\u0159ad\u00ed f\u00e1z\u00ed tohoto kan\u00e1lu vypad\u00e1 takto:<\/p>\n<ol>\n<li>statick\u00e1 anal\u00fdza<\/li>\n<li>kompilace<\/li>\n<li>modulov\u00e9 testy<\/li>\n<li>integra\u010dn\u00ed testy<\/li>\n<li>UI testy<\/li>\n<li>ru\u010dn\u00ed kontrola<\/li>\n<\/ol>\n<p>\nZm\u011bny, kter\u00e9 byly zam\u00edtnuty v N-t\u00e9 f\u00e1zi kan\u00e1lu, se nep\u0159enesou na f\u00e1zi N+1.<\/p>\n<p>Pro\u010d pr\u00e1v\u011b tak a ne jinak? V t\u00e9 \u010d\u00e1sti kan\u00e1lu, kter\u00e1 se t\u00fdk\u00e1 testov\u00e1n\u00ed, se teste\u0159i dozv\u011bd\u00ed o \u0161iroce zn\u00e1m\u00e9 pyramide testov\u00e1n\u00ed.<\/p>\n<p><img decoding=\"async\" alt=\"Zav\u00e1d\u011bjte statickou anal\u00fdzu do procesu, m\u00edsto abyste ji pou\u017e\u00edvali k hled\u00e1n\u00ed chyb\" src=\"\/wp-content\/uploads\/2019\/05\/f155307fd4c1663800843c394098ea6f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Testovac\u00ed pyramida. Zdroj: <noindex><a rel=\"nofollow\" href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\">neaktu\u00e1ln\u00ed statistika<\/a><\/noindex> Martin Fowler.<\/i><\/p>\n<p>V doln\u00ed \u010d\u00e1sti t\u00e9to pyramidy se nach\u00e1zej\u00ed testy, kter\u00e9 se snadn\u011bji p\u00ed\u0161\u00ed, kter\u00e9 se rychleji vykon\u00e1vaj\u00ed a nemaj\u00ed tendenci k fale\u0161n\u00e9mu spou\u0161t\u011bn\u00ed. Proto by jich m\u011blo b\u00fdt v\u00edce, m\u011bly by pokr\u00fdvat v\u00edce k\u00f3du a b\u00fdt prov\u00e1d\u011bny jako prvn\u00ed. V horn\u00ed \u010d\u00e1sti pyramidy je situace opa\u010dn\u00e1, a proto by m\u011bl b\u00fdt po\u010det integra\u010dn\u00edch a UI test\u016f sn\u00ed\u017een na nezbytn\u00e9 minimum. \u010clov\u011bk v tomto \u0159et\u011bzci je nejdra\u017e\u0161\u00ed, nejpomalej\u0161\u00ed a nejm\u00e9n\u011b spolehliv\u00fd zdroj, a proto se nach\u00e1z\u00ed na sam\u00e9m konci a vykon\u00e1v\u00e1 pr\u00e1ci pouze v p\u0159\u00edpad\u011b, \u017ee p\u0159edchoz\u00ed f\u00e1ze neodhalily \u017e\u00e1dn\u00e9 defekty. Nicm\u00e9n\u011b podle stejn\u00fdch princip\u016f se buduje kan\u00e1l i v \u010d\u00e1stech, kter\u00e9 nejsou p\u0159\u00edmo spojen\u00e9 s testov\u00e1n\u00edm!<\/p>\n<p>Cht\u011bl bych navrhnout analogii ve form\u011b v\u00edcestup\u0148ov\u00e9ho syst\u00e9mu filtrace vody. Na vstupu je \u0161pinav\u00e1 voda (zm\u011bny s defekty), na v\u00fdstupu bychom m\u011bli z\u00edskat \u010distou vodu, v\u0161echny ne\u017e\u00e1douc\u00ed ne\u010distoty by m\u011bly b\u00fdt odstran\u011bny.<\/p>\n<p><img decoding=\"async\" alt=\"Zav\u00e1d\u011bjte statickou anal\u00fdzu do procesu, m\u00edsto abyste ji pou\u017e\u00edvali k hled\u00e1n\u00ed chyb\" src=\"\/wp-content\/uploads\/2019\/05\/76b5be8f13d55c16970d67e09767a045.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>V\u00edcestup\u0148ov\u00fd filtr. Zdroj: <noindex><a rel=\"nofollow\" href=\"https:\/\/commons.wikimedia.org\/wiki\/File:Milli-Q_Water_filtration_station.JPG\">Wikimedia Commons<\/a><\/noindex><\/i><\/p>\n<p>Jak je zn\u00e1mo, \u010distic\u00ed filtry jsou navr\u017eeny tak, aby ka\u017ed\u00fd dal\u0161\u00ed stupe\u0148 mohl zachytit st\u00e1le jemn\u011bj\u0161\u00ed frakci zne\u010di\u0161t\u011bn\u00ed. To znamen\u00e1, \u017ee stupn\u011b hrub\u00e9ho \u010di\u0161t\u011bn\u00ed maj\u00ed v\u011bt\u0161\u00ed propustnost a ni\u017e\u0161\u00ed n\u00e1klady. V na\u0161\u00ed analogii to znamen\u00e1, \u017ee vstupn\u00ed quality gates maj\u00ed v\u011bt\u0161\u00ed v\u00fdkon, vy\u017eaduj\u00ed m\u00e9n\u011b \u00fasil\u00ed p\u0159i spu\u0161t\u011bn\u00ed a jsou samy o sob\u011b nen\u00e1ro\u010dn\u00e9 \u2014 a p\u0159esn\u011b v takov\u00e9m po\u0159ad\u00ed jsou uspo\u0159\u00e1d\u00e1ny. Role statick\u00e9 anal\u00fdzy, kter\u00e1, jak nyn\u00ed rozum\u00edme, m\u016f\u017ee zachytit pouze ty nejhrub\u0161\u00ed nedostatky \u2014 je rol\u00ed s\u00edta-\u201e\u0161pinavce\u201c na samotn\u00e9m za\u010d\u00e1tku filtra\u010dn\u00edho stupn\u011b.<\/p>\n<p>Statick\u00e1 anal\u00fdza sama o sob\u011b nezlep\u0161\u00ed kvalitu kone\u010dn\u00e9ho produktu, stejn\u011b jako \u201e\u0161pinavec\u201c neu\u010din\u00ed vodu pitnou. A p\u0159esto je jej\u00ed d\u016fle\u017eitost v celkov\u00e9 souvislosti s dal\u0161\u00edmi prvky v\u00fdrobn\u00edho procesu z\u0159ejm\u00e1. I kdy\u017e v mnohostup\u0148ov\u00e9m filtru mohou v\u00fdstupn\u00ed stupn\u011b potenci\u00e1ln\u011b zachytit to sam\u00e9, co vstupn\u00ed \u2014 je jasn\u00e9, k jak\u00fdm d\u016fsledk\u016fm povede pokus spol\u00e9hat se pouze na stupn\u011b jemn\u00e9ho \u010di\u0161t\u011bn\u00ed, bez vstupn\u00edch stup\u0148\u016f.<\/p>\n<p>C\u00edlem \u201e\u0161pinavce\u201c je uvolnit n\u00e1sledn\u00e9 stupn\u011b od zachyt\u00e1v\u00e1n\u00ed zcela hrub\u00fdch nedostatk\u016f. Nap\u0159\u00edklad alespo\u0148 osoba prov\u00e1d\u011bj\u00edc\u00ed code review by se nem\u011bla rozptylovat nespr\u00e1vn\u011b naform\u00e1tovan\u00fdm k\u00f3dem a poru\u0161en\u00edm stanoven\u00fdch pravidel k\u00f3dov\u00e1n\u00ed (jako jsou zbyte\u010dn\u00e9 z\u00e1vorky nebo p\u0159\u00edli\u0161 hluboce vno\u0159en\u00e9 v\u011btven\u00ed). Chyby jako NPE by m\u011bly b\u00fdt zachyceny modulov\u00fdmi testy, ale pokud analyz\u00e1tor ji\u017e p\u0159ed testem upozor\u0148uje, \u017ee chyba se nevyhnuteln\u011b objev\u00ed \u2014 v\u00fdrazn\u011b to urychl\u00ed jej\u00ed opravu.<\/p>\n<p>P\u0159edpokl\u00e1d\u00e1m, \u017ee nyn\u00ed je jasn\u00e9, pro\u010d statick\u00e1 anal\u00fdza nezlep\u0161uje kvalitu produktu, pokud se pou\u017e\u00edv\u00e1 p\u0159\u00edle\u017eitostn\u011b, a m\u011bla by se pou\u017e\u00edvat neust\u00e1le k zachycov\u00e1n\u00ed zm\u011bn s hrub\u00fdmi nedostatky. Ot\u00e1zka, zda pou\u017eit\u00ed statick\u00e9ho analyz\u00e1toru zlep\u0161\u00ed kvalitu va\u0161eho produktu, je p\u0159ibli\u017en\u011b ekvivalentn\u00ed ot\u00e1zce: \u201eZlep\u0161\u00ed se pitn\u00e9 vlastnosti vody poch\u00e1zej\u00edc\u00ed z \u0161pinav\u00e9ho rybn\u00edka, pokud ji p\u0159efiltrujete p\u0159es cedn\u00edk?\u201c<\/p>\n<h2>Zaveden\u00ed do legacy-projektu<\/h2>\n<p>\nD\u016fle\u017eit\u00e1 praktick\u00e1 ot\u00e1zka: jak implementovat statickou anal\u00fdzu do procesu kontinu\u00e1ln\u00ed integrace jako \u201equality gate\u201c? V p\u0159\u00edpad\u011b automatick\u00fdch test\u016f je to jasn\u00e9: existuje sada test\u016f, selh\u00e1n\u00ed jak\u00e9hokoli z nich je dostate\u010dn\u00fd d\u016fvod pova\u017eovat, \u017ee sestaven\u00ed nepro\u0161lo quality gate. Pokus o nastaven\u00ed gate na z\u00e1klad\u011b v\u00fdsledk\u016f statick\u00e9 anal\u00fdzy selh\u00e1v\u00e1: u legacy k\u00f3du je varov\u00e1n\u00ed anal\u00fdzy p\u0159\u00edli\u0161 mnoho, nechceme je \u00fapln\u011b ignorovat, ale zastavit dod\u00e1vku produktu pouze proto, \u017ee obsahuje varov\u00e1n\u00ed analyz\u00e1toru, nen\u00ed mo\u017en\u00e9.<\/p>\n<p>P\u0159i prvn\u00edm pou\u017eit\u00ed analyz\u00e1tor na jak\u00e9mkoli projektu vyd\u00e1v\u00e1 obrovsk\u00e9 mno\u017estv\u00ed varov\u00e1n\u00ed, z nich\u017e v\u011bt\u0161ina se net\u00fdk\u00e1 spr\u00e1vn\u00e9 funk\u010dnosti produktu. Opravit v\u0161echny tyto pozn\u00e1mky najednou nen\u00ed mo\u017en\u00e9, a mnoh\u00e9 \u2014 ani nen\u00ed pot\u0159eba. Koneckonc\u016f v\u00edme, \u017ee n\u00e1\u0161 produkt celkov\u011b funguje a to i p\u0159ed zaveden\u00edm statick\u00e9 anal\u00fdzy!<\/p>\n<p>V d\u016fsledku toho se mnoho lid\u00ed omezuje na epizodick\u00e9 pou\u017e\u00edv\u00e1n\u00ed statick\u00e9 anal\u00fdzy, nebo ji pou\u017e\u00edvaj\u00ed pouze v informa\u010dn\u00edm re\u017eimu, kdy p\u0159i sestaven\u00ed je jednodu\u0161e vyd\u00e1no hl\u00e1\u0161en\u00ed analyz\u00e1toru. To je ekvivalentn\u00ed absenci jak\u00e9koli anal\u00fdzy, proto\u017ee pokud m\u00e1me ji\u017e mnoho varov\u00e1n\u00ed, pak vznik dal\u0161\u00edho (jakkoli z\u00e1va\u017en\u00e9ho) p\u0159i zm\u011bn\u011b k\u00f3du z\u016fst\u00e1v\u00e1 nepov\u0161imnut.<\/p>\n<p>Jsou zn\u00e1my n\u00e1sleduj\u00edc\u00ed zp\u016fsoby zaveden\u00ed quality gates:<\/p>\n<ul>\n<li>Nastaven\u00ed limitu celkov\u00e9ho po\u010dtu varov\u00e1n\u00ed nebo po\u010dtu varov\u00e1n\u00ed d\u011blen\u00e9ho po\u010dtem \u0159\u00e1dk\u016f k\u00f3du. To funguje \u0161patn\u011b, proto\u017ee takov\u00fd gate voln\u011b propou\u0161t\u00ed zm\u011bny s nov\u00fdmi defekty, dokud jejich limit nen\u00ed p\u0159ekro\u010den.<\/li>\n<li>Zaznamen\u00e1n\u00ed v\u0161ech star\u00fdch varov\u00e1n\u00ed v k\u00f3du jako ignorovan\u00fdch k ur\u010dit\u00e9mu okam\u017eiku, a odm\u00edtnut\u00ed sestaven\u00ed p\u0159i vzniku nov\u00fdch varov\u00e1n\u00ed. Takovou funk\u010dnost poskytuje PVS-studio a n\u011bkter\u00e9 online zdroje, nap\u0159\u00edklad Codacy. Nem\u011bl jsem p\u0159\u00edle\u017eitost pracovat s PVS-studio, co se t\u00fd\u010de m\u00e9ho zku\u0161enosti s Codacy, tak jejich hlavn\u00ed probl\u00e9m spo\u010d\u00edv\u00e1 v tom, \u017ee ur\u010den\u00ed toho, co je \u201estar\u00e1\u201c, a co \u201enov\u00e1\u201c chyba \u2014 je docela slo\u017eit\u00fd a ne v\u017edy spr\u00e1vn\u011b funguj\u00edc\u00ed algoritmus, zejm\u00e9na pokud se soubory v\u00fdrazn\u011b m\u011bn\u00ed nebo p\u0159ejmenov\u00e1vaj\u00ed. Z m\u00e9 zku\u0161enosti Codacy mohl v pull requestu vynechat nov\u00e1 varov\u00e1n\u00ed, a z\u00e1rove\u0148 nepropustit pull request kv\u016fli varov\u00e1n\u00edm, kter\u00e1 se net\u00fdkala zm\u011bn v k\u00f3du dan\u00e9ho PR.<\/li>\n<li>Podle m\u00e9ho n\u00e1zoru je nejefektivn\u011bj\u0161\u00edm \u0159e\u0161en\u00edm to popsan\u00e9 v knize <noindex><a rel=\"nofollow\" href=\"https:\/\/www.amazon.com\/Continuous-Delivery-Deployment-Automation-Addison-Wesley\/dp\/0321601912\">Continuous Delivery<\/a><\/noindex> \u201emetoda hra\u010dky\u201c (\u201eratcheting\u201c). Hlavn\u00ed my\u0161lenka spo\u010d\u00edv\u00e1 v tom, \u017ee vlastnost\u00ed ka\u017ed\u00e9ho vyd\u00e1n\u00ed je po\u010det varov\u00e1n\u00ed statick\u00e9 anal\u00fdzy, a povolena jsou jen takov\u00e1 zm\u011bny, kter\u00e9 celkov\u00fd po\u010det varov\u00e1n\u00ed nezvy\u0161uj\u00ed.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Hra\u010dky<\/h2>\n<p>\nFunguje to takto:<\/p>\n<ol>\n<li>V po\u010d\u00e1te\u010dn\u00ed f\u00e1zi se realizuje z\u00e1pis do metadat o vyd\u00e1n\u00ed po\u010dtu varov\u00e1n\u00ed v k\u00f3du, kter\u00fdch na\u0161li analyz\u00e1tory. Tak\u017ee p\u0159i sestaven\u00ed hlavn\u00edho v\u011btve ve va\u0161em spr\u00e1vci repository se nezapisuje jen \u201evyd\u00e1n\u00ed 7.0.2\u201c, ale \u201evyd\u00e1n\u00ed 7.0.2, obsahuj\u00edc\u00ed 100500 varov\u00e1n\u00ed Checkstyle\u201c. Pokud pou\u017e\u00edv\u00e1te pokro\u010dil\u00fd spr\u00e1vce repository (nap\u0159. Artifactory), ulo\u017een\u00ed takov\u00fdch metadat o va\u0161em vyd\u00e1n\u00ed je snadn\u00e9.<\/li>\n<li>Nyn\u00ed ka\u017ed\u00fd pull request p\u0159i sestaven\u00ed porovn\u00e1v\u00e1 po\u010det vznikl\u00fdch varov\u00e1n\u00ed s t\u00edm, jak\u00e9 mno\u017estv\u00ed m\u00e1 aktu\u00e1ln\u00ed vyd\u00e1n\u00ed. Pokud PR zv\u00fd\u0161\u00ed toto \u010d\u00edslo, k\u00f3d neprojde quality gate na statickou anal\u00fdzu. Pokud se po\u010det varov\u00e1n\u00ed sni\u017euje nebo nem\u011bn\u00ed \u2014 tak projde.<\/li>\n<li>P\u0159i p\u0159\u00ed\u0161t\u00edm vyd\u00e1n\u00ed bude znovu p\u0159epo\u010d\u00edtan\u00fd po\u010det varov\u00e1n\u00ed zaps\u00e1n do metadat vyd\u00e1n\u00ed.<\/li>\n<\/ol>\n<p>\nTak pomalu, ale jist\u011b (jako p\u0159i pr\u00e1ci s klikou) se po\u010det varov\u00e1n\u00ed sna\u017e\u00ed bl\u00ed\u017eit nule. Samoz\u0159ejm\u011b, syst\u00e9m lze oklamat t\u00edm, \u017ee se p\u0159id\u00e1 nov\u00e9 varov\u00e1n\u00ed t\u00edm, \u017ee se oprav\u00ed ciz\u00ed. To je v po\u0159\u00e1dku, proto\u017ee v dlouh\u00e9m obdob\u00ed to p\u0159in\u00e1\u0161\u00ed v\u00fdsledky: varov\u00e1n\u00ed se obvykle opravuj\u00ed ne jednotliv\u011b, ale skupinov\u011b podle ur\u010dit\u00fdch typ\u016f, a v\u0161echna snadno odstran\u011bn\u00e1 varov\u00e1n\u00ed jsou docela rychle odstran\u011bna.<\/p>\n<p>Na tomto grafu je zn\u00e1zorn\u011bn celkov\u00fd po\u010det varov\u00e1n\u00ed Checkstyle za posledn\u00edch \u0161est m\u011bs\u00edc\u016f pr\u00e1ce tohoto \u201emechanismu\u201c na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\">jednom z na\u0161ich OpenSource projekt\u016f.<\/a><\/noindex>Po\u010det varov\u00e1n\u00ed se sn\u00ed\u017eil o \u0159\u00e1d, a to p\u0159irozen\u00fdm zp\u016fsobem, z\u00e1rove\u0148 s v\u00fdvojem produktu!<\/p>\n<p><img decoding=\"async\" alt=\"Zav\u00e1d\u011bjte statickou anal\u00fdzu do procesu, m\u00edsto abyste ji pou\u017e\u00edvali k hled\u00e1n\u00ed chyb\" src=\"\/wp-content\/uploads\/2019\/05\/9529bb2fb32187057088e8d2c4203333.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPou\u017e\u00edv\u00e1m modifikovanou verzi t\u00e9to metody, kter\u00e1 odd\u011blen\u011b po\u010d\u00edt\u00e1 varov\u00e1n\u00ed rozd\u011blen\u00e1 podle modul\u016f projektu a n\u00e1stroj\u016f anal\u00fdzy. Vytvo\u0159en\u00fd YAML soubor s metadaty o sestaven\u00ed vypad\u00e1 p\u0159ibli\u017en\u011b takto:<\/p>\n<pre><code class=\"plaintext\">celesta-sql:\n  checkstyle: 434\n  spotbugs: 45\ncelesta-core:\n  checkstyle: 206\n  spotbugs: 13\ncelesta-maven-plugin:\n  checkstyle: 19\n  spotbugs: 0\ncelesta-unit:\n  checkstyle: 0\n  spotbugs: 0\n<\/code><\/pre>\n<p>\nV jak\u00e9mkoliv pokro\u010dil\u00e9m CI syst\u00e9mu lze \u201emechanismus\u201c implementovat pro jak\u00e9koliv n\u00e1stroje pro statickou anal\u00fdzu, ani\u017e byste se spol\u00e9hali na pluginy a extern\u00ed n\u00e1stroje. Ka\u017ed\u00fd z analyz\u00e1tor\u016f generuje svou zpr\u00e1vu v jednoduch\u00e9m textov\u00e9m nebo XML form\u00e1tu, kter\u00fd se snadno zpracov\u00e1v\u00e1. Je jen pot\u0159eba napsat pot\u0159ebnou logiku do CI skriptu. M\u016f\u017eete se pod\u00edvat, jak je to implementov\u00e1no v na\u0161ich open source projektech vyu\u017e\u00edvaj\u00edc\u00edch Jenkins a Artifactory. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/2bass\/blob\/dev\/Jenkinsfile\">zde<\/a><\/noindex> nebo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/dev\/Jenkinsfile\">zde<\/a><\/noindex>. Oba p\u0159\u00edklady z\u00e1vis\u00ed na knihovn\u011b <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/inponomarev\/ratchetlib\">ratchetlib<\/a><\/noindex>: metoda <code>countWarnings()<\/code> b\u011b\u017en\u011b po\u010d\u00edt\u00e1 xml tagy v souborech generovan\u00fdch Checkstyle a Spotbugs, a <code>compareWarningMaps()<\/code> realizuje ten prav\u00fd mechanismus, vyhazuj\u00edc\u00ed chybu v p\u0159\u00edpad\u011b, \u017ee se po\u010det varov\u00e1n\u00ed v n\u011bkter\u00e9 z kategori\u00ed zv\u00fd\u0161\u00ed.<\/p>\n<p>Zaj\u00edmav\u00e1 varianta implementace \u201ez\u00e1mku\u201c m\u016f\u017ee b\u00fdt pou\u017eita pro anal\u00fdzu pravopisu koment\u00e1\u0159\u016f, textov\u00fdch liter\u00e1l\u016f a dokumentace pomoc\u00ed aspell. Jak je zn\u00e1mo, p\u0159i kontrolov\u00e1n\u00ed pravopisu nejsou v\u0161echna slova nezn\u00e1m\u00e1 standardn\u00edmu slovn\u00edku nutn\u011b nespr\u00e1vn\u00e1; mohou b\u00fdt p\u0159id\u00e1na do u\u017eivatelsk\u00e9ho slovn\u00edku. Pokud ud\u011bl\u00e1te u\u017eivatelsk\u00fd slovn\u00edk sou\u010d\u00e1st\u00ed zdrojov\u00e9ho k\u00f3du projektu, m\u016f\u017ee b\u00fdt kvalita br\u00e1ny pro pravopis formulov\u00e1na n\u00e1sledovn\u011b: proveden\u00ed aspell se standardn\u00edm a u\u017eivatelsk\u00fdm slovn\u00edkem. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/271dcfc8dc3ad65ac2d1dcaa39b7fd3ea8fb5891\/Jenkinsfile#L36\">by se nem\u011blo<\/a><\/noindex> nalezeny \u017e\u00e1dn\u00e9 pravopisn\u00e9 chyby.<\/p>\n<h2>O d\u016fle\u017eitosti fixace verze analyz\u00e1toru<\/h2>\n<p>\nNa z\u00e1v\u011br je t\u0159eba poznamenat n\u00e1sleduj\u00edc\u00ed: a\u0165 u\u017e implementujete anal\u00fdzu jak\u00fdmkoli zp\u016fsobem do va\u0161eho dod\u00e1vkov\u00e9ho kontejneru, verze analyz\u00e1toru by m\u011bla b\u00fdt pevn\u011b stanovena. Pokud dojde k samovoln\u00e9 aktualizaci analyz\u00e1toru, p\u0159i sestavov\u00e1n\u00ed dal\u0161\u00edho pull requestu se mohou \u201eobjevit\u201c nov\u00e9 chyby, kter\u00e9 nesouvis\u00ed se zm\u011bnou k\u00f3du, ale s t\u00edm, \u017ee nov\u00fd analyz\u00e1tor je schopen odhalit v\u00edce chyb \u2014 a to v\u00e1m zkomplikuje proces p\u0159ij\u00edm\u00e1n\u00ed pull request\u016f. Upgrade analyz\u00e1toru by m\u011bl b\u00fdt v\u011bdom\u00fdm krokem. Nicm\u00e9n\u011b, pevn\u00e1 fixace verze ka\u017ed\u00e9 komponenty sestaven\u00ed je obecn\u011b nezbytn\u00fdm po\u017eadavkem a t\u00e9matem pro zvl\u00e1\u0161tn\u00ed diskusi.<\/p>\n<h2>Z\u00e1v\u011bry<\/h2>\n<p><\/p>\n<ul>\n<li>Statick\u00e1 anal\u00fdza v\u00e1m nenajde chyby a nezlep\u0161\u00ed kvalitu va\u0161eho produktu v\u00fdsledkem jednor\u00e1zov\u00e9ho pou\u017eit\u00ed. Pozitivn\u00ed vliv na kvalitu p\u0159in\u00e1\u0161\u00ed pouze jej\u00ed trval\u00e9 pou\u017e\u00edv\u00e1n\u00ed v procesu dod\u00e1vky.<\/li>\n<li>Hled\u00e1n\u00ed chyb v\u016fbec nen\u00ed hlavn\u00edm \u00fakolem anal\u00fdzy; drtiv\u00e1 v\u011bt\u0161ina u\u017eite\u010dn\u00fdch funkc\u00ed je k dispozici v opensource n\u00e1stroj\u00edch.<\/li>\n<li>Implementujte kvalitativn\u00ed br\u00e1ny na z\u00e1klad\u011b v\u00fdsledk\u016f statick\u00e9 anal\u00fdzy na samotn\u00e9m po\u010d\u00e1tku dod\u00e1vkov\u00e9ho kontejneru, p\u0159i\u010dem\u017e pou\u017eijte \u201ez\u00e1mek\u201c pro legacy k\u00f3d.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Odkazy<\/h2>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.amazon.com\/Continuous-Delivery-Deployment-Automation-Addison-Wesley\/dp\/0321601912\">Continuous Delivery<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=8Cx3LHNjI24\">A. Kudrjavcev: Anal\u00fdza program\u016f: jak pochopit, \u017ee jste dobr\u00fd program\u00e1tor<\/a><\/noindex> prezentace o r\u016fzn\u00fdch metod\u00e1ch anal\u00fdzy k\u00f3du (nejen statick\u00e9!)<\/li>\n<\/ol>\n<p>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/436868\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u0431\u043b\u043e\u0433 PVS-studio, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0431\u0437\u043e\u0440\u043e\u0432 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041d\u0435\u0434\u0430\u0432\u043d\u043e PVS-studio \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 Java, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 IntelliJ IDEA, \u0447\u0435\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24622,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32848","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0412\u043d\u0435\u0434\u0440\u044f\u0439\u0442\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0430 \u043d\u0435 \u0438\u0449\u0438\u0442\u0435 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0430\u0433\u0438 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:49:16+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:49:16+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Implementujte statickou anal\u00fdzu do procesu, m\u00edsto abyste s jej\u00ed pomoc\u00ed hledali chyby | ProHoster","description":"Napsat tento \u010dl\u00e1nek m\u011b p\u0159im\u011blo velk\u00e9 mno\u017estv\u00ed materi\u00e1l\u016f o statick\u00e9 anal\u00fdze, kter\u00e9 se st\u00e1le \u010dast\u011bji objevuj\u00ed.","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0412\u043d\u0435\u0434\u0440\u044f\u0439\u0442\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0430 \u043d\u0435 \u0438\u0449\u0438\u0442\u0435 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0430\u0433\u0438 | ProHoster","og:description":"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430.","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:49:16+00:00","article:modified_time":"2019-10-31T18:49:16+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32848","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 12:50:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:51:27","updated":"2026-01-21 12:50:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/32848","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=32848"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/32848\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/24622"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=32848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=32848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=32848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}