28 Şubat 2020 Cuma

System Call Nedir

Sistem Çağrısı (System Call) Nedir?
System Call ile kernel içindeki bir kod parçası çalıştırılır. Açıklaması şöyle.
An operating system can access a system's hardware directly, but a user program is not given direct access to the hardware. This is done so that the kernel can keep the system safe and secure from malicious user programs. But often, a user program requires some information from the hardware (e.g., from a web camera to show you the picture), but it cannot get the information directly. So, it requests the operating system to supply it the information. This request is made by using an appropriate system call.
Sistem Çağrısı İçin Yöntemler
1. Jump Table İle Subroutine Çağırmak
Bu yöntem çok eskiden kullanılıyormuş. Açıklaması şöyle
...coming from 8-bit systems that accessed system services by calling subroutines through a jump table. This simple system seems to give the same benefits from indirection as using software interrupts on x86. An example of such a system is the kernel (or "Kernal", for Commodore purists) used on Commodore's 8-bit machines.

Additionally, the reliance on software interrupts might be a reason for why the transition to using Protected mode, and accessing more than 640KiB of memory, was so slow and difficult for MS-DOS users.
2. Interrupt Çağırmak
Bu yöntem özellikle Intel tarafından tercih ediliyormuş. 8086 ile de mecburi hale gelmiş. Açıklaması şöyle.
Using INT comes not only natural due the way the 8086 is designed, but was as well intended by Intel as OS entry point, much like a Super Visor Call (SVC) on /360 type mainframes:
x86 INT 0x20 - DOS İçindi
Açıklaması şöyle.
Access to the DOS API was done through the INT 21h x86 instruction.
x86 INT 0x80 - Eski Linux Kernelleri İçindi
Linux üzerinde sistem çağrısı yapmak için Kernel 2.5'ten önce INT 0x80 (Interrupt) kullanılıyordu.
Aşağıdaki cümleyi buradan aldım
Most Unix systems and derivatives do not use software interrupts, with the exception of interrupt 0x80, used to make system calls. This is accomplished by entering a 32-bit value corresponding to a kernel function into the EAX register of the processor and then executing INT 0x80.
Mesela dosya açmak için 5 numaralı sistem çağrısı yapılırdı. EAX'e 5, dosya ismine pointer EBX'e, bayraklar ECX'e, dosya açma modları EDX'e yazılır ve sistem çağrısı yapılırdı.

Yeni çekirdeklerde x86 mimarisi için SYSENTER/SYSEXIT talimatları kullanılıyor.

Aşağıdaki şekilde INT 0x80 kullanımını görmek mümkün.


C Kütüphanesi
Tabiki sistem çağrısı artık modern diller vasıtasıyla genellikle bir kütüphanenin arkasına gizlenmiş durumda. Örneğin aşağıdaki şekildeki glibc (GNU C kütüphanesi) gibi.

Hatta glibc içindeki read/write gibi metodlar bile bir seviye daha soyutlama kullanıyorlar. Açıklaması şöyle.
....the syscall functions you use (read(), write(), ...) are all libc wrappers around the real syscalls, even the generic syscall() function.
glibc kütüphanesinin devre dışı bırakarak direkt sistem çağrısı yapmak mümkün. Yöntem ise inline assembly. Açıklaması şöyle.
The only way of manually calling a syscall without passing through the C library (and therefore without doing symbol resolution) other than compiling statically is to use inline assembly. You can take a look at man 2 syscall to see which registers and instructions to use. On ARM AArch64 for example you can invoke a syscall by loading the syscall number in the register x8, parameters in x0 through x5, and then executing the svc #0 instruction.
Sistem Çağrısını Hızlandırmak
how does the processor know an instruction is making a system call sorusunda ise bazı sistem çağrılarını hızlandırmak içinse vsyscall (virtual system call) yapısının kullanıldığından bahsediliyor. Örneğin gettimeofday bir sistem çağrısını olmasına rağmen, belli bir adreseteki sayfaya sabitlendiği için CPU, kernel moduna geçmeden daha hızlı olarak çağırılabiliyor.
Sistem Çağrısında CPU Kernel Moduna Geçer
Sistem çağrısının başlaması için ilk önce CPU'nun user modundan kernel moduna geçmesi gerekmektedir. CPU modlarını öğrenmek için CPU modes başlıklı yazıya bakabilirsiniz. CPU modları ayrıca genellikle Ring'ler ile ilişkilendirilmiştir. Örneğin kernel mod Ring 0'ı kullanırken Device Driver kodu kernel içinde olsa bile Ring 1'i kullanabilir. Bu sadece bir örnekti, Windows NT ve Unix genellikle sadece Ring 0 ve Ring 3'ü kullanırlar.

Dolayısıyla bir sistem çağrısı (system call) en basit ve hiçbir bloke olma durumunu içermiyorsa aslında sadece CPU'nun mod değiştirmesi olarak düşünülebilir. Aşağıda buradan aldığım ve daha rahat anlaşılsın diye kırptığım bir şekil ile bunu görmek mümkün. Kırmızı renk ile temsil edilen çizgilerde kernel kendi context'i içindeki kod parçasını mod değiştirerek çalıştırıyor.

Örneğin şimdiki zamanı isteyen bir kernel metodunu çağırıyor olsaydık, kernel önce user mod yazmaçlarını muhafaza edecek, daha sonra kendi içindeki kodu çağıracak ve daha sonra cevabı bizim yazmaçlarımızdan birine veya hafızada bir yere yazacaktı. Burada dikkat edilmesi gereken nokta işletim sisteminin bizim yazılımımıza hiç bir zaman kesme yapmadığını farz ediyoruz. Bu durumda context switch yapılmasına da - yani bir programdan başka programa geçişe - gerek kalmıyor.

Thread
Bir thread'in sistem çağrısı yapıp yapmadığını görmek için (örneğin read/write) ps komutunu kullanabiliriz.

Örnek
Şöyle yaparız.
ps -p<pid> -o stat
Çıktıda şu değerleri görüyorsak thread sistem çağrısındadır.
D    uninterruptible sleep (usually IO)
S    interruptible sleep (waiting for an event to complete)

27 Şubat 2020 Perşembe

Clean Architecture (Uncle Bob)

Giriş
Clean Architecture kitabı 2012 yılında yazıldı

Mimari ve Yazılımda Kullanılan Kütüphaneler/Çatılar
Mimari ve yazılım iskeleti farklı şeylerdir. Açıklaması şöyle
“Your architectures should tell readers about the system, not about the frameworks you used in your system” — Robert C. Martin.
Spring vs Clean Architecture
Clean Architecture with Spring Boot: A good idea? yazısında bir karşılaştırma var. Clean architecture ile yazılımın Maintainability level iyileşiyor. Ancak Propagation cost artıyor


Screaming Rule
Açıklaması şöyle. Yani bir bakışta yazılımın ne yaptığı anlaşılabilmeli
The “Screaming” Rule
I couldn’t really find a name for the second diagram, so I called it “The Screaming Rule”, but I believe this is pretty accurate — let me explain!

Uncle Bob stated on multiple occasions that the architecture of an application should scream at you what the application is all about. He even has a nice metaphor for it, saying that, when you see the blueprints of a building you can easily tell if the building is a church, a house, or a library. Similarly, the design of our software should shout banking, retail, or gaming, rather than Spring, .NET, or Flask. I highly encourage you to read his article where he goes as far as calling this design “The Screaming Architecture”.

The only way of achieving this expressive design is to put the use cases in front of the implementation details.
Bir cümle şöyle
The goal of software architecture is to minimize the human resources required to build and maintain the required system. 
Mimarinin Değişmesi
Bir cümle şöyle
When requirements change, the difficulty in making such a change should be proportional to the scope of the change, not to the shape of the change. The difference between scope and shape often drives the growth in software development costs. It is the reason that the first year of development is much cheaper than the second, and the second year is much less expensive than the third.
Mimari
Kitapta kullanılan şekil şöyle
Bu şeklin açıklaması şöyle. Günümüzde Use Case kelimesi yerine Service kelimesi kullanılıyor.
The Dependency Rule
The first diagram is a visual representation of the “Dependency Rule”. This rule states that all the source code dependencies should point inwards. As a result, the Controllers will depend on our Domain Services, and they will depend on our Entities — which will sit at the center of our application.

In other words, our Entity objects do not know anything about the use cases, which, in turn, do not know about the framework. As a result, we will decouple the business rules and use cases from the framework and delivery mechanisms. ...

This idea was largely accepted and adopted: we can see everywhere this Controller — Service — Repository layer separation. There is a small difference though: maybe you have noticed that the “Use Case” classes from the original diagram are replaced here by “Services”.
Clean Architecture Kitabındaki Mimariye Benzeyen Türevler
Açıklaması şöyleHexagonal Architecture yazısına bakabilirsiniz. Bence Hexagonal Architecture daha önce ortaya çıkmış bir kavram. Dolayısıyla Clean Architecture ilham almış diyebiliriz.
Since then, his diagram has been used many times by various tech writers and conference speakers. Some of the original ideas were slightly changed or enhanced, leading to different names for the resulting designs: For instance, you might find it labeled as “Hexagonal Architecture” or “Ports and Adapters”.

Eleştiriler
Microservice mimaride bu Clean Architecture yapısını eleştiren bir yazı burada. Güçlü ve zayıf yönleri şeklen şöyle. Yani reliability ve security kısımları zayıf


Mimarinin Özellikleri
Bazı maddeler şöyle.
Some characteristics of a clean architecture, as described on the blog post, are:

1. Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.

2. Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.

3. Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.

4. Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.

5. Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.
Aslında bu maddelerin bence en önemlisi şunlar. Yani yazılımın test edilebilir olması ve teknolojinin kolayca değiştirilebilmesi.
A Clean Architecture style has a positive effect on maintainability:
- We can test domain entities and use cases without a framework, UI, and infrastructure.
- Technology decisions can change without affecting domain code. And vice versa. It is even possible to switch to a new framework with limited effort.



26 Şubat 2020 Çarşamba

Test Design Techniques - Exploratory Testing (Keşif Testi)

Giriş
Açıklaması şöyle"Keşif testi" testçinin geçmişte edindiği bilgeye dayanarak testler tasarlamasıdır.
Essentially, exploratory testing is a software testing approach that is executed without any previously developed documentation, test cases, or checklists. Therefore, a tester creates and runs tests based on his knowledge regarding the product. Overall, experience and extensive technical background of QA engineers plays a big role, helping them execute tests more accurately.
Bu Yöntem Ne Zaman Kullanılır
Bu teknik zaman kısıtı olan, test  ile gereksinim arasında izlenebilirlik kurulması gerekmeyen durumlarda kullanılabilir. Açıklaması şöyle.
-New projects that don’t have extensive documentation yet
-To identify software weaknesses
-Gathering more information about product logic and workflow
-If the testing team includes skilled testers who could perform the exploratory testing without losses in the budget and time, etc.
Nasıl Yapılır
İzlenebilecek yöntemler şöyle
1) Freestyle Exploratory Testing : Freestyle testing yöntemi kullanılsa bile bu yöntem "sağına soluna tıklama" olarak algılanmamalı. Açıklaması şöyle
As the name suggests, this technique provides a freedom to the testers to investigate bugs or defects without any detailed planning. This technique is usually carried out by a tester when there is a need to become familiarized with an application and to perform parallel continuous testing without defining any ground rules for test coverage.
2) Scenario-Based Exploratory Testing - Belli bir senaryo takip edilir. Açıklaması şöyle
This type of testing is usually carried out after the initial phase of testing in order to make revisions to the testing flow, as per the observations from the initial testing process. The idea is to develop end-to-end scenarios according to real users' interactions. Testers tend to consider different sets of possibilities by exploring the platform to match each developed scenario and provide maximum test coverage.
3) Strategy-based Exploratory Testing - Yazılıma aşina olan testçiler en riskli bölgeleri test ederler. Açıklaması şöyle
This type of exploratory testing is mostly done by testers familiar with an application’s functionalities that need testing. Familiarity with the product is important to defining testing strategies. The strategy to test is usually developed using various analyses, such as Boundary Value analysis, the equivalence technique, and the risk-based technique to identify more potential bugs.
En İyi Uygulama (Best Practice) Maddeleri
İzlenmesi gereken bazı maddeleri şöyle.
1. Organize Your Test Cycle With Enough Time Window
2. Add Checkpoints Early on in the Testing Process
3. Record the Entire Process With Great Detail
4. Aim to Be a User When Performing Exploratory Testing
5. Define the Scope of Exploratory Testing With Precision
6. Prioritize and Classify Your Bugs
7. Prepare an Informative Bug Report
Exploratory Testing ve Test Otomasyonu
Açıklaması şöyle. Bu tür testleri tam otomasyona sokmak çok mümkün değil.
While some testing activities can be done by a testbot, it is actually not possible to do a full exploratory test via test automation. Common things that we can automate in the flow of exploratory testing are generating random test data, performing functional test executions, output logging, developing reports, and sharing insights with the development team.

HTTP Durum Kodları

Giriş
Http Durum Kodları'nın (Http Status Codes) listesi burada.

Programlarken hata oluşması durumunda exception atarız. Ancak iletişim protokollerinde exception atamayacağımız için durum kodu döndürmek gerekir.

Security By Obscurity
Security through obscurity olarak ta bilinir. Örneğin bilinçli olarak yanlış Http Durum Kodunu dönmek bu yöntemlerden birisidir. 401 Unauthorized yerine 305 Use Proxy dönülebilir.

Informational Kodları
Information Kodları yazısına taşıdım.

SUCCESS Kodları
SUCCES Kodları yazısına taşıdım

REDIRECTION Kodları
REDIRECTON Kodları yazısına taşıdım

CLIENT ERROR Kodları
CLIENT ERROR Kodları yazısına taşıdım

SERVER ERROR Kodları
SERVER ERROR Kodları yazısına taşıdım.

24 Şubat 2020 Pazartesi

IEEEE 754 - Double

Double
Double'ın bir diğer ismi ise Double-precision floating-point format.

Double için kullanılan 64 bit şöyle bölümleniyor.
   1 bit|11bit    |52 bit
    sign|exponent |mantissa veya significant
Türkçeleri şöyle:
Sign = Yön, Exponent = Üst, Mantissa = Kök

32 bit tüm tamsayılar, double ile temsil edilebilir.

Exponent
Açıklaması şöyle. Yani bu alanın 11 bit olması tesedüf değil.
For the 64-bit format, the main consideration was range; as a minimum, the desire was that the product of any two 32-bit numbers should not overflow the 64-bit format. The final choice of exponent range provides that a product of eight 32-bit terms cannot overflow the 64-bit format — a possible boon to users of optimizing compilers which reorder the sequence of arithmetic operations from that specified by the careful programmer.
Significant Figure
Not : Bir çok yazıda precision yerine "significant figure" kelimesi de kullanılıyor. Ben bu yazıda precision kelimesini kullandım, çünkü Fizik Bilimindeki significant kavramı ile karışmasın istedim.

Fizik Biliminde significant kelimesinin tanımı şöyle. Yapılan ölçümde kaç haneye kadar emin olduğumuzu gösterir.
  1. Significant figures by definition are the reliable digits in a number that are known with certainty.”
  2. “A significant figure is the one which is known to be reasonably reliable.”
Precision
Tablo olarak şöyledir.
             bits        range                       precision
  float        32        1.5E-45   .. 3.4E38          7- 8 digits
  double       64        5.0E-324  .. 1.7E308        15-16 digits
  long double  80        1.9E-4951 .. 1.1E4932       19-20 digits
Precision toplam hane sayısı anlamına gelir. Bu veri tipi ile 16-17 precision 'a kadar sayıları saklamak mümkün.  Örnek'te 17 hane var.
569.23230682688904 - Toplam 17 hane
Ya da şöyle
double: 0.333333333333333 - Toplam 17 hane , sıfır hariç
C dili precision değerine erişmek için bazı macrolar tanımlamış. Bunlar şöyle. İlk sütun C'deki tanımlı minimum değer, ikincisi ise IEEE 754 standardındaki tanıımlı değer. double için C 10 hane, IEEE 754 ise 17 hane belirtir. Bir çok derleyici IEEE 754 uyumlu olduğu için ikinci değeri kullanır.
FLT_DECIMAL_DIG   6,  9 (float)                           (C11)
DBL_DECIMAL_DIG  10, 17 (double)                          (C11)
LDBL_DECIMAL_DIG 10, 21 (long double)                     (C11)
DECIMAL_DIG      10, 21 (widest supported floating type)  (C99)
Tam Sayı
"Integer digits",  "Integral digits" olarak adlandırılır.

Küsurat
"Fraction Digits", "Fractional Digits", "Fractional Part" veya çok nadiren de olsa "Decimal" olarak adlandırılır. Cümle içindeki örnek şöyle
For instance, in the number 31.415, there are two integer digits and three fraction digits.
Round Trip
Şöyle yaparız.
printf("%.17g", number)
Örnek
Elimizde şöyle kodlar olsun
C++ kodu
cout.precision(17);
for (double i = 0.0; i < 3; i = i + 0.1) {
  cout << fixed << i << endl;
}
Java kodu
for (double i = 0.0; i < 3; i = i + 0.1) {
  System.out.println(i);
}
Bu 3 kod sanki farklı sonuçlar veriyor gibi görünebilir. Ancak esas fark double değerin string'e çevrilirken geçtiği işlemden kaynaklanıyor. Örneğin C ve Java double'ın sadece bir komşu değerden farklı olduğunu gösterecek kadar basamak kullanmasını gerektiriyor.

Significant Precision
Significant sağdaki sıfırların üst şeklinde yazıldıktan sonra kalan rakamlardır. Örneğin 1500 sayısı 1.5 x 10 ^ 3 şeklinde yazılabilir. Bu durumda Significant 1.5 olur. Bundan sonra tam hane sayısı olarak yazacağım.

1. C Dili
C dili significant precision değerine erişmek için bazı macrolar tanımlamış. Bunlar şöyle. İlk sütun C'deki tanımlı minimum değer, ikincisi ise IEEE 754 standardındaki tanıımlı değer. double için C 10 hane, IEEE 754 ise 15 hane belirtir. Bir çok derleyici IEEE 754 uyumlu olduğu için ikinci değeri kullanır.
FLT_DIG   6, 6 (float)
DBL_DIG  10, 15 (double)
LDBL_DIG 10, 18 (long double)
 Açıklaması şöyle.
C provides DBL_DIG, DBL_DECIMAL_DIG, and their float and long double counterparts. DBL_DIG indicates the minimum relative decimal precision. DBL_DECIMAL_DIG can be thought of as the maximum relative decimal precision.
Bu macrolara bakınca değerleri şöyle
FLT_DIG 6 or greater
DBL_DIG 10 or greater
LDBL_DIG 10 or greater
2. C++
Eğer derleyici IEEE 754 uyumlu ise  tam sayı hanesi ise 15'tir. Yani noktanın sol tarafında en fazla 15 tane sayı olabilir. Yani tüm 15 haneli tam sayılar double'a çevrilip tekrar tam sayı haline gelebilir.
int digit10=std::numeric_limits<double>::digits10; // ==15
3. Kendimiz
Şöyle hesaplarız.
log10(2^53) = 15.95
Küsuratlı sayı olamayacağı için sayı aşağıya yuvarlanır ve 15 olur.

Exponent
Exponent alanı 1023'e göre referans alınır. Bunan exponent bias denir. Örneğin exponent olarak 1 elde etmek istiyorsak 11 bitlik bu alana 1024 yazmak gerekiyor çünkü 1024 - 1023 = 1 .

11 bitlik alana 0 .. +2047 arasında bir değer yazılabilir ki bu da -1022 .. +1023 arasında exponent elde edebilmemize neden olur

C++'ta numeric_limits içindeki radix, digits, min_exponent, max_exponent, min_exponent10, max_exponent10 metodları da kullanılabilir. Double için şu çıktıyı alırız.
radix : 2
digits : 53
min_exponent : -1021
max_exponent : 1024
min_exponent10 : 308
max_exponent10 : -307

Sonsuz Sayısı
Örnek - Java
Şöyle yaparız.
double i = Double.POSITIVE_INFINITY;
Sonsuz Sayısını Sayıyı Artırmak
Açıklaması şöyle.
...because adding 1 to a floating-point value that is sufficiently large will not change the value, because it doesn't "bridge the gap" to its successor.
Örnek
Şu kod sonsuz döngüye sebep olur.
double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}

En Büyük Sayı
Örnek - C Dili
Double ile temsil edilebilecek en büyük sayı DBL_MAX  sabiti ile bulunur. Yazdırırsak şu çıkar.
1.7976931348623157e+308
Örnek - Java
Şöyle yaparız
double i = Double.MAX_VALUE;
En Küçük Sayı
Double ile temsil edilebilecek en küçük sayı sabiti -DBL_MAX ile bulunur. C++ ile şöyle yaparız.
std::numeric_limits<double>::lowest()
Java'da şöyle yaparız
The smallest negative number for Double is -Double.MAX_VALUE
Sıfıra Yakın En Küçük Sayı
Double ile sıfıra en yakın sayı  DBL_MIN ile bulunur. C++ ile şöyle yaparız.
std::numeric_limits<double>::min()
NaN Sayısı
Örnek - Java
Şöyle yaparız.
double i = Double.NaN;
NaN Sayısını Artımak
Açıklaması şöyle.
...results in an infinite loop, because NaN is not equal to any floating-point value, including itself
Örnek
Şu kod sonsuz döngüye sebep olur.
double i = Double.NaN;
while (i != i) {}
Karşılaştırma
Yöntemler şöyle
1. Her sayı belli bir küsurat hanesine yuvarlanır ve >, < işlemine sokulur. 
org.apache.commons.math3.util.Precision sınıfı kullanılabilir

Örnek
Şöyle yaparız
double firstValue = 10.2f;
double secondValue = 10.3f;
       
if(firstValue > secondValue){
  System.out.print("First Value and second value are not equal");
}
2. Epsilon veya diğer ismiyle tolerans değeri kullanılarak karşılaştırma yapılır.
Bu yöntemi kullanıyorsak metod isimleri şöyle olabilir. Metod isimleri için Almost, Nearly,Approximately gibi isimler de kullanılabilir
NearlyEqual
NearlyNotEqual
DefinitelyGreater
NearlyGreaterOrEqual
DefinitelyLess
NearlyLessorEqual
Yine org.apache.commons.math3.util.Precision sınıfı kullanılabilir
Veya com.google.common.math.DoubleMath sınıfı kullanılabilir
3. Belirtilen ULP (x ve y değeri arassındaki kaç tane double olduğu) kadar yakın olup olmadığının karşılaştırması yapılır
Yine org.apache.commons.math3.util.Precision sınıfı kullanılabilir


Küsurat Hanesine Yuvarlama
Şöyle yaparız.

Sum İşlemi
Bir çok double sayısını ardarda toplayınca aslında hataları da eklemiş oluyoruz. Yani sapma daha çok oluyor. Bu gibi durumlar için Kahan summation kullanılabilir. Java'daki DoubleStream bu algoritmayı kullanıyor.