Sunday, May 23, 2021

როგორ ვიყოთ მეტად ეფექტურები დისტანციურად მუშაობის დროს

 უკვე ერთ წელზე მეტია რაც პანდემია დაიწყო და უმეტესობა ჩვენგანი, თუ ყველა არა, იძულებული გახდა გადასულიყო მუშაობის დისტანციურ რეჟიმზე. ტექნოლოგიური პრობლემები რომ გვერდზე გადავდოთ, სხვა პრობლემებმაც იჩინა თავი. ერთ-ერთი პრობლემა არის ეფექტურობა. ამ პოსტში გაგიზიარებთ ჩემს შეხედულებას და იდეებს, როგორ შეიძლება გავხდეთ უფრო ეფექტურები, როცა სახლიდან გვიწევს მუშაობა. ცხადია, რომ ეს ყველასთვის შეიძლება არ მუშაობდეს, რადგან თითოეული ჩვენგანი დამოუკიდებელი ინდივიდია. ახლა კი დავუბრუნდეთ იმ ეტაპებს, რომელსაც პირადად ვიყენებ ან მიცდია:





  1. დილით სირბილი და მსუბუქი ვარჯიში


დილით მსუბუქი, გამაჯანსაღებელი ვარჯიში არა თუ პანდემიის, არამედ ჩვეულებრივ პირობებშიც  ძალიან კარგია. ამ დროს ჩვენი ორგანიზმი იღვიძებს, ფხიზლდება და უკვე მზად არის უფრო ადვილად გაუმკლავდეს ყოველდღიურ რუტინას. თუნდაც 15 წუთი ძუნძული ან სწრაფი სიარულიც, შეიძლება ეფექტურობის გაზრდის წინაპირობა იყოს. თუ იმის საშუალება გაქვთ რომ პარკში ირბინოთ, ეს ორგანიზმის გამოღვიძებასთან ერთად სუფთა ჰაერის მიღებაცაა.




  1. სამუშაო კუთხის მოწყობა


ეცადეთ საკუთარ გემოზე მოიწყოთ სამუშაო კუთხე. ანუ გქონდეთ მუდმივი სამუშაო კუთხე და არ გიწევდეთ სხვადასხვა დღეს სხვადასხვა ადგილის დაკავება. მოაწყეთ სამუშაო კუთხე ისე, რომ შეგექმნათ ოფისის ატმოსფერო. გქონდეთ ყველა საჭირო ნივთი (საწერი კალამი, ფურცლები ჩანაწერებისთვის, რვეული და ა.შ.) იმავე მაგიდაზე, ანუ არ მოგიწიოთ აქეთ-იქით სირბილი და გამოიყენეთ ეს სივრცე მხოლოდ სამუშაო გარემოსთვის, რათა მოხდეს სამუშაო სივრცისა და პირადი სივრცის გამიჯვნა. ამით მცირედით მაინც შეიმცირებთ იმის განცდას, რომ სახლიდან მუშაობთ.




  1. ჩაიცვით ისე, როგორც ჩაიცმევდით ოფისში 


ერთი შეხედვით ეს შეიძლება სასაცილოდ მოგეჩვენოთ, მაგრამ ჩაცმულობაც გარკვეულწილად სამუშაო ატმოსფეროს ქმნის. ხოლო, როცა სამუშაო საათებს მორჩებით, აუცილებლად გამოიცვალეთ და მოირგეთ ყოველდღიური სახლის ტანსაცმელი. ისევე როგორც სამუშაო კუთხის შემთხვევაში, მოახერხეთ გამიჯნოთ სამუშაო და სახლის ტანსაცმელი. ამით თქვენ მოახერხებთ გამიჯნოთ სამუშაო და პირადი ცხოვრების სივრცეები და გარემო.


  1. ჩართეთ კამერები ონლაინ შეხვედრის დროს


უმრავლესობა ჩვენგანს ყოველდღიურად მინიმუმ ერთი შეხვედრა მაინც აქვს. კამერის ჩართვა დაგვეხმარება იმაში, რომ მეტად ორიენტირებული ვიყოთ შეხვედრაზე და მის შინაარსზე, რაგან როცა კამერა გამორთული გვაქვს, შეიძლება სულმა წაგვძლიოს და ჩვენი სმარტფონისკენ ან სხვა მოწყობილობისკენ ან სულაც სხვა საქმისკენ გაგვექცეს ხელი, რაც ყურადღებას გაგვიფანტავს და ჩვენი შეხვედრაზე დასწრება მხოლოდ ფორმალობა იქნება, რაც საქმისთვის დაბალ ეფექტს მოიტანს. 



ალბათ, ზემოთ ჩამოთვლილს რჩევებს კიდევ შეიძლება დაემატოს რამე, მაგრამ ესენი იყო ის ძირითადი პუნქტები, რაც საკუთარ თავს შევატყე და საკუთარ მაგალითზე ჩამოვაყალიბე. როგორც უკვე აღვნიშნე, ცხადია, ეს ყველას არ დაეხმაროს, მაგრამ იმედი მაქვს, ვიღაცას მაინც გამოადგება.





Monday, April 12, 2021

დისტანციური სწავლების პორტალების შედარება

 ბოლო ერთი წლის მანძილზე ონლაინ სწავლება როგორც სკოლებში, ასევე უნივერსიტეტებში და ყველა სხვა სასწავლო დაწერესებულებაში სავალდებულო გახდა. სხვადასხვა დაწესებულებამ სხვადასხვა პლათფორმა გამოიყენა. ამ პოსტში შევეცდები მოკლედ შევეხო რამდენიმე ყველაზე გავრცელებული პლატფორმის შედარებას.

ერთ-ერთი საკმაოდ კარგი პლათფორმა დისტრანციურ სწავლებაში არის Google Meet + Google Classroom. გუგლის ეს ორი პროდუქტი, ერთიანობაში ძალიან კარგ შესაძლებლობებს გვაძლევს ვმართოთ სასწავლო პროცესი და გავუზიაროთ მოსწავლეებს ან სტუდენტებს მასალები ყოველგვარი დამატებით ელექტრონული ფოსტის ან რაიმე სხვა საშუალების გარეშე. ზოგადად, ამ პლათფორმებს პანდემიის დაწყებამდეც აქტიურად გამოიყენებდნენ და ერთ-ერთი გახლავართ მე, ვინც მისი მომხმარებელი ვიყავი. Google Meet-ის გამოყენების ვიდეო ინსტრუქცია შეგიძლიათ იხილოთ მოცემულ მისამართზე https://youtu.be/VOsYzS1sT0Q , ხოლო რაც შეეხება Classroom-ის გამოყენების ვიდეო ინსტრქუციას, შეგიძლიათ იხილოთ შემდეგ მისამართზე https://youtu.be/McFVeZgL2vE

 


ერთ-ერთი ასევე პირველი პლათფორმა რომელიც დისტანციურ სწავლებაში დაინერგა, არის Zoom. უნდა აღინიშნოს ისიც, რომ Zoom-ის აქციების ფასი საგრძნობლად გაიზარდა პანდემიის დაწყების შემდეგ, რადგან ძალიან ბევრმა ადამიანმა დაიწყო მისი გამოყენება. ზოგადად, Zoom-ის ერთ-ერთი ნაკლოვანება არის ის, რომ თუ ლიცენზია არ გაქვს მაშინ 40 წუთის შემდეგ შეხვედრას ავტომატურად ხურავს და ყველა მონაწილე ახლიდან უნდა შემოვიდეს. გარდა ამისა, თუ გვსურს stream გავუშვათ მაგალითად Facebook live-ში, ამისთვისაც გვჭირდება რომ გვქონდეს ლიცენზირებული Zoom. რაც შეეხება მასალების გაგზავნას, Zoom-ში შეგვიძლია გავაგზავნოთ ფაილები, თუმცა სტუდენტმა ან მოსწავლემ ეს უნდა შეინახოს თავისით და დაახარისხოს, ხოლო თუ შევადარებთ Google Classroom-ს იქ ყველაფერი მუდმივად ხელმისაწვდომი და თემების მიხედვით დახარისხებულია, შესაბამისად კლასის მონაწილეებს მასალების მოძებნა საკმაოდ მარტივად შეუძლიათ. თუ მაინც გადაწყვეტთ, რომ Zoom გამოიყენოთ, მაშინ მისი გამოყენების ვიდეო ინსტრუქცია შეგიძლიათ იხილოთ მოცემულ ბმულზე https://youtu.be/YQL4PvlLDAo

 


საჯარო სკოლებში ძირითადად გავრცელებულია Microsoft-ის პროდუქტი Teams, რომელიც ასევე საკმაოდ კარგი საშუალებაა დისტანციური სწავლებისთვის. ამ პროგრამაში მუშაობის დიდი გამოცდილება არ მაქვს, მაგრამ Zoom-თან შედარებით მასაც ის უპირატესობა აქვს რომ ვიდეოს ჩანაწერები ავტომატურად ინახება Microsoft-ის ღრუბლოვან საცავში (cloud-ზე) და მათი მიწოდება სტუდნეტებისთვის და მოსწავლეებისთვის საკმაოდ მარტივია.

 


რომ შევაჯამოთ, სამივე პლატფორმა აქიურად გამოიყენება და შეიძება განვიხილოთ ისეც, რომ გემოვნების ამბავია ვინ რომელს აირჩევს, თუმცა ჩემი პირადი აზრია, რომ Google იმდენად კარგ და დახვეწილ პროდუქტებს გვთავაზობს, რომ ამ შანსის არ გამოყენება არ შეიძლება. ასევე უნდა აღინიშნოს ისიც, რომ Google მუდმივად ანახლებს თავის პროდუქტებს და პანდემიის დაწყების პერიოდს თუ შევადარებთ ახლანდელთან, Meet-იც და Classroom-იც ძალიან დაიხვეწა და ბევრი ფუნქციონალი დაემატა.

Thursday, August 13, 2020

7 საუკეთესო პრაქტიკა (Best practices) GIT-ზე უკეთესი კოდის ხარისხისთვის

 

არავინ კამათობს იმაზე, რომ Git თამაშობს მთავარ როლს პროგრამული უზრუნველყოფის შექმნაში. Git არის იარაღი, რომელიც რამდენიმე დეველოპერს საშუალებას აძლევს ერთსა და იმავე კოდზე, ერთსა და იმავე დროს. მაგრამ,  დეველოპერები კვლავ აწყდებიან კოდის ხარისხის პრობლემას. რატომ ? ერთ-ერთი მთავარი მიზეზი არის ის, რომ უმრავლესობა მათგანი არ მიჰყვება Git-ის საუკეთესო პრაქტიკებს. ქვემოთ ჩვენ განვიხილავთ 7 ძირითად მიდგომას, რომელიც დაგვეხმარება კოდის ხარისხის გაზრდაში. 

 

1)     Atomic Commit 

Commit Git-ზე ნიშნავს, რომ შენ შეცვალე შენი კოდი და გსურს რომ ეს ცვლილებები შეინახო, როგორც ახალი სანდრო ვერსია. ვერსიის კონტროლის სისტემა არ გვზღუდავს იმაში, თუ როგორი სახე ექნება ჩვენს Commit-ს. მაგალითად:

·       თქვენ შეგიძლიათ დაა-commit-ოთ 1000 ცვლილება როგორც ერთი commit.

·       თქვენ შეგიძლიათ დაა-commit-ოთ ყველა dll ფაილი ან თუნდაც ბიბლიოთეკები

·       თქვენ შეგიძლიათ დაა-commit-ოთ ცვლილებები, რომლებიც შეიცავს შეცდომას.

მაგრამ არის თუ არა ეს კარგი ? რა თქმა უნდა, არა.

თუ ჩვენს commit-ს ექნება ზემოთ აღნიშნული თვისებები, მაშინ ჩვენ კომპრომისზე მივდივართ კოდის ხარისხთან, ასევე code review-ს დასჭირდება უფრო მეტი დრო. ეს ყველაფერი გამოიწვევს იმას, რომ გუნდის პროდუქტიულობა დაიკლებს. ამიტომ, ჩვენ უნდა ვეცადოთ რომ ჩვენი commit იყოს ატომური. ეს გულისხმობს, რომ ჩვენ ვა-commit-ებთ მხოლოდ ერთ ცვლილებას. ერთი ცვლილება არ გულისხმობს მხოლოდ ერთ ფაილს. საუბარია ერთ ლოგიკურ ცვლილებაზე, რომელიც შეიძლება რამდენიმე ფაილში მოითხოვდეს ცვლილების განხორციელებას.

 

2)     სიცხადე იმაში თუ რა უნდა/არ უნდა დავა-commit-ოთ

ბევრი დეველოპერი აკეთებს კოდში ცვლილებებს, შემდეგ აკეთებს commit-ს და შემდეგ push-ს. ჩვენ შეიძლება შევხვდეთ ბევრ repository-ის, სადაც და-commit-ებული იქნება dll, pdf და სხვა არასასურველი ფაილები. როდესაც ვაკეთებთ commit-ს, საკუთარ თავს უნდა დავუსვათ ორი შეკითხვა:

·       საჭიროა თუ არა ყველა ფაილის დაკომიტება და საჭიროა თუ არა ისინი ვერსიის კონტროლის სისტემაში ?

·       არის თუ არა კონკრეტული ფაილები source code-ის ნაწილი ?

არასასურველი ფაილების და-commit-ება რომ თავიდან ავიცილოთ, უნდა გამოვიტენოთ .gitignore ფაილი. თუ ჩვენ ერთზე მეტ repository-თან ვმუშაობთ, მაშინ უფრო ადვილია გამოვიყენოთ გლობალური .gitignore ფაილი. ეს ფაილი გვეხმარება იმაში, რომ ჩვენი კოდი იქნება უფრო სუფთა და ვერსიის კონტროლზე არ შევხვდებით არასასრუველ ფაილებს.

 

3)     Git-ის ბრძანებების ცოდნა

Git არის მძლავრი იარაღი და ასევე ძალიან სასარგებლო, თუმცა საბოლოოოდ ის არის კომპიუტერული პროგრამა. შესაბამისად, სასურველია რომ ვიცოდეთ საბაისო ბრძანებები რომ გამოვიყენოთ ის უფრო ეფექტურად.

 

4)     გაქვთ თუ არა Git Workflow ?

თუ მუშაობ გუნდში და იყენებთ Git-ს, მაშინ არის არსებითი რომ მთელი დეველოპმენტ გუნდი იყენებს ერთსა და იმავე Workflow-ს. ქვემოთ მოყვანილია სამი ძირითადი უპირატესობა workflow-ს გამოყენებისას:

·       დეველოპმენტ პროცესი იქნება უფრო ორგანიზებული

·       კარგი Git Workflow არის საწინდარი branch-ების ყოველთვის მოწესრიგებულ მდგომარეობაში ყოფნის, ანუ ყოველთვის გვექნება clean branch-ები.

·       ეს უფრო კომფორტულს გახდის ჩვენს ცხოვრებას და გააუმჯობესებს კოდის ხარისხს.

 

5)     გატესტე და-push-ვამდე

სანამ ჩვენ ჩვენს ცვლილებებს დავა-commit-ებთ და დავ-push-ავთ, აუცილებელია რომ ისინი გავტესტოთ. თუ დავა-commit-ებთ შეცდომიან კოდს ლოკალურ repository-ზე ეს დაგბლოკავთ თქვენ, მაგრამ თუ თქვენ და-push-ავთ შეცდომიან კოდს, მაშინ თქვენ დაბლოკავთ მთლიან გუნდს.

·       ეს მიდგომარე დაგვეხმარებათ თქვენ და თქვენს გუნდს რომ დაწეროთ უფრო მეტი unit test-ები და გაუშვათ ისინი ყოველი commit-ის წინ.

·       ყველა დეველოპერმა თქვენს გუნდში უნდა გაიაზროს ის, რომ build-ის გაფუჭება (შეცდომიანი კოდის და-commit-ება) არ არის კარგი და თუ ეს მაინც მოხდა გარკვეული მიზეზების გამო, მაშინ ყველასთვის მთავარი პრიორიტეტი უნდა იყოს ამ პრობლემის აღმოფხვრა.

 

6)     დაიცავით master branch

Default branch git-ზე არის master. შესაბამისად, კოდი ამ branch-ზე უნდა იყოს სტაბილური და გამოიყენებოდეს მხოლოდ production-თვის. ჩვენ უნდა დავიცვათ master branch სხვადასხვა მიმართულებით.ქვემოთ მოცემულია  რეკომენდაციები ამის განსახორციელებლად:

·       master branch არ უნდა იქნას წაშლილი არც შემთხვევით და არც განზრახ.

·       master branch-ზე commit-ის ისტორია არ უნდა იყოს შეცვლილი და გადაწერილი

·       პირდაპირი commit master branch-ზე არ უნდა იყოს შესაძლებელი code review-ს გარეშე

 

7)     Branch მენეჯმენტი

Git გვთავაზობს მძლავს branching მოდელს. ჩვენ უნდა გვქონდეს ჩვენი კოდი master-ისგან განსხვავებულ branch-ზე შემდეგ შემთხვევებში:

·       თუ ჩვენ ვაპირებთ ახალი ფუნქციონალის იმპლემენტაციას - უნდა გავაკეთოთ ახალ branch-ზე.

·       თუ ვაპირებთ არსებული bug-ის fix-ს - უნდა გავაკეთოთ ახალ branch-ზე.

·       თუ გვინდა refactoring - უნდა გავაკეთოთ ახალ branch-ზე.

როცა უკვე მოვრჩებით ჩვენს ცვლილებებს ჩვენს branch-ზე, შემდეგ უნდა გავაკეთოთ Pull Request (Merge Request) და მხოლოდ code review-ს გავლის შემდეგ უნდა მოვახდინოთ მისი სინქრონიზება master-ზე.

Tuesday, January 22, 2019

Spring Boot + Kafka Producer API


წინა პოსტში განვიხილეთ, როგორ გავაგზავნოთ და მივიღოთ შეტყობინებები Apache Kafka-ს მეშვეობით command line-ის მეშვეობით. ახლა ცოტა წინ წავიწიოთ და ვნახოთ როგორ შეიძლება ეს ყველაფერი გავაკეთოთ Java-ში, კერძოდ კი Spring Boot აპლიკაციით. ჯერ საწყის ეტაპზე, შეგვიძლია შევქმნათ მხოლოდ Producer აპლიკაცია. ამისთვის შევიდეთ Spring-ის initializer-ზე (https://start.spring.io)  და დავამატოთ შესაბამისი dependency-ები.


Generate Project ღილაკზე დაჭერით გადმოვწეროთ და ამოვაარქივოთ გადმოწერილი zip ფაილი. შემდეგ გავხსნათ ჩვენთვის სასურველ IDE-ში (ამ შემთხვევაში IntelliJ).
საწყის ეტაპზე application.properties ფაილში ჩავწეროთ მისამართი იმ სერვერისა, რომელზეც დაინსტალირებულია Kafka.



ახლა შევქმნათ KafkaProducerConfig კლასი, რომ დავაკონფიგურიროთ Producer. საწყის ეტაპზე გავაგზავნოთ მხოლოდ String ტიპის შეტყობინებები, ხოლო შემდეგში ვნახავთ თუ როგორ გავაგზავნოთ ობიექტები.


ყურადღება მივაქციოთ იმას, რომ KEY_SERIALIZER_CLASS_CONFIG-სა და VALUE_SERIALIZER_CLASS_CONFIG ის მნიშვნელობები ორივე არის StringSerializer.class, ხოლო KafkaTemplate-ც შესაბამისად არის KafkaTemplate<String,String>. bootstrapAddress არის მნიშვნელობა, რომელსაც @Value ანოტაციით ვკითხულობთ application.properties ფაილიდან.

ახლა შევქმნათ REST endpoint. RestController, სადაც მარტივად მივიღებთ HttpRequest-ს და გავაგზავნით შეტყობინებას, რომელსაც Consumer მიიღებს (ამ ეტაპზე Consumer იქნება command line-ით).


თუ ჩვენს Spring Boot აპლიკაციას გავუშვებთ და გამოვიძახებთ შემდეგ ბრძანებას (URL-ს) http://localhost:8080/publish/message?msg=Hello  და პარალელურად Consumer დასტარტული გვექნება სერვერზე (sudo kafka-console-consumer.sh --zookeeper localhost:2181 --topic kafka_topic  --from-beginning) , რომელიც მოუსმენს kafka_topic TOPIC-ს, მაშინ Command line-ში მივიღებთ შემდეგ შეტყობინებას


ახლა ვნახოთ როგორ შეიძლება Spring Boot აპლიკაციით გავაგზავნოთ Java ობიექტი. ამისთვის საჭიროა მცირედი ცვლილებების შეტანა კონფიგურაციაში. VALUE_SERIALIZER_CLASS_CONFIG-ის მნიშვნელობა უნდა გავხადოთ JsonSerializer.class და ProducerFactory უნდა იყოს ProducerFactory<String,User> , თუ გვინდა User კლასის ტიპის ობიექტების გაგზავნა. შესაბამისად KafkaTemplate-ც უნდა იყოს KafkaTemplate<String,User> ტიპის.


რა იცვლება Producer კლასში (RestController-ში) ? ამ ეტაპისთვის, შევქმნათ User კლასის ობიექტი მეთოდშივე, რომლითაც გვინდა გაგზავნა. User კლასს აქვს მხოლოდ ორივე ველი id და username და შესაბამისად getter და setter მეთოდები.



თუ დავარესტარტებთ ჩვენს აპლიკაციას და გამოვიძახებთ შემდეგ URL-
და Consumer API ძველებურად დასტარტულია და უსმენს kafka_topic TOPIC-ს, მაშინ command line-ში უნდა მივიღოთ user ობიექტის შესაბამისი JSON String.









Monday, January 21, 2019

Apache Kafka-ს ინსტალაცია Ubuntu-ზე და Publish/Consume მაგალითი


რა არის Apache Kafka ?

Apache Kafka არის streaming პლათფორმა რომელსაც შეუძლია დაამუშავოს ტრილიონობით event-ები დღის განმავლობაში. თავდაპირველად ჩაფიქრებული იყო როგორც messaging queue. Kafka დაფუძნებულია distributed commit log-ის აბსტრაქციაზე. მას შემდეგ რაც შეიქმნა და open source გახდა LinkedIn-ის მიერ 2011 წელს, Kafka messaging queue-დან გარდაიქმნა სრულფასოვან streaming პლათფორმად.


Install Apache Kafka on Ubuntu
პირველ რიგში უნდა მოვახდინოთ package reposiotry cache-ის update შემდეგი ბრძანებით.
sudo apt-get update
Apache Kafka დამოკიდებულია Java-ზე, ამიტომ წინაპირობაა რომ სერვერზე, რომელზეც გვინდა Kafka-ს დაყენება დაინსტალირებული იყოს JDK. თუ უკვე არ გვაქვს დაინსტალირებული, ამის გაკეთება შეგვიძლია შემდეგი ბრძანებით:
sudo apt-get install openjdk-8-jdk
შემდეგი ეტაპი არის zookeeper-ის დაინსტალირება.
sudo apt-get install zookeeperd
იმის შესამოწმებლად დაინსტალირდა თუ არა zookeeper ჩვენს სერვერზე, შეგვიძლია გავუშვათ შემდეგი ბრძანება:
sudo systemctl status zookeeper


თუ რაიმე მიზეზის გამო, zookeeper არ არის started მდგომარეობაში, მაშინ შეგიძლიათ გაუშვათ შემდეგი ბრძანება:

sudo systemctl start zookeeper
და ასევე zookeeper რომ system startup-ზე მივაბათ საჭიროა გავუშვათ შემდეგი ბრძანება:
sudo systemctl enable zookeeper


ახლა უკვე დადგა დრო გადმოვწეროთ Apache Kafka. ამ კონკრეტული შემთხვევისთვის, შეგვიძლია გადმოვწეროთ 1.1.1 ვერსია.
წინა ბრძანება გადმოწერს Apache Kafka-ს კომპრესირებულ არქივს.
ახლა შეგიძლიათ შექმნათ Kafka ფოლდერი /opt ფოლდერში.
mkdir opt
mkdir opt/Kafka
ახლა კი შეგვიძლია extract გავუკეთოთ Kafka არქივს /opt/Kafka ფოლდერში
sudo tar xvzf kafka_2.12-1.1.1.tgz -C /opt/Kafka
წინა ოპერაციის წარმატებულობა შეგიძლია შეამოწმოთ შემდეგი ბრძანებით
ls /root/opt/kafka

ახლა გახსენით ~/.profile ფაილი
sudo nano ~/.profile
და ბოლოში დაამატეთ
export KAFKA_HOME=”/root/opt/Kafka/kafka_2.12-1.1.1”
export PATH=”$PATH:${KAFKA_HOME}/bin”
და შეინახეთ ფაილი.

ახლა გახსენით ~/.bashrc ფაილი
sudo nano ~/.bashrc
და ბოლოში დაამატეთ
Alias sudo=’sudo env PATH=”$PATH”’
და შეინახეთ.

შემდეგ კი დაარესტარტეთ სერვერი
sudo reboot

სისტემის ახლიდან ჩატვირთვის შემდეგ, შეამოწმეთ KAFKA_HOME
echo $KAFKA_HOME

შემდეგი ეტაპი არის ჩვენთვის „სიცოცხლის გამარტივება“, გავაკეთოთ სიმბოლური ლინკი Kafka server.properties ფაილის  შემდეგი ბრძანებით
sudo ln -s $KAFKA_HOME/config/server.properties /etc/kafka.properties

შემდეგი ეტაპი უკვე არის გატესტვა
შემდეგი ბრძანებით შეგვიძლია Kafka-ს სერვერი „დავქოქოთ“ ანუ start  გავაკეთოთ
sudo kafka-server-start.sh /etc/kafka.properties
როცა უკვე Kafka Server დაისტარტება შეგვიძლია შევქმნათ testing topic-ი. ამისთვის გავხსნათ ახალი command line tab და გავუშვათ შემდეგი ბრძანება
sudo kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic testing
შედეგი უნდა იყოს შემდეგი


ახლა გავუშვათ Producer API,რომ შევძლოთ შეტყობინების გაგზავნა
sudo kafka-console-producer.sh --broker-list localhost:9092 --topic testing
როცა Enter-ს დავაწვებით გამოვა ინტერაქტიული ფანჯარა (>) იქნება, სადაც შეგვიძლია ავკრიფოთ შეტყობინება და Enter-ზე დაჭერით გავაგზავნოთ, მაგალითად


შემდეგ უნდა გავუშვათ Consumer API, რომ გაგზავნილი შეტყობინებები მივიღოთ. შეტყობინების მიღება ხდება მომენტალურად, ხოლო თუ გაგზავნი შემთხვევაში Consumer API არ არის დასტარტული, მაშინ დასტარტვამდე გაგზანილ ყველა შეტყობინებას ერთიანად მივიღებთ.
Consumer API-ც ახალ command line tab-ში დავსტარტოთ
sudo kafka-console-consumer.sh --zookeeper localhost:2181 --topic testing --from-beginning
ახლა შევამოწმოთ ჩვენი გაგზავნილი შეტყობინება თუ მივიღეთ, გადავიდეთ Consumer-ის TAB-ში და ვნახავთ რომ შეტყობინება მოვიდა.






Saturday, September 8, 2018

Composite Pattern

Design Pattern-ები არის ერთ-ერთი ყველაზე პოპულარული თემა ბლოგებზე და ასევე ინტერვიუების დროს. ამ პოსტში განვიხილავთ Composite Pattern-ს ერთ-ერთ მაგალითზე. ერთადერთი რაც უნდა დავიმახსოვროთ არის ის, რომ Composite Pattern-ი გამოიყენება რეკურსიული მოქმედების განსახორციელებლად ხისებურ სტრუქტურაზე.


განვიხილოთ სასტუმროს მაგალითი, რომელსაც არ აქვს შუქის ცენტრალური ჩამრთველი და გამომრთველი და იმისთვის რომ ეს ოპერაცია განვახორციელოთ, საჭიროა ყოველი სართულის ყოველ ოთახში ჩავრთოთ/გამოვრთოთ შუქი. ასეთი სასტუმროს სისტემის მოდელირებისთვის შევქმნათ ინტერფეისი Component (სახელის კონვენცია რომ დავიცვათ) და აღვწეროთ ორი მეთოდი.

ამის შემდეგ გვჭირდება Building, Floor და Room კლასები შესაბამისად, რომელებიც თითოეული იმპლემენტაციას გაუკეთებს Component ინტერფეისს.

  • Building-ში შუქი ჩართულად/გამორთულად ითვლება თუ მის ყველა სართულზე არის ჩართული/გამორთული.
  • Floor-ზე შუქი ჩართულად/გამორთულად ითვლება თუ მის ყველა ოთახში არის ჩართული/გამორთული.
  • Room-ში შუქი ჩართულად/გამორთულად ითვლება თუ შიგნით არის ჩართული/გამორთული.



Building ახორციელებს მისი ყველა სართულისთვის შუქის ჩართვის/გამორთვის ოპერაციას, ხოლო Floor შესაბამისად ახორციელებს იმავე ოპერაციას თავისი ყველა ოთახისთვის.

საბოლოო ეფექტი ის არის, რომ ძირითად ოპერაციას იწყებს Building, რომელიც რეკურსიულად ხორციელდება მის ქვემოთ არსებულ ობიექტებზე (Floor და Room). "დომინოს ეფექტი" არის ერთ-ერთი თვისება Composite Pattern-თვის.

აქვე აღვნიშნოთ რომ default-ად ყველა ოთახში შუქი გამორთულია. ახლა ვნახოთ ტესტ კლასი და შევამოწმოთ რომ ჩვენი სტრუქტურა სწორად მუშაობს.


Tuesday, May 1, 2018

Java 8 HashMaps, Keys და Comparable Interface

Java 8-ში წინა ვერსიებთან შედარებით ბევრი რამ გაუმჯობესებულია. ბევრი კლასი და-update-და. მათ შორის გამონაკლისი არ ყოფილა HashMap, რომელიც ერთ-ერთი ყველაზე ფართოდ გამოყენებადია. ამ პოსტში გავამახვილებ ყურადღებას იმაზე, თუ რა ხდება როცა Hash კოლიზიას აქვს ადგილი.

უპირველეს ყოვლისა, რომელი არის ყველაზე მარტივი გზა იმისა, რომ მოვახდინოთ კოლიზია HashMap-ში ? შევქმნათ კლასი, რომელსაც ექნება თავისი hash ფუნქცია და დავწეროთ მისი ყველაზე ცუდი იმპლემენტაცია (hashCode მეთოდის). ამის ერთ-ერთი მაგალითია ის, რომ hashCode() მეთოდმა ყოველთვის დააბრუნოს რაიმე კონსტანტა. როგორ ფიქრობთ რა მოხდება ამ დროს ? ტექნიკურ ინტერვიებზე ამ კითხვაზე ხშირად პასუხობენ, რომ ყოველი ახალი ჩამატებული ელემენტი HashMap-ში შეცვლის ძველს, რაც სიმართლეს არ შეესაბამება. Hash Collision არ გულისხმობს იმას, რომ HashMap-ში მონაცემები ერთმანეთს გადაეწერება, ეს ხდება მაშინ და მხოლოდ მაშინ როცა ისეთი ორი ელემენტის ჩასმას ვცდილობთ HashMap-ში, რომელთა Key-ები ტოლია equals() მეთოდზე დაყრდნობით, ანუ equals() მეთოდი აბრუნებს true-ს. ელემენტები არა ტოლი გასაღებებით და ერთნაირი hashCode-ებით მოთავსდება ერთსა და იმავე bucket-ში რომელიღაც ტიპის მონაცემთა სტრუქტურაში (შესამჩნევია რომ ამ შემთხვევაში map-ის საერთო performance გაუარესდება, რადგან ელემენტის ჩასმაც და წაკითხვაც უფრო დიდ დროს წაიღებს).

დასაწყისისთვის მოვიყვანოთ პატარა მაგალითი, რომელიც რა თქმა უნდა, გაზვიადებულია და პრაქტიკაში ნაკლებათ მოსახდენია (თუ საერთოდ მოხდა), მაგრამ ეს მაგალითი კარგად დაგვანახებს განსხვავებას. ამ მაგალითში, კოლიზიები იმაზე მეტი იქნება, ვიდრე ეს რეალურად პრაქტიკაში მოხდება.

მაგალითში, Person ტიპის ობიექტი გვქონდეს HashMap-ის გასაღებად, ხოლო მნიშვნელობები იყოს String.
ახლა კი მოვახდინოთ კოლიზია.
ამ კოდმა საკმაოდ მძლავრ კომპიუტერზე მუშაობას მოანდომა 2.5 საათი და საბოლოოდ ელემენტის წაკითხვამ კი დაახლოებით 40 მილიწამი. ახლა, ყოველგვარი წინასწარი ახნის გარეშე მოდით მოვახდინოთ Peron კლასის მცირე ცვლილება, მოდით მან იმპლემენტაცია გაუკეთოს Comparable<Person> ინტერფეისს და Person კლასში დავამატოთ კოდის შემდეგი ფრაგმენტი 
ზემოთ აღნიშნულმა კოდმა, იმავე კომპიუტერზე, მუშაობას მოანდომა ერთ წუთზე ნაკლები და საბოლოოდ ელემენტის წაკითხვას 1 მილიწამი - ანუ ის 150-ჯერ სწრაფად მუშაობს ამ შემთხვევაში. 

მოდით ახლა ავხსნათ რა მოხდა. როგორც დასაწყისში აღვნიშნეთ, Java 8-ში წინა ვერსიებთან შედარებით ბევრი კლასი გაუმჯობესდა. Java 7-ში კოლიზირებული (ერთი და იმავე hashCode-ის მქონე ელემენტები) ინახებოდა bucket-ში რომლის სტრუქტურაც იყო LinkedList. Java 8-დან დაწყებული, თუ კოლიზირებული ელემენტების რიცხვი არის გარკვეულ რიცხვზე მეტი (ეს რიცხვი არის 8), და Map-ის capacity არის 64-ზე მეტი, მაშინ HashMap-ის იმპლემენტაცია LinkedList-ის ნაცვლად იქნება BinaryTree.

აქ გაგვიჩნდება აზრი, რომ non-comparable გასაღებების შემთხვევაში, ეს ხე იქნება არაბალანსირებული, მაშინ როცა სხვა შემთხვევაში ის იქნება მეტ-ნაკლებად ბალანსირებული. მაგრამ ეს არ შეესაბამება სიმართლეს. Tree-ის იმპლემენტაცია HashMap-ში არის Red-Black Tree, რაც იმას ნიშნავს, რომ ის ყოველთვის არის ბალანსირებული. თუ ჩვენ დავწერთ utility კლასს, რომელიც ზემთ აღნიშნული მაგალითისთვის შეამოწმებს ხის სიღრმეს, ის იქნება 19.

ახლა მთავარი კითხვა, როგორ მივიღეთ ასეთი დიდი განსხვავება Comparable ინტერფესისის იმპლემენტაციით ? როცა HashMap ცდილობს იპოვოს ხეში ახალი ელემენტისთვის ადგილი, ის ამოწმებს ახალი და ძველი ელემენტები (უკვე არსებული) არის თუ არა ადვილად სადარი (Comparable interface). ჩვენი მაგალითის პირველ შემთხვევაში ის იძახებს tieBreakOrder(Object a, Object b) მეთოდს. ეს მეთოდი პირველად ცდილობს ობიექტების შედარებას class name-ზე დაყრდნობით, და შემდეგ იყენებს System.identityHashCode-ს. მაგრამ, როცა გასაღები აიმპლემენტირებს Comparable-ს ეს პროესი გაცილებით მარტივია. გასაღები (key), თვითონვე განსაზღვრავს როგორ უნდა შეედაროს სხვა ელემენტს და ელემენტის ჩამატება და წაკითხვა უფრო სწრაფად ხდება.  tieBreakOrder(Object a, Object b)  მეთოდის გამოძახება ხდება მხოლოდ მაშინ თუ ორი ელემენტის compareTo მეთოდი დააბრუნებს 0-ს (ანუ თუ ტოლია).

რომ შევაჯამოთ, Java 8-ში, თუ HashMap-ის bucket-ში ელემენტების რიცხვა გადააჭარბა 8-ს და HashMap-ის ზომამ 64-ს, მაშინ bucket-ის იმპლემენტაცია LinkedList-ის ნაცვლად იქნება Red-Black Tree, რომელიც ყოველთვის დაბალანსებულია და თუ Map-ის გასაღები აიმპლემენტირებს Comparable-ს, მაშინ ელემენტის ჩამატება და წაკითხვა იქნება გაცილებით სწრაფი. მაგრამ უნდა აღინიშნოს ისიც, რომ თუ კოლიზიების რიცხვი არც ისე დიდია, Comparable/ non-Comparable იდეას უკვე დიდი აზრი აღარ აქვს.