Author Archives: admin

Pragmatic Programmer kitabında verilen ipuçlar 2

There Are No Final Decisions

Business requirements (iş isterleri) geldiği zaman dökümanın son hali diye düşünülür. Daha sonra ise döküman v1 den v10 a kadar uzayabilir. Yazılım geliştirmede değişikliğin geleceğini işe başlamadan önce kafamıza oturtmalıyız. Örneğin MSSQL kullanılıyorsa MYSQL’e geçiş yapmak istenebilir. Yazdığımız kodun gelişime açık değişime kapalı olması gereklidir.

Database sınıfının soyutlaştırılması örneği:

https://softwareengineering.stackexchange.com/questions/301362/how-are-abstract-database-interfaces-written-to-support-multiple-database-types/301371

Use the Power of Command Shells

GUI kullanmak yerine Shell komutlarını kullanmak performansı arttırır.  Bence bazı şeyler GUI ile daha rahat oluyor. Örneğin database için GUI olmasını tercih ediyorken GIT için komut satırını kullanmayı tercih ediyorum. Komut satırı kullanımı birazda işletim sistemiyle alakalı. Gözlemlediğim Linux ve macOS kullanıcıları komut satırı kullanımına daha yatkın.

Use a Single Editor Well

Güçlü bir editor seçin ve seçtiğiniz editor üzerinde iyi olmaya yoğunlaşın. Bütün kısayolları bilin. Günümüzde birçok editor var. En popülerleri VIM, Notepad++, Sublime Text, ATOM, VSCode, Bracket …

Always Use Source Code Control

Takımdaki tek kişi olsan dahi, 1 haftalık bir prototype olsa dahi mutlaka Source Control aracı kullanın diye öğüt verilmiş. “throw-away” olsa dahi source control ile kodunuzu yönetin.

Fix the Problem, Not the Blame

Yazılım içerisinde çıkan bug’ın kimin hatası olduğunun önemi yok. Önemli olan bug’ın çözülmesi. Kişilere yönelmek insanların enerjisini düşürür ve asıl odaklanılması gereken problem unutulur.

Don’t Panic When Debugging

Debugging sırasında panik olunmamalı. Sinirli bir takım yöneticisi, hızlı çözüm isteyen bir müşteri panik olmanıza neden olabilir. Önemli olan sakin davranıp bug üzerine kafa yormaktır. Anlatılan konu bug’da olmayabilir. Semptomlar dinlenir ve ona göre karar verilir.

Bug çözümü yapmanın en iyi yolu bug’ı reproducible edebilmektir.

Don’t Assume It—Prove It – Don’t Program by Coincidence

Varsayımlar yapılmalıdır fakat yapılan varsayımların kanıtlanması önemlidir. Yıllardır çalışan kod üzerinde bir anda bug gelmiş olabilir. Bu tür bir bug ile karşı karşıya gelindiğinde o zaman düşünülen varsayımın yanlış olduğu anlaşılabilir veya o durum düşünülmemiş olabilir. Data kaynaklı bir bug varsa parameter check yapılabilir. Kodlama yapılırken ne yaptığının farkında olunmalı.

Minimize Coupling Between Modules

“By writing “shy” code as much as possible we can achieve our objective. “ Yazılım projelerinde oluşturulan modüller, objeler birbirlerini sıkı sıkıya bağlı olmamalıdır. (tight coupling, loose coupling) Örneğin bir iş sınıfındaki alanlar private olmalıdır. İş mantığı get-set üzerinden değilde sınıf içerisinde public edilen bir metod üzerinde yapılabilir.

Örnek birbirine bağlı Java class:

public class Service {
  private CustomerService customerService;
  private OrderService orderService;
  public Service() {
     customerService = new CustomerService();
     orderService = new OrderService();
  }
  private void doSomething() {
     orderService.processOrder();
  }
}

Service Class’ı CustomerService ve OrderService ‘e bağımlı durumda. Buradaki bağımlılık kodun test edilmesini engelleyecek ve bakımının okunabilirliği tasarım açısından azaltacak. Dependency Inversion prensibine uygun değil. Yüksek Seviyeli modülleri düşük seviyeli modüllere bağımlı olmamalı. Modüller soyutlara bağımlı olmalı. (Program to interface) Soyutlamalar detay sınıflara(concrete class) bağımlı olmamalıdır. Constructor injection ile bağımlılıklar tersine çevrilebilir.

Always Design for Concurrency

Concurency(eş zamanlılık) birden fazla işlemin aynı anda gerçekleşmesi olayına denir. Birden fazla iş aynı anda yapılabilir. Örneğin iki iş aynı anda çalışmaya başlarsa iş bitme zamanları birbirlerinden farklı olabilir. Kod execution lineer ilerlemez. Her iki işin ortak paylaştığı değişkenler, objeler thread-safe yapılmalı. 

Örnek thread-safe singleton class

https://www.geeksforgeeks.org/java-singleton-design-pattern-practices-examples/

Estimate the Order of Your Algorithms (Big O notation and Time Complexity)

Bir fonksiyonun çalışma süresini tam olarak ms, s türünden hesaplayıp kesin bir şey söylemek zordur. Çalışma süresini belirleyen faktörler değişkenlik gösterebilir. Örneğin çalışan bilgisayarın ne kadar hızlı olduğu, hangi programlama dilinin kullanıldığı, fonksiyon içerisinde başka çağrımlar yapılıp yapılmadığı, giriş parametrelerinin değişkenlik göstermesi gibi bir sürü parametre vardır. Direk olarak fonksiyonun çalışma süresi ne kadar diye sormak yerine “How does the runtime of this function grow? Fonksiyonun çalışma süresi nasıl büyür?” diye sorulmalıdır. Bu sorunun cevabı ise BigO ile verilir. Zaman karmaşıklığı kabaca linear time, constant time, quadratic time olarak sınıflandırılabilir.

Örneğin sıralı bir dizide bir değer bulunmak istendiğinde lineer bir yaklaşımla problem çözülebilir. Bulmak istediğimiz değer dizinin en sonunda olursa(worst case) O(n) olur. Bütün diziyi gezmiş(traverse-iterate) etmiş oluruz. Dizi sıralı olduğu için binary search ile algoritma geliştirilirse bütün diziyi iterate etmek durumunda olmayacağımızdan O(log(n)) olur. Algoritmamız büyük değerler ve küçük giriş değerleri için daha hızlı çalışır.

Yazdığımız kodlarda quadratic fonksiyonlara(iç içe döngüler) dikkat etmeliyiz. Fonksiyonun çalışması için gerekli bir setup’da olabilir. Giriş parametrelerine göre execute edilmesine gerek olmayan kod parçacıkları handle edilebilir. Dynamic programming ile set, hash collection larından faydalanılabilinir. Fonksiyonlar, metodlar büyük giriş parametleri ve küçük giriş parametrelerine göre çalışma zamanları farklılık gösterebilir.

Big O Notation

https://www.geeksforgeeks.org/analysis-algorithms-big-o-analysis/

You Can’t Write Perfect Software.

Yazılm mükemmel olamaz. Yapılabilinecek en iyi şey kodun secure, korunur ve gelebilecek hatalara karşı önlemlerin alınmış olmasıdır.

Test Your Software, or Your Users Will. . . . . . . . .

Bug çıkabileceğini bile bile kullanılan branchlere kod geçilmemeli. Diğer türlü bug’ı son kullanıcı veya test mühendisi bulacaktır. O tarafa gelmeden bug yerinde çözülmelidir.

Find Bugs Once

Test mühendisinin bug bulabilmesine izin verilmemelidir. Code coverage ve integration testler ile akla gelen tüm testler dev tarafından yapılmalıdır. Developer olarak zamanımızı yeni kod yazımı(feature) ve yeni bug çözümlerine harcamalıyız.

Don’t Be a Slave to Formal Methods

Varolan büyük projelerde çalışırken yapmak istediğiniz şey daha önce bir başkası tarafından bir benzeri veya aynısı yapılmış olabilir. İş mantığını, mimariyi bozmadan direk copy/paste yerine daha iyi nasıl yapılır diye düşünüp ufak araştırmalar yapmak kodun kalitesini arttırır.

Gently Exceed Your Users’ Expectations . . . .

Kullanıcı beklentileri tam olarak karşılanma hatta kullanıcının daha mutlu olabilmesi için biraz daha fazlası yapılmalıdır.

Work with a User to Think Like a User . . . . . . .

Yazılımın anlaşılır olması ve sistemin anlaşılabilmesi için kullanıcı ile birlikte çalışmak iyi bir yoldur. Agile çalışılan scrum projelerinde kullanıcılarda işin içerisine dahil edilir.

Refactor Early, Refactor Often

Yeniden yaz, yeniden üzerinde düşün, yeniden planla. Refactor işlemi sık sık yapılmalı.

Test Et -> Fail aldığını gör -> Refactor et -> Yeniden test et.

Pragmatic Programmer kitabında verilen ipuçlar

https://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X
Her yazılımcının okuması gereken kitaplar arasında gösteriliyor

Care About Your Craft

İşini severek yaparak zevk almak her insanın hayatında istediği bir durum. Yazılım Geliştirmeyi severek yapıyorsanız o zaman iyi sonuçlar verebilirsiniz. Diğer türlü sabah işe git akşam gel şeklinde geçen bir iş hayatı işveren içinde kendiniz içinde iyi olmayacaktır. İşinizi sevdiğinizde motive olmanız kolaylaşır ve işinizi daha iyi yapmak istersiniz.

Think! About Your Work

Yaptığınız işin eleştirisini başkası yapmadan önce kendiniz yapın. Akışına bırakmak yerine ne yaptığınızın farkında olun ve işin modüler olarak değerlendirmesini/takibini yapın. Daha iyi çözümler olabileceğini aklınızdan çıkarmayın bu sebeple araştırmacı olun.

Provide Options, Don’t Make Lame Excuses..

Gerçek hayattan bir örnek vermek gerekirse hayatta yaşamını mutlu bir şekilde uzun süre sürdürebilmenin yolu değişikliğe açık olmanız ve bulunduğunuz ortama ayak uydurmanızdır derler. Yazılım projeleride değişir öncesinde/sonrasında hata çıkma olasılığı yüksektir. Örneğin test süreçlerinde bir hata yapıldıysa dürüst olmak gerekir ve hatayı kabullenmeliyiz. Hatayı düzeltmek için seçenekler sunulmalı ve çözümü yapılmalıdır. Faydasız bahanelerin kimseye faydası olmaz. Projedeki tüm stake holder ların bu düşünce yapısında olması gerekir. Kesin çözüm için problemin doğru kişiye adreslenmesi ve yardımcı olunması gerekir.

Bahane üretmek yerine takım arkadaşlarından destek almak veya internetten destek almak iyi bir çözüm.

 Don’t Live with Broken Windows

Kod yazımı sırasında sizinle ilgili veya ilgili olmayan bir hata(tasarım hatası, yanlış iş mantığı, zayıf kod) gördüğünüzde hemen düzeltin. Eğer düzeltmek için yeterli zamanınız yoksa durumu not edip takım liderine bildirin. Burası zaten yanlış ve kimse düzeltmemiş deyip hiç bir şey yapmamak yanlış bir durum.

Be a Catalyst for Change

Takım içerisinde uyumlu olmak ve pozitif olmak motivasyonu ve iş başarısını etkileyen bir durum. Takıma vereceğiniz iyi bir sinerji ile ilerisinin daha pozitif olmasını sağlayabilirsiniz.  Catalyst değişime sebep veren kişi olarak kullanılmış.

Remember the Big Picture

Detaylarda boğulmak yerine sonuca odaklanın. Daily sabah toplantılarının oldukça kısa olması bu sebeple önemli bir durum.

Make Quality a Requirements Issue

Şuan elde çalışan ürün yıllar sonra gelecek harika ürüne göre tercih edilir.  Ürün sahibi ile sürekli iletişimde olup erken ve sık sık ürünün genel değerlendirmesi yapılması kalitenin artmasına sebep olur. Erken yapılan geri dönüşler kaliteyi belirleyen unsurlardandır

Invest Regularly in Your Knowledge Portfolio

Öğrenme alışkanlığı edin.

  • Her yıl yeni bir programlama dili öğrenin
  • 6 ayda bir Teknik bir kitap okuyun
  • Kişisel gelişim için Teknik olmayan kitaplarda tercih edin
  • Dersler alın(Eski bilgileri tazelemek veya yeni şeyler öğrenmek için kaynak oluşturun Üniversitelerin ders sayfaları ve videoları takip edilebilir)
  • Meetuplara katılın: Isole olmak insanı bitiren davranışlardan biridir. Meetuplara katılıp yine fikirler edinin, insanlar ile konuşun
  • Farklı ortamları deneyin: Linux, Windows, MacOS ve benzeri ortamları deneyip karşılaştırma yapabilecek durumda olun
  • Şimdide kalın: Teknoloji/yazılım çok gelişen bir olgu olduğu için okuyarak dinleyerek kendinizi geliştirin

Kendinize yatırım yaparak bilginin en değerli hazine olduğunu özümseyin

Critically Analyze What You Read and Hear (Critical Thinking)

Dinlerken veya okurken direk kabul etmek yerine kendi anlayacağınız şekilde mantık kurun daha sonra anladığınızı karşı tarafa aktarın.

It’s Both What You Say and the Way You Say It (Communicate!)

Dinleyici olun. İletişiminiz iyi olsun. Fikirlerinizi insanlar ile paylaşmadığınız sürece veya efektif bir şekilde anlatmadığınız sürece herhangi fikrin bir kullanışlılığı yok.

  • Ne söyleyeceğinizi bilin
  • Konuşacağınız kişiyi tanıyın
  • Doğru zamanı bulun. Yazılımcılar meşgul olabilir
  • Konuşma stiliniz iyimser olsun
  • Konuşmaya dahil olun
  • Geri dönüş yapın

DRY—Don’t Repeat Yourself

Yazılımın kolay geliştirilmesi, tutarlı olması ve bakımının kolay yapılabilmesi için yazdığınız kodun duplike olmadığına dikkat edin.

  • Bazen aynı projede başkasının yazdığı kodu kopyalamak kolay gelir. Kopyalamak yerine refactor etmeyi deneyin.

Redis cache ve axios örneği

Redis ANSI C ile yazılmış açık kaynak kodlu bir veri yapısı tutucusudur(data structure store). Database, cache veya publish/subscribe mesajlaşmada broker olarak kullanılabilir. Pratikte cache olarak kullanımı daha yaygındır. Cache olarak kullanımda ilişkisel veritabanından farklı olarak veriyi diskte tutmak yerine ana bellekte tutar. Sorgu RAM sonucu RAM üzerinden gelir(in-memory).

Docker ile redis kurulumu – redis default port: 6379

docker run --name redisserver -p 6379:6379 -d redis

Axios ile spesifik bir ip adresinin bilgilerini getiren apiye request atacağız. İlk request atıldığında redis devreye girecek ve ilk datayı key, value şeklinde belirtilen zaman dilimi süresince memory’de saklayacak. Sonraki aynı atılan requestlerde request atılmadan önce cache içerisinde varsa veriyi cache içerisinden getirecek. Eğer yoksa resource api çağrımı yapacak. Bu yöntem ile 300ms süreyi 15ms-20ms arasına çekmek mümkün oldu.

npm install redis axios

Request/Response caching: client.setEx ile 60 saniyeliğine datayı cache ediyoruz

const REDIS_PORT = process.env.REDIS_PORT || 6379;
const client = redis.createClient(REDIS_PORT);

router.get('/ipInfo', cache, (req, res) => {

  const { ipAddress } = req.query;
  let url = `https://iplist.cc/api/${ipAddress}`;

  axios.get(url)
  .then(function (response) {

    if(response.status == 200){
      //key, second, payload data
      let dd = JSON.stringify(response.data);
      client.setex(ipAddress, 60, dd);
      return res.json(response.data);
    }
    res.send('Fail');

  })
  .catch(function (error) {
    return res.json({
      err: error
    });
  })

});

Cache middleware

function cache(req, res, next) {
  const { ipAddress } = req.query;

  client.get(ipAddress, (err, data) => {
    if (err) throw err;

    if (data !== null) {
      console.log('redis cache');
      res.json(JSON.parse(data));
    } else {
      next();
    }

  });
}

Request/Response ölçümü

curl-format.txt

DNS lookup, TCP bağlantısı, varsa redirect, veri iletimi gibi işlerin ölçümü için format dosyası

time_namelookup: %{time_namelookup}
time_connect: %{time_connect}
time_appconnect: %{time_appconnect}
time_pretransfer: %{time_pretransfer}
time_redirect: %{time_redirect}
time_starttransfer: %{time_starttransfer}
———
time_total: %{time_total}

CURL Komutu

curl -w "@curl-format.txt" -o /dev/null -s http://localhost:3000/user/ipInfo?i pAddress=52.178.167.109

Cache öncesi

time_namelookup: 0.015000
time_connect: 0.015000
time_appconnect: 0.000000
time_pretransfer: 0.015000
time_redirect: 0.000000
time_starttransfer: 0.250000
———
time_total: 0.250000

Cache sonrası

time_namelookup: 0.000001
time_connect: 0.000001
time_appconnect: 0.000000
time_pretransfer: 0.000001
time_redirect: 0.000000
time_starttransfer: 0.015000
———
time_total: 0.015000

250ms den cache ile response süresi 15 ms oldu.

Redis bu örnekte remote bir API ye bağlandı fakat uzun süren ilişkisel db sorgularıda bu şekilde cache edilebilir

https://github.com/eroltutumlu/node-auth/blob/master/routes/user.js

Node.js ile JWT authentication örneği

Kullanılan bağımlılıklar

  • Express: HTTP metodlarını hızlı bir geliştirmemizi sağlayan Node.js framework
  • MongoDB Atlas: https://cloud.mongodb.com/ MongoDB i locale kurmak yerine cloud üzerinden kurulumunun yapılması için
  • Mongoose: MongoDB için Node.js nesne modelleme aracı (Hibernate gibi)
  • Bcrypt: Parola hash için kullanılan node.js kütüphanesi. (https://github.com/kelektiv/node.bcrypt.js) Örnekte parolayı hashlerken random text(SALT) + password şeklinde hash ediliyor.
  • Jsonwebtoken: JWT üretmemizi sağlayacak Node.js kütüphanesi
  • Body-parser: HTTP Request içerisindeki body kısmını alabilmemiz için gerekli modül

MongoDB için cloud.mongodb.com üzerinden bir cluster oluşturulur. IP Whitelist ile sadece kendiniz erişebileceğiniz şekilde ayarlayabilirsiniz yada 0.0.0.0 yaparak herkesin erişmesini sağlayabilirsiniz

Cluster->Connect->Connect your application ile ConnectionString alınır. Network access ile IP Whitelist oluşturulur.
let dbUrl = 'mongodb+srv://SUNUCU_ADI:'+ encodeURIComponent('PAROLA_BURADA') + '@cluster0-vtlge.mongodb.net/test?retryWrites=true&w=majority';
module.exports = {
    mongoURI: dbUrl
};

MongoDB dağıtık ve verileri Document-based(tablosal değil döküman tabanlı key, value gibi) tabanlı bir veritabanıdır. Mongoose ise MongoDB dökümanlarını biraz daha tablosal hale (schema based) getiren nesne modelleme aracıdır. Schema validasyonu, type casting/conversions, model logic gibi işleri kendisi yönetir. CRUD metodları mongoose ile schema ları ile birlikte gelir.

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    default: Date.now
  }
});
const User = mongoose.model('User', UserSchema);
module.exports = User;

Parolayı database e kayıt ederken plain halini değilde hash halini database’e kayıt etmek iyi bir pratiktir. Bcrypt kendi built-in metodları ile otomatik üretilen salt parolayı db ye kayıt eder. Login sırasında compare ederken yine salt kullanılarak hash edilmiş şifreyi kullanıcının şifresi ile kıyaslar.

https://codahale.com/how-to-safely-store-a-password/ —- tl;dr : use bcrypt

router.post('/register', (req, res) => {
  const { name, email, password } = req.body;
  User.findOne({ name })
    .then(user=>  {
      if(user) {return res.status(400).json()}
    });
  const newUser = new User({
    name,
    email,
    password
  });
  bcrypt.hash(password, saltRounds, (err, hash) => {
    newUser.password = hash;
    newUser.save((err, user) => {
      if (err) return console.error(err);
      console.log(user.email);
    });  
  });
  res.send("ok");
});

LogIn ve JWT üretmek/1dakikalık geçerli accessToken

router.get('/authenticate', (req, res) => {
  const {username, password} = req.query;
  User.findOne({name: username}, (err, user) => {
    if(user){
      bcrypt.compare(password, user.password, function(err, result) {
        if(result){
          jwt.sign({id: user.id, email: user.email}, 
            require('../config/default').JWT_SECRET,
            {expiresIn: '60s'},
            (err, token) => {
              return res.json({
                token: token
              });
          });
        }else{
          return res.status(400).json('user or password is incorrect')
        }
      });
    }else{
      return res.status(400).json('user or password is incorrect')
    }
  });
});

API güvenli hale getirmek: Özel bir resource’a request geldiğinde middleware fonksiyonu ile Request header’i içerisinde Authorization eki aranması ve request objesine token set edilmesi. Resource içerisinde ise token verify edilir.

router.get('/profil', verifyToken, (req, res) => {
  jwt.verify(req.token, require('../config/default').JWT_SECRET, (err, userData) => {
    if(err){
      res.sendStatus(403);
    }else{
      res.json({
        userData,
        secret: 'Node is great'
      });
    }
  });
});

function verifyToken(req, res, next){
  const bearerHeader =  req.headers['x-access-token'] || req.headers['authorization'];
  if(typeof bearerHeader !== 'undefined'){
    const bearer = bearerHeader.split(' ');
    const token = bearer[1];
    req.token = token;
    next();
  }else {
    res.sendStatus(403).json('Access denied');
  }
}

Kod: https://github.com/eroltutumlu/node-auth

Hackerrank Repeated String Sorusu matematiksel çözüm

Given an integer, n, find and print the number of letter a’s in the first letters of S(String)

n <= 10^6

Örneğin:

s = “abcac”

n = 10

Yeni String = “abcacabcac” (n haneli oldu ve tekrar edebildiği kadar tekrar etti)

Bizden istenen ise string içerisindeki a karakterinin sayısı: sonuç olarak 4

Çözüm:

n/s yapıldığı zaman kaç kere birinci string kümesinin kaç kere repeat yapıldığını bulabilirim. Örnekte kalan 0 ve bölüm ise 2. S içerisinde 2 adet a vardı. 2*2 den 4 adet olacağını anlıyorum. Eğer kalan olsaydı ayrıca for döngüsünü kalan sayısı kadar dönüp a ların sayısnı bulabilirim

long repeatedString(char* s, long n) {

    long strCount = strlen(s);
    long aCount = 0;
    for (int i = 0; i < strCount; i++) {
        if(s[i] == 'a'){
            aCount++;
        }
    }

    long reminder =  n % strCount;
    long division = n / strCount;
    aCount = aCount * division;

    for (int i = 0; i < reminder; i++) {
        if(s[i] == 'a'){
            aCount++;
        }
    }

    return aCount;

}

Temel mülakat soruları

Glassdoor üzerinden FANG şirketlerinin çalışma kültürlerine, maaş ve mülakat soruları gibi bilgilere ulaşılabiliyor. Yorumlar Anonymous olarak yapılıyor. İncelediğimde CS50 temel soruları, Veri yapıları(btree, list), teknik olarak ise Coding interview questions kitabından veya leetcode gibi sitelerdeki sorulara benzer sorduklarını gördüm.

En temel aklıma gelen mülakat soruları şu şekilde:

  • STACK, HEAP nedir? (Tanımların yapılması, Nerede kullanıldığının bildirilmesi, Bellek yapısından bahsedilmesi, Register, Flip Flop, 0,1) Stackoverflow nedir?
  • reference type/value type nedir? Dillere göre örnek verilmesi
  • Kabaca internet nasıl çalışır? Client server mimarisi, Data iletimi için geçerli protokollerin belirtilmesi
  • NoSQL, Relational DB nedir? Farkları nelerdir? Use case’leri nedir? In memory db nedir?
  • OO Design nedir? Temelleri nedir? Neden yapılır?

Bir yazılımcının kesin bilmesi gerekli dediğiniz soruları sizde paylaşabilirsiniz.

Docker postgres bağlantısı

Docker developer dostu bir container teknolojisi olarak tanımlayabiliriz. Bilgisayarıma PostgreSQL kurmak yerine Docker yardımıyla kurulumunu yapacağım. Böylece docker engine kendi içerisinde kurulum yapacak bende expose ettiğim port üzerinden postgres ile konuşacağım. Bu örnek PostgreSQL üzerinde olsada lighweight veya heavy tüm framework/environment tool ları kurmak mümkün.

Postgres instance i başlatmak:

docker run –name CONTAINER_NAME -e POSTGRES_PASSWORD=PASSWORD -d -p 5430:5432 postgres

Yukarıdaki komut docker hub üzerinden postgres imajını pull edecek ve çalışan bir container haline getirecek. -e ile environment özellikleri veriliyor. Kullanıcı adı ve db default postgres olduğundan özellikle vermeye gerek yok fakat şifre deneme amaçlı password olarak verildi. -d ise container in arka planda çalışmasını sağlıyor bu sayede bash işgal olmamış oluyor. -p ise docker container’i ile tcp üzerinden kullanabileceğim port tanımı yapılması anlamına geliyor. Container üzerindeki 5432 fakat ben 5430 ile postgres’e bağlanacağım.

DBeaver ile POSTGRESQL bağlantısı

Diğer bir yoluda docker-compose dosyası ile bağlantı gerçekleştirmek:

docker-compose.yml

version: '2.1'
services:
postgres:
image: postgres
container_name: postgres
restart: always
ports:
- 5430:5432
environment:
POSTGRES_PASSWORD: 123456
POSTGRES_DB: customermanagement

docker-compose up -d komutu ile postgres imajı local üzerinde yoksa pull edilir ve container olarak çalışır hale gelir. Docker-compose kullanmanın avantajı uygulamayı bir bütün olarak containerization edilebilir. Tüm docker dependency’leri docker-compose ile yönetilebilir. Image isimleri services altına yml formatında yazılır

Software Developer’lar için Docker 101

https://www.ubuntupit.com/important-docker-commands-for-software-developers/

https://github.com/eroltutumlu/customer-management-api

Hackerrank Warm up Challenge: Sock Merchant

Yazılım dünyasında zinde kalmanın ve hergün kod pratiği yapmanın önemli olduğunu düşünüyorum. Programlama soruları çözerek bildiğimiz dilin tekniğini daha çok öğrenme şansı bulabilir ve kendi çözümlerimizi başkalarının çözümleriyle karşılaştırabiliriz. Farklı sorular çözerek kendimizi bir üst seviyeye taşıma şansı edinebiliriz.

Firmaların mülakat süreçlerinde kullandığı/developer’ların sorular bulup kendini geliştirebileceği birkaç ortam:

Yazılarımda hackerrank üzerinde karşılaştığım bazı soruları blog siteme taşıyacağım.

Problem

Bir çorap dükkanında çorap çiftlerinin sayısının elde edilmesi. Çoraplar bir dizi içerisinde renksel olarak tutuluyor.

Örnek: 10 20 20 10 10 30 50 10 20

sock.png
Şekil 1: Çorap çiftleri

Dizi içerisinde 10(yeşil) sayısından 4 adet var. Bu durumda iki eşleşme durumu oluyor. 3 tane ise 20(mavi) var. Bu durumda 2 eşleşme olur ve mavilerden 1’i dışarıda kalır. Output olarak 2+1 = 3 eşleşme verir.

Pseudocode

def sockMerchant(n, sockArr)
   socksCountValuePair = Key Value
   count = 0
   for each sock int sockArr
      if socks contains sock
          update sock's value + 1
      else
          sock's value = 1
      if sock's value != 1 and sock's val %2 == 0
          count++
 return count;

Kod

Map<Integer, Integer> socks = new HashMap<Integer,Integer>();
int count = 0;
for(int i = 0; i < ar.length; i++) {
  int sock = ar[i];
  socks.put(sock, socks.containsKey(sock) ? socks.get(sock) + 1 : 1);
  int v  = socks.get(sock);
  if(v!=1 AND v%2==0) {
    count++;
  }		
}	
return count;

En kötü durumda karmaşıklığımız(Time complexity) O(n) olarak çalışır. Tanım ve hesaplamar sabit olarak alındı.

Bazı çözümler HashSet ile yapılmış. HashSet ve HashMap karşılaştırması için aşağıdaki linki bırakıyorum

https://stackoverflow.com/questions/2773824/difference-between-hashset-and-hashmap