28 Mayıs 2019 Salı

DevOps

DevOps Aslında Çevik (Agile) Süreçlerin Devamı
Açıklaması şöyle. Amaç devir işlemlerini ve birbirini bekleyen birbirine muhtaç insanları en aza indirmek.
In order to do small batch releases central to Lean and Agile best practices, you need to find a way to reduce handoffs and make releasing to production seamless and easy. Out of this necessity naturally flow many of the DevOps practices. The concept of the full stack engineer popularized in DevOps is a natural answer to this need. To reduce handoffs engineers must be conscious of all portions of the system so that any member of the team can understand and integrate QA, security, and operational requirements without handing off to other teams. Similarly, cross-functional teams must become the norm so that small, self-contained team can deliver fully functional products without additional hand-offs to operations teams.
DevOps Ne Olarak Anlaşılıyor
Sanırım en çok bir şeylerin otomasyona geçirilmesi olarak anlaşılıyor.

Denetimli (Regulated) Ortamlar
Finans gibi denetimli ortamlarda bile DevOps kullanılıyor. Açıklaması şöyle
Challenges of implementing DevOps in the finance industry
Unlike other industries, regulated industries imply several challenges 

- Strong restrictions on secured networks 

- Fine-grained audit trails 

- Strong ACLs models 

- Full lifecycle governance 

- Integration with 3rd parties
Governance
Governance için bir yazı burada.

23 Mayıs 2019 Perşembe

CMMI - Requirements Management Süreci

Giriş
Gereksinimlerin tanımlanması ve yazılması zor bir iştir ve bir çok müşteri ne istediğini tam olarak bilmez.


Requirements Management Nedir?
Requirements Management is a process which enables consistent administration (change management, establish traceability) of  the requirements during the project's software development lifecycle.

Yani kısaca yazılımın veya donanımın gerçekleştirilebilmesi için gereksinimlerin yazılması, yönetilmesi ve çift yönlü izlenebilirliğin olması gibi klasik süreci kapsıyor.

REQM Faaliyetleri
Bu alanın yapılmasını istediği maddeler aşağıda.

1 Understand Requirements - Toplantı ve Tutanaklar
Bu faaliyetin temel amacı gereksinimler üzerinde uzlaşma sağlamaktır. Uzlaşma sağlamak için bir çok kez bir araya gelinmesi gerekebilir. Toplantılarda Minutes of Meeting/Toplantı Tutanağı (MoM) tutulur. Yani bir şekilde uzlaşma kayıt altına alınır. MIL STD 498 kullanan projelerde sistem seviyesi gereksinimlere görüş vermek ve konuşmak için System Requirements Review (SRR) toplantısı yapılır.Eğer proje şirket içi bir proje ise, şirketin sürecinde tanımlı olan bir form/belge kullanılabilir.

2. Obtain Commitment to Requirements - Taahhüt/Bağlılık Formu
Obtain Commitment To Requirements maddesini yerine getirmek için bir çok şirket çalışanlarına bir belge imzalatıyor. Sanki imzalamama şansımız varmış gibi düşündürten bir belge işte.
3. Manage Requirements Changes - Araçlar
Proje kapsamında yazılım gereksinimlerinin yönetilmesi genellikle bir başka yazılım aracılığıyla yapılır. IBM Rational Doors, Rational RequisitePro ya da Excel bile kullanıldığını gördüm.

Konuyla ilgili olarak DOORS Notlarıma göz atabilirsiniz.

4 Çift Yönlü İzlenebilirlik - Maintain Bidirectional Traceability Of Requirements
REQM sürecindeki en zor maddelerden birisi çift yönlü izlenebilirlik matrisi tutmak. Bu matriste doküman ile bir üst veya bir alt doküman arasındaki maddeler arasında tablolar oluşturulur.

SRS ve STD Arasında Requirements Traceability Matrix yazısına bakabilirsiniz. 

- Çift yönlü izlenebilirlik matrisi projede kaynak koda kadar inecek kadar bilderinleştirilebiliyor. 

- Ancak en genel manada Kullanım Durumları ve İsterler arasındaki izlenebilirlik kast ediliyor

- Bazı projelerde Kullanım Durumu yerine Sistem Gereksinimleri Dokümanı var. O zaman Sistem Gereksinimleri dokümanı ile Yazılım Gereksinimleri Dokümanı arasında çift yönlü izlenebilirlik yapılır.

4.1 Statement Of Work
Sözleşme bir çok belgeden oluşur. Sözleşmenin bazı ekleri yazılım açısından önemlidir. Bunlar genellikle EK-A İş Tanımı (Statement of Work) ve EK-B Teknik Şartname belgeleridir. Teknik Şartname tedarik makamı tarafından hazırlanır.

Yazılım gereksinimleri geliştirilirken, projenin başındaki Statement of Work (SOW) dokümanına da atıfta bulunulur. SOW sözleşme altında sağlanan ürün veya hizmetin yazılı tanımını sağlayan dokümandır.
5 Alignment Between Project Work and Requirements
SRS ile tasarım arasındaki bağlantı. MIL-STD-498-SRS başlıklı yazıya göz atabilirsiniz.


Bazı Sorular
CMMI'da anlamadığım bir nokta Requirements Management sürecinin, Requirements Development'tan önce gelmesi. Aşağıdaki şekilde Requirements Management seviye 2'de tanımlı iken, Requirements Development seviye 3'te gösterilmiş.

Software Estimation

Giriş
Projenin başlangıcında bir kestirim yapılır. Şu kadar adam ile bu kadar süre ve maliyetle bu işi bitiririm diye.Bu kestirimin hazırlanması her zaman sıkıntılı bir iştir.

Kestirim Yöntemleri
Kestirim için count/compute/judge yöntemlerinden birisi kullanılabilir. Yanlış yöntem ise üst yönetim tarafından belirtilen süre ve kaynak sınırlamasına uyacak şekilde kestirim yapmaya çalışmak.

1. Count yönteminde iş daha alt parçalara ayrılarak her bir parçanın değeri sayılarak bir değer elde edilir.
2. Compute yönteminde kabaca bir hesaplama yapılır
3. Judge yöntemi tamamen öngörüye dayalıdır. Resmin tamamını başka bir projeye dayanarak öngörür ve bu yeni iş için öngörüde bulunuruz.

Tahmin/Kestirimin Sorgulanması
Tahminin en iyi/en kötü hangi kritere göre yapıldığını belirtmekte fayda var. Tahminin diğerleri tarafından sorgulanması gayet normal.

Function Point
Function Point (FP) genellikle Count yönteminde kullanılır. Her gereksinim veya iş parçacığı için bir FP değeri hesaplanır.  FP teknolojiden bağımsız düşünülmelidir. Açıklaması şöyle
Since Function Points measures systems from a functional perspective they are independent of technology.
Bir diğer açıklama şöyle. Elimizde detaylı gereksinim yoksa FP hesaplamak kolay değil.
Function points are measured based on the requirements to fulfill (e.g. number of forms, number of fields in each forms, etc...). Productivity is then measured in FP per unit of time and per person. The problem with FP is that it requires very detailed requirements upfront.
Her bir FP şu noktalardan low, average, high olarak değerlendirilir.
External Inputs, External Outputs, External Inquiry, Internal Logical Files,External Interface Files
Bu FP değeri Function Point Languages Table ile SLOC'a dönüştürülebilir. Dönüşüm ne kadar anlamlı bilmiyorum.

Şirketlerin bir FP için nihai üründe ne kadar SLOC kodladıklarını hesaplamaları da ne kadar anlamlı bilmiyorum çünkü FP'nin kodda tam olarak nerede başlayıp nerede bittiğini anlamak ta bir mesele.

SLOC
Farklı programlama dilleri ve farklı alanlar çok farklı SLOC'lara sebep olabilir. Eğer aynı programlama dili ve aynı alanda çalışıyorsak SLOC bir fikir verebilir. Açıklaması şöyle.
...within a same company, with similar culture, line of business and with enough data, differences (as to unique situations and capabilities of individuals) blend enough so that the SLOC metric is useful for comparing productivity of tools and languages.
Kanban
Kanbdan'da toplam bir kapasite vardır. Bu kapasite / haftada biten iş sayısına bakılarak bu iş ne zaman biter sorusu cevaplanabilir. Bir örnek burada

22 Mayıs 2019 Çarşamba

LeetCode Breadth First Search

Giriş
Breadth-First Search (BFS)- önce bir alt seviyedeki tüm çocukları dolaşır. Açıklaması şöyle
The thing about BFS, is that it traverses the graph level by level. Meaning that first it traverses all the vertices at a distance of 1 from the source vertex. Then it traverses all the vertices at a distance of 2 from the source vertex and so on.
BFS düğümü bir sol bir da sağ olmak üzere iki alt düğüm içerir. Tanımlamak için şöyle yaparız.
struct Node {
  Node* right;
  Node* left;
};
Dolaşma Sırası
Aşağıdaki ağaç yapısını BFS ile dolaşmak istersek sıralama şöyle olur. 1 sonra  2, 3 sonra 4,5,6 vs.
       1 
     /   \   
    2     3   
   / \     \   
  4   5     6   
 /           \ 
7             8
Complexity
Açıklaması şöyle
BFS runs in O(V + E) time provided the graph is represented by the adjacency list structure.

In the dense case also, you will see the answer will be O(V+E). (Representation is adjacency list).

In case of Adjacency matrix O(V^2).
Binary Search İle Farkı
Binary Search yani ikilik aramanın amacı en az sayıda düğümü dolaşmak, BFS'nin amacı ise tüm düğümleri belli bir sıra ile dolaşmak. Binary Search ile arama yapmak için şöyle yaparız.
Node* find(int v) {
  Node* temp = root;  
  while (temp != nullptr) {
    if (temp->data == v) {
      return temp;
    }
    else {
      if (v > temp->data) {
        temp = temp->right;
      }
      else {
        temp = temp->left;
      }
    }
  }
  return nullptr;
}
BFS - Özyinelemeli Dolaşma
Kodda önce left_subtree() daha sonra right_subtree() recursive (öz yinelemeli) olarak
Örnek
Şöyle yaparız. Burada tree bir map'e dolduruluyor. Böylece her seviyedeki nesneye kolayca erişilebiliyor.
typedef std::map<int, std::vector<node>> nodes_by_level;

join_siblings(int level, const tree& t, nodes_by_level& nodes) {
  if (t.root()) { 
    nodes[level].push(t.root());
    join_siblings(level + 1, t.left_subtree(), nodes);
    join_siblings(level + 1, t.right_subtree(), nodes);
  }
}

nodes_by_level join_siblings(const tree& t) {
  nodes_by_level nodes;
  join_siblings(0, t, nodes);
  return nodes;
}
Örnek
Soru Maximum Path Sum in a Binary Tree. Şöyle yaparız. Burada aslında yapılan hesaplamayı dikkate almazsak, klasik bir recursive BFS görebiliriz.
int findMaxUtil(Node node, Res res) { 
  if (node == null) 
    return 0; 
  
  // l and r store maximum path sum going through left and 
  // right child of root respectively 
  int l = findMaxUtil(node.left, res); 
  int r = findMaxUtil(node.right, res); 
  
  // Max path for parent call of root. This path must 
  // include at-most one child of root 
  int max_single = Math.max(Math.max(l, r) + node.data, node.data); 
    
  // Max Top represents the sum when the Node under 
  // consideration is the root of the maxsum path and no 
  // ancestors of root are there in max sum path 
  int max_top = Math.max(max_single, l + r + node.data); 
  
  // Store the Maximum Result. 
  res.val = Math.max(res.val, max_top); 
  
  return max_single; 
} 

int findMaxSum() {return findMaxSum(root);} 
  
// Returns maximum path sum in tree with given root 
int findMaxSum(Node node) { 
  // Initialize result 
  // int res2 = Integer.MIN_VALUE; 
  Res res = new Res(); 
  res.val = Integer.MIN_VALUE; 
  
  // Compute and return result 
  findMaxUtil(node, res); 
  return res.val; 
} 
BFS - Stack Kullanarak Dolaşma
Örnek
Şöyle yaparız
public List<Integer> closestKValues(TreeNode root, double target, int k) {
  // 1. Create a Priority Queue, sorted on diffs
PriorityQueue<double[]> pq = new PriorityQueue<double[]>(
Comparator.comparing(a -> a[1]));
  Stack<TreeNode> stack = new Stack<>();

  stack.push(root);

  // 2. Traverse tree iteratively and place items in PQ
  while (!stack.isEmpty()) {
    TreeNode current = stack.pop();
    pq.add(new double[] {current.val /* value */,
Math.abs(current.val - target/* diff */ )});
    if (current.left != null) {
stack.push(current.left);
    }
    if (current.right != null) {
stack.push(current.right);
    }        
  }

  // 3. Prepare the output with needed K-values.
  List<Integer> result = new ArrayList<>();

  for (int i = 0; i < k; ++i) {
    if (!pq.isEmpty()) {
result.add((int) pq.poll()[0]);
    }
  }
  return result;
}
BFS - Liste Kullanarak Dolaşma
Açıklaması şöyle.
In a BFS, you use a queue. If you come across an unseen node, you add it to the queue.
Örnek
Elimizde şöyle bir ağaç olsun.
   5
  / \
2     15
     /
    10
   / \ 
  6   14
Şöyle yaparız. Burada Tree bir listee dolduruluyor
public void bfs (Tree T)
{
  
  List<Tree> list = new List<Tree>();
  
  if (T == null)
    return ;
   
  list.Add(T);

  while (list.Count != 0)
  {
    Tree currNode = list.pop ();

    if (currNode.l != null)
    {
      ...
      list.Add(currNode.l);
    }
    if (currNode.r != null)
    {
      ...
      list.Add(currNode.r);
    }
  }
  
}
BFS İle Maze (Labirent) veya Izgara (Grid) Dolaşma
- Bu tarz sorular mülakatlarda çokça soruluyor. Genellikle bir kuyruk kullanılarak çözülür.

- BFS ile Dijkstra's Shortest Path çok benziyorlar. Aralarındaki en önemli fark BFS komşuları kuyruğa eklerken herhangi bir kritere bakmaz. Shortest Path ise en kısa yolu seçer.

Örnek
Labirentte alıcılar/mayınlar varsa bunların etrafından dolaşarak en soldan en sağa geçiş isteyelim. Adımlar şöyle

Başlamadan Önce
Elimizde kareleri temsil eden şöyle bir yapı olsun
struct Node {
  
  int x
  int y;
  int distance
}
Ayrıca dolaşılan düğümleri sakladığımız bir dizi olsun
boolean [][] visited = new boolean [M][N];
1. Başlamadan önce alıcıların ve etrafındaki 8 hücrenin konumlarını işaretle. Bu hücreleri uğranmayacak (tehlikeli) olarak bir sabitle işaretle.
2. Başlamadan önce normal hücrelerin mesafe bilgisini sıfırla.

Algoritma
1. En soldaki tüm sütunları eğer alıcılar yüzünden tehlikeli değilse BFS kuyruğuna ekle.
2. do till queue is not empty - kuyrukta eleman var olduğu sürece
  a) Kuyruktan bir eleman al
  b) Eğer hedef konum ise çık
  c) Değilse etrafındaki 4 tane kareyi eğer alıcı yoksa kuyruğa ve uğranmamışsa ziyaret edildi olarak işaretle, ayrıca mesafeyi artır  ve kuyruğa ekle
3. Eğer kuyruk boşaldı ve hedefe varılması ise false dön


Örnek
Kendimden iki düğüm ötedeki çocukları dahil ederek dolaşmak istersek şöyle yaparız.
For each vertex v in V
{
  Do a BFS with v as source vertex
  {
    For all vertices u at distance of 2 from v
    add u to adjacency list of v 
    and terminate BFS
  }
}
Örnek
Elimizde özel sadece şöyle dolaşabilen bir robot olsun. Yani sadece sağa veya aşağı gibebilsin.
(x,y)  ->  (x+y, y)
(x,y)  ->  (x, x+y)
Şöyle yaparız.
def can_reach_target(pos, target):
    if pos == target: 
        return True
    if pos[0] > target[0] or pos[1] > target[1]: 
        return False
    return can_reach_target((pos[0], sum(pos)), target) or \
           can_reach_target((sum(pos), pos[1]), target)