Slices in Zig are one of the language’s fundamental concepts and are implemented as “fat pointers.” This article explores what slices are, how they work as fat pointers, and their practical applications in Zig programming. What is a Fat Pointer? A fat pointer is a pointer that carries additional metadata alongside the memory address. In Zig, a slice is a fat pointer that contains: A pointer to the underlying data The length of the slice Slice Syntax and Structure In Zig, a slice is deno...| Posts on Murat Genc
Pointers are fundamental concepts in Zig that allow you to work with memory addresses directly. Unlike some other languages, Zig provides explicit control over pointer operations while maintaining safety through its type system. Basic Pointer Concepts What is a Pointer? A pointer in Zig is a value that stores the memory address of another value. Pointers are declared using the asterisk (*) symbol followed by the type of value they point to.| Posts on Murat Genc
Introduction Zig, a modern systems programming language, revolutionizes memory management through its allocator system. This guide will dive deep into the world of Zig allocators, exploring their functionality, types, and best practices. What are Allocators? Allocators in Zig are interfaces that abstract the process of memory allocation and deallocation. They provide a standardized way to request and release memory, allowing developers to write memory-safe code while maintaining control over ...| Posts on Murat Genc
Introduction Memory management is a cornerstone of systems programming, and Zig provides a robust set of tools to handle it efficiently and safely. This comprehensive guide delves deep into how Zig manages memory, focusing on the two primary types of memory allocation: stack and heap. We’ll explore the intricacies of each, their use cases, and how Zig’s features ensure safe and efficient memory usage. Stack Allocation Stack allocation in Zig is the default method for local variables.| Posts on Murat Genc
Introduction Zig, a modern systems programming language, offers powerful features like anonymous functions and closure-like behavior. This article provides a comprehensive exploration of these concepts, their implementation, and working mechanisms in Zig. Anonymous Functions Definition and Working Mechanism Anonymous functions, also known as lambda functions, are unnamed functions typically used for short-term or single-use purposes. In Zig, anonymous functions are implemented using a special...| Posts on Murat Genc
1. Basics of Return Values and Error Unions Before diving into advanced topics, let’s cover the fundamentals of return values and error unions in Zig. Understanding these basics is crucial for mastering Zig’s powerful error handling system. 1.1 Simple Return Values In Zig, functions can return values of any type. This flexibility allows for clear and expressive function signatures. Here’s a basic example: fn add(a: i32, b: i32) i32 { return a + b; } const result = add(5, 3); // result i...| Posts on Murat Genc
1. Introduction to Functions in Zig Functions in Zig are fundamental building blocks that allow you to organize code into reusable and modular units. Zig’s approach to functions combines simplicity with powerful features, enabling both straightforward implementations and complex metaprogramming techniques. Technical Background In Zig, functions are first-class citizens, meaning they can be assigned to variables, passed as arguments, and returned from other functions. Under the hood, Zig fun...| Posts on Murat Genc
Introduction In Zig, resource management and error handling are critical aspects of writing robust, efficient code. The defer and errdefer keywords are powerful tools that address these concerns, offering elegant solutions for ensuring proper cleanup and handling of resources. This guide will delve deep into their functionality, use cases, and best practices. Defer in Depth Basic Concept The defer keyword in Zig allows you to schedule a piece of code to be executed when the current scope exit...| Posts on Murat Genc
1. For Loops: The Cornerstone of Iteration 1.1 Basic For Loop: Unpacking the Simplicity Zig’s basic for loop is deceptively simple yet incredibly powerful. Let’s dissect it: const items = [_]i32{ 1, 2, 3, 4, 5 }; for (items) |item| { std.debug.print("Item: {}\n", .{item}); } Detailed breakdown: Syntax Analysis: for (items): This specifies the iterable. In Zig, this can be an array, slice, or any other iterable type.| Posts on Murat Genc
Table of Contents Introduction What are Smart Pointers? Comparison with C++ Pointers Common Smart Pointers in Rust Box Rc RefCell Arc Weak Memory Management and Safety Performance Considerations Advanced Usage Patterns Best Practices Comparison Table Conclusion Introduction Rust, a systems programming language celebrated for its emphasis on safety, concurrency, and performance, introduces a powerful concept known as smart pointers. These smart pointers are sophisticated data structures that n...| Posts on Murat Genc
Introduction Control flow is the cornerstone of programming logic, dictating how a program’s execution navigates through various decisions and conditions. Zig, with its emphasis on clarity and compile-time evaluation, offers a robust set of control flow constructs that blend simplicity with power. This comprehensive guide will delve deep into Zig’s control flow mechanisms, providing detailed explanations, practical examples, and best practices. 1. If Statements: The Bedrock of Decision Ma...| Posts on Murat Genc
🧠 The Philosophy Behind Zig’s Type System Zig’s type system is a testament to the language’s core philosophy: providing low-level control and high-level expressiveness without hidden costs. It achieves this through a careful balance of type inference, explicit typing, and powerful compile-time features. Let’s embark on a comprehensive journey through Zig’s type system, uncovering its nuances and capabilities. 🔍 Type Inference: Smart, but Not Too Smart Type inference in Zig is ...| Posts on Murat Genc
🧬 The DNA of Zig Strings: Bytes, Slices, and UTF-8 In the Zig programming language, strings are not a primitive type but rather a concept built upon more fundamental elements. This approach provides both power and flexibility, but it requires a deeper understanding to master. Let’s unravel the intricacies of Zig strings layer by layer. 1. The Fundamental Building Block: u8 At the most basic level, Zig strings are arrays or slices of u8 - 8-bit unsigned integers.| Posts on Murat Genc
🧱 The Building Blocks of Efficient Data Management In the world of Zig programming, arrays and slices stand as pillars of data organization and manipulation. These powerful constructs offer a blend of performance, flexibility, and safety that sets Zig apart in the realm of systems programming. Let’s embark on an in-depth journey to uncover the intricacies of arrays and slices in Zig! 📦 Arrays: The Steadfast Foundations Arrays in Zig are fixed-size, contiguous blocks of memory that sto...| Posts on Murat Genc
1. Introduction Bloom filters, invented by Burton Howard Bloom in 1970, are space-efficient probabilistic data structures designed to test whether an element is a member of a set. They are incredibly useful in various computer science applications, particularly when dealing with large datasets and when a small probability of false positives is acceptable. 2. Structure of a Bloom Filter A Bloom filter consists of two main components: A bit array of m bits, initially all set to 0 k different ha...| Posts on Murat Genc
🚀 The Programming Paradigm of the Future Zig, as a pioneer in modern systems programming, is redefining the concepts of “comptime” (compile-time) and “runtime”. These two concepts form the foundation of Zig’s revolutionary approach to performance and flexibility. Let’s take a closer look at this magical world! 🕰️ Comptime: The Power of Compile-Time Comptime is one of Zig’s most striking features. But what exactly is comptime, and why is it so important?| Posts on Murat Genc
Zig provides a rich set of basic data types that form the foundation for more complex data structures and algorithms. This comprehensive guide explores the fundamental data types in Zig, including integers, floats, booleans, and several other important types. 1. Integer Types Integers are whole numbers that can be either signed (positive, negative, or zero) or unsigned (positive or zero). Zig offers the following integer types: Signed integers: i8, i16, i32, i64, i128 Unsigned integers: u8, u...| Posts on Murat Genc
In Zig, variables and constants form the backbone of data management. This comprehensive guide will delve into the nuances of working with variables and constants, exploring advanced concepts and providing numerous examples to illustrate their usage. Variables in Zig Variables in Zig are mutable storage locations that can hold values of specific types. They are crucial for storing and manipulating data in your programs. Declaring Variables In Zig, you declare variables using the var keyword.| Posts on Murat Genc
In the ever-evolving landscape of software development, the ability to create adaptable, efficient, and scalable systems is paramount. Composable APIs have emerged as a powerful paradigm to address these needs. This article delves deep into the world of Composable APIs, exploring their intricacies, benefits, and implementation strategies. What are Composable APIs? Composable APIs, also known as API composition or microservices composition, represent a architectural approach where complex func...| Posts on Murat Genc
Zig: The Language That’s Turning Heads in Systems Programming 🚀 The New Kid on the Block That’s Shaking Up the Industry In the ever-evolving world of programming languages, Zig has burst onto the scene like a bolt of lightning, promising to revolutionize systems programming. But what makes Zig so special? Let’s dive into the exciting world of this young language that’s already making waves. 🕰️ From Humble Beginnings to Rising Star Zig’s journey began in 2015 when Andrew Kell...| Posts on Murat Genc
Table of Contents Introduction Fundamentals of Load Balancing Load Balancing Algorithms Round Robin Weighted Round Robin Least Connections Weighted Least Connections Least Response Time IP Hash URL Hash Least Bandwidth Resource-Based (Adaptive) Comparative Analysis Choosing the Right Algorithm Advanced Considerations Conclusion Introduction Load balancing is a critical component in modern distributed systems and web architectures. It ensures optimal resource utilization, maximizes throughput,...| Posts on Murat Genc
With the release of .NET 8, developers have access to a powerful new feature called SearchValues. This feature significantly enhances the efficiency of search operations within collections, particularly for large datasets. In this article, we will delve into the details of SearchValues, exploring its functionality, usage, benefits, and practical examples. We will also include benchmarks to demonstrate its performance improvements. What is SearchValues? SearchValues is a new API introduced in .| Posts on Murat Genc
Multitasking is a crucial feature of modern operating systems, allowing them to execute multiple tasks (processes) concurrently. There are two primary types of multitasking: non-cooperative (preemptive) multitasking and cooperative multitasking. Understanding the distinctions between these approaches is critical for designing and optimizing software systems. Non-Cooperative (Preemptive) Multitasking Definition: Non-cooperative multitasking, also known as preemptive multitasking, is a system w...| Posts on Murat Genc
In .NET, one of the important features for performance and memory management is ReadOnlySpan<T>. In this article, we will explore what ReadOnlySpan<T> is, how to use it, and its technical details. Additionally, we will look at how it translates to IL code and compare it to other collection types. What is ReadOnlySpan<T>? ReadOnlySpan<T> is a type introduced in .NET Core 2.1 that provides a type-safe and memory-safe representation of a contiguous region of arbitrary memory.| Posts on Murat Genc
The Reactor-Executor pattern is a powerful architectural approach for building highly scalable and responsive concurrent applications. It separates the concerns of event demultiplexing and event handling, enhancing both scalability and manageability. This article explores the pattern in depth, discussing its components, benefits, and implementation details. We’ll provide examples in Rust to illustrate its practical application. Understanding the Reactor-Executor Pattern Reactor Pattern The ...| Posts on Murat Genc
Introduction In Rust, asynchronous programming leverages futures, which are essentially stackless coroutines. Unlike stackful coroutines that maintain their own stack, stackless coroutines rely on the compiler and runtime to manage state and execution. This approach allows for highly efficient and safe concurrency. This article provides an in-depth technical explanation of how futures work in Rust, focusing on the underlying mechanics and the role of the Rust compiler. High-Level Introduction...| Posts on Murat Genc
In the world of computer science and software development, optimizing the performance and responsiveness of applications is crucial. Two key techniques that developers use to achieve these goals are asynchronous programming and parallel programming. Both approaches allow programs to handle multiple tasks efficiently but in different ways. Understanding the fundamental concepts, use cases, and differences between these techniques is essential for leveraging them effectively in your projects. A...| Posts on Murat Genc
Performance Rust is a compiled language offering performance comparable to C and C++. This makes it highly suitable for data analysis and statistics, where large datasets and complex computations are common. Its ability to process data faster and more efficiently than interpreted languages like Python is a significant advantage. Memory Safety Rust’s ownership system and strong type system ensure memory safety at compile time, preventing common bugs such as data races, null pointer dereferen...| Posts on Murat Genc
Efficient resource management is pivotal in systems programming, where the reliability and performance of applications heavily depend on the meticulous management of resources. Rust’s Drop trait provides a sophisticated mechanism for deterministic resource handling, markedly enhancing the predictability and efficiency of resource management over traditional methods like garbage collection (GC) and manual resource management. The Challenge of Resource Management Resources such as memory, fil...| Posts on Murat Genc
Function pointers are a powerful feature in Rust, enabling developers to dynamically manage and manipulate references to functions, fostering customizable behaviors and efficient complex design patterns. This guide dives into their practical applications, syntax, advanced use cases, and best practices, and it compares them with closures and trait objects. Type Safety and Performance: A Balancing Act Rust is a language that does not compromise on safety or performance, and function pointers ar...| Posts on Murat Genc
In Rust, lifetime specifiers are crucial for managing references and ensuring that data referenced by a pointer isn’t deallocated as long as it’s needed. Lifetime specifiers aid Rust’s borrow checker in ensuring memory safety by explicitly defining how long references within structs, enums, or functions are valid. This is especially important when dealing with non-‘static lifetimes, or data that might not live for the entire duration of the program. Below, I’ll explain how you can a...| Posts on Murat Genc
Problem: Once upon a time, there was a large toy factory that produced various types of toys. The factory manager wanted to make the production process of different types of toys more efficient. Setting up separate production lines for each type of toy was both costly and time-consuming. The manager aimed to increase the factory’s capacity and produce innovative toys by standardizing production processes and entering new markets. Solution: The manager decided to solve this problem by creati...| Posts on Murat Genc
In the Rust programming language, iterators are structures used to traverse and perform operations on collections. They provide a way to access elements of data collections and manipulate them while adhering to Rust’s strict ownership and borrowing rules, ensuring safe and efficient usage. Defining and Using Iterators The basic way to utilize an iterator is through the .iter(), .iter_mut(), and .into_iter() methods, which differ based on the ownership status of the collection:| Posts on Murat Genc
Rust Macros and Compile-Time Metaprogramming: A Deep Dive Introduction Hello Rust enthusiasts! Today, we’re going to explore one of Rust’s most powerful features—macros and compile-time metaprogramming. These capabilities empower Rust to be both powerful and flexible, enabling you to make your code cleaner, safer, and more reusable. Let’s dive in! Understanding Rust Macros and Their Basic Structure In Rust, macros are powerful tools for reusing code. There are two main types: Declarat...| Posts on Murat Genc
Rust, a modern and safe programming language, is rapidly gaining popularity in the software development world. One of the most important features of Rust is its focus on modularity and reusability. This is achieved through a concept called “crates.” In this article, we will take a detailed look at what crates are in Rust, how they are used, and why they are important. What is a Crate? Simply put, a crate is the fundamental building block of a Rust project.| Posts on Murat Genc
Rust programlama dilinde enum ve pattern matching özellikleri, tip güvenliği ve kod okunabilirliği için oldukça önemli ve güçlüdür. enum (enumerasyonlar), farklı varyantları (variant) olan bir türü temsil eder. pattern matching ise, bu varyantları kolayca ve güvenli bir şekilde ele almanıza olanak tanır. Enum Nedir? enum keyword’ü ile bir enumerasyon oluşturabilirsiniz. Her bir “varyant” farklı bir olası değeri temsil eder. enum Renk { Kirmizi, Yesil, Mavi, } Bu...| Posts on Murat Genc
Merhaba arkadaşlar! Bu yazıda, Rust’ın unsafe özelliğini ele alacağız. Rust, hatasız bir yazılım geliştirme deneyimi sağlamak için pek çok kısıtlama getirir. Ancak bazen, bu kısıtlamaların ötesine geçmek ve sistem seviyesinde daha fazla kontrol sahibi olmak gerekebilir. İşte tam da bu durumlarda, Rust’ın bize sunduğu “unsafe” kelimesini kullanıyoruz. Bu konu biraz kafa karıştırıcı olabilir, bu yüzden adım adım ilerleyelim. Unsafe Rust: Nedir ve Neden ...| Posts on Murat Genc
Rust programlama dilinde, bellek güvenliğini sağlamak için bir dizi özellik bulunur. Ancak, bazen daha düşük seviye işlemlere ihtiyaç duyabiliriz. Bu durumda “Raw Pointers” devreye girer. Bu makalede, Rust’taki Raw Pointers hakkında detaylı bir şekilde konuşacağız. Raw Pointers Nedir? Raw pointers, Rust dilinde bellek güvenliği denetimlerinden muaf olan bir pointer türüdür. Rust, bellek güvenliğini sağlamak için kullanılan Box, Rc, & ve &mut gibi bir dizi point...| Posts on Murat Genc
Among the many features offered by the Rust language, the “Box” type is one of the most significant. It allows objects with memory limitations on the stack to be stored dynamically on the heap. In this article, we will examine the Box type of the Rust language in detail and compare its features with the C#, Go, and Java languages. The Box Type in Rust In the Rust language, the Boxtype is used when data needs to be stored in memory allocated on the heap.| Posts on Murat Genc
The Uniqueness of the Rust Programming Language Rust is a modern systems programming language that aims to offer memory safety, concurrency, and high performance together. One of the most significant features of Rust is its memory management model. This model is based on the concepts of “ownership” and “borrowing”. The Importance of Ownership and Borrowing Concepts Ownership and Borrowing are the cornerstones of Rust’s memory management model. These concepts enable Rust’s memory s...| Posts on Murat Genc
Hello! If you are interested in the Rust programming language, you have probably encountered the Option type, which is quite important for you. This type is one of the standard solutions that Rust provides for error handling and managing values that could be null. What is the Option Type? Rust uses the Option<T> type to manage null values or non-primitive values. This is perfect for marking situations where a specific value T could exist or might not exist.| Posts on Murat Genc
1. Introduction: Definition and Use Cases of the Transactional Outbox Pattern The Transactional Outbox Pattern is a design model that enables reliable communication between microservices. This model allows a microservice to perform database operations and send messages outwards within the same transaction. As a result, either both operations succeed or both fail, ensuring data consistency. The key components of this model are an “Outbox” table and a “Publisher” service. When a transac...| Posts on Murat Genc
Once upon a time, there was a tree in a forest. This tree was a complex structure with leaves and branches. Each branch could have smaller branches and leaves on it. The tree worked as a whole, holding its branches and leaves together. This tree is an example of the Composite design pattern. The tree (Composite) contains two types of components: branches (also Composite) and leaves (Leaf). Both branches and leaves implement the same interface (Component) recognized by the tree.| Posts on Murat Genc
Once upon a time, there were two kingdoms. Despite being very close to each other, a wide and deep river was located between them. This river made it difficult for the kingdoms to interact with each other. To solve this situation, both kingdoms decided to build a bridge. This bridge became an interface that facilitated communication between the two kingdoms. However, the bridge had different structures and features on each side.| Posts on Murat Genc
The Anemic Domain Model is a software design pattern where most of the domain logic is found in services and data transfer objects, often obscuring functionality and behavior, and is typically used for data transmission only. This term was first defined by Martin Fowler as a negative example of a design pattern. A typical example relies on the ability of objects to store data, but the business logic resides in services and other external resources.| Posts on Murat Genc
Once upon a time, there was an object named “Component”. This object was used to perform a specific function. However, sometimes it was necessary to extend or modify this function. That’s where “Decorators” came into play. Decorators are objects that “decorate” or extend the Component. A Decorator comes on top of a Component and extends or modifies its function. This is used to extend the functionality of the Component without changing it itself.| Posts on Murat Genc
Once upon a time, there were two friends from two different worlds: the Electric Vacuum Cleaner and the Electric Outlet. The Electric Vacuum Cleaner needed energy and wanted to get this energy from the Electric Outlet. However, there was a problem. The plug of the Electric Vacuum Cleaner did not fit the Electric Outlet. They were both produced in different standards and could not communicate directly with each other. In this case, a hero emerged: the Adapter.| Posts on Murat Genc
Murat: The Transaction Script pattern allows transactions to be carried out simply and smoothly. However, using this pattern can make understanding and maintaining the code difficult for applications with complex business logic. Epictetus: Yes, Murat. But we must not forget that everything depends on complexity. The Transaction Script pattern can be an excellent choice for applications with simple business logic. However, as the business logic becomes more complex and requires many transactio...| Posts on Murat Genc
The Transaction Script is an Enterprise application design pattern often used in transaction-based systems. This pattern is created by bringing together a series of procedures to perform a transaction. These procedures are typically used to initiate a transaction, run database queries, and process the results. The Transaction Script pattern is suitable for applications with non-complex business logic. However, as the business logic becomes more complex and requires many transactions, using th...| Posts on Murat Genc
Overview The SemaphoreSlim class is a structure used in C# to control one or more threads using a specific resource or operation concurrently. SemaphoreSlim limits the number of threads that can access the resource at the same time. The use of SemaphoreSlim is often used to prevent deadlock situations in multi-threaded applications and to ensure that a specific resource is used by only one or more threads at the same time.| Posts on Murat Genc
Once upon a time, there was a ruler in the Singular Realm. The ruler’s name was “Singleton”, and he had the property of being the only entity in the whole realm. Singleton had educated everyone else about preserving his uniqueness and singularity. Being the sole ruler of his kingdom, Singleton was recognized with the property of being a unique entity that, once created, could not be changed again. In every corner of the kingdom, it was known that Singleton was created only once and only...| Posts on Murat Genc
Once upon a time, there was a kingdom, and the name of this kingdom was “Abstract Factory”. Although it seemed abstract, everything in this kingdom had a purpose, a certain order, and a specific design. There were certain rules on how everything was made, and these rules were based on design patterns that regulated the creation of objects. In the kingdom of Abstract Factory, the King, known as AbstractFactory, would manage the factories of different types of products.| Posts on Murat Genc
Once upon a time, there was a very beautiful kingdom, and its name was “Builder Pattern”. Everything in this kingdom was about the art of constructing complex objects step by step and connecting them together. These complex objects were the most valuable treasures of the kingdom, and each one was carefully and thoughtfully constructed. The wisest person in the kingdom was this master named the Builder. The Builder would construct complex objects using materials like stones, bricks, and wood.| Posts on Murat Genc
Once upon a time, there was a magical kingdom, and its name was “Factory Method”. This kingdom was a place that controlled the creation of objects. The wisest ruler of the kingdom believed that the creation of objects had its own special ways, and this was part of his rule. The ruler had a princess, and her name was “Creator”. Creator used her magical powers every day to create a new object.| Posts on Murat Genc
Once upon a time, there was a place called the Land of Creators. In this land, there was a secret to creating new objects quickly and efficiently. This secret was called the “Prototype Pattern”. One day in the Land of Creators, there was a magical drawing pen. This pen had the ability to copy any object it touched. This feature made the creation of objects easy and fast, because instead of creating each object from scratch, an existing object was being copied.| Posts on Murat Genc
When working with databases, it is of great importance to properly manage concurrent operations and ensure data integrity. Concurrency control is used to manage multiple users or processes accessing the same data concurrently. In this article, we will explore how to ensure data integrity using LINQ (Language Integrated Query) with optimistic concurrency. What is Optimistic Concurrency? Optimistic concurrency is a method where resources are not locked when a transaction begins, but changes are...| Posts on Murat Genc
When working with databases, managing concurrent operations and ensuring data integrity are of great importance. Concurrency control is used to manage multiple users or processes accessing the same data concurrently. In this article, we will explore how to use LINQ (Language Integrated Query) with pessimistic concurrency to maintain data integrity. What is Pessimistic Concurrency? Pessimistic concurrency is based on the principle of locking the relevant data when a transaction begins and main...| Posts on Murat Genc
In another corner of the Land of Computers, in the City of Microservices, there was another world where all microservices moved according to a specific symphony. In this world, all microservices were governed by a single orchestra conductor, and this management model was called “Orchestration-Based Saga.” This resembled a music performance in a grand orchestra. Just as an orchestra conductor tells all musicians when and which notes to play, in this world, the Orchestra Conductor Microserv...| Posts on Murat Genc
In another corner of the Land of Computers, in the City of Microservices, there was another world where all microservices moved according to a specific symphony. In this world, all microservices were managed by a single orchestra conductor, and this management model was called “Orchestration-Based Saga.” It was akin to a music performance in a grand orchestra. Just as an orchestra conductor tells all musicians when to play which notes, here the Orchestra Conductor Microservice determined ...| Posts on Murat Genc
Bilgisayarlar Diyarı’nın bir başka köşesinde, Mikroservisler Şehri’nde, her mikroservisin kendi veritabanına sahip olduğu farklı bir dünya vardı. Bu model, “Her Servis için Veritabanı” olarak adlandırılmıştı. Bu dünyada, her mikroservis kendi hazine sandığına, yani kendi veritabanına sahipti. Bu sandıklar, her bir mikroservisin ihtiyaç duyduğu verileri içerirdi ve sadece ilgili mikroservis tarafından erişilebilirdi. Tıpkı bir masal kahramanının kendi h...| Posts on Murat Genc
Hoş geldin, maceracı arkadaşım! Bugün seni fantastik bir yolculuğa çıkaracağım. Bilgi Krallığı’nın hikayeler, bilgiler ve bulmacalarla dolu derinliklerine doğru büyülü bir seyahat, tam da senin gibi bir kod yazarı kahramanı için! Adımlarımızı Saga Pattern’ın büyülü dünyasına doğru yönlendireceğiz. Peki, bavulunu hazırladın mı? O zaman yola koyulalım! Saga Pattern’ın Destansı Kökenleri Bir hikayeye başlamadan önce, tıpkı saga yazarlarının ya...| Posts on Murat Genc
Uzun zamandır düşündüğüm ama bir türlü hayata geçiremediğim ilginç (en azından benim için) bir seriye başlamak istiyorum. Bildiğim, özümsediğim kadarı ile tarihi filozoflar ile teknolojik konularda onların kendi ideolojileri bağlamında diyaloglara girmek. Bunun içinde ilk kavram olarak mikroservis konusunu seçtim. Bakalım filozoflarımız bu konu hakkında neler konuşacak.| Posts on Murat Genc
HTTP isteklerini izlemek ve teşhis etmek için daha fazla yetenek ekleyerek, kütüphanemizi daha da geliştirebiliriz. Bu amaçla, isteklerin ve yanıtların bazı temel bilgilerini loga kaydeden bir middleware ekleyelim. Bu özellik, HTTP isteklerinin ve yanıtlarının kaydını tutmak için HttpClient‘in DelegatingHandler sınıfını kullanır. Bu, bir HTTP isteği gönderildiğinde ve bir yanıt alındığında çalışan bir kod parçasıdır. Bu durumda, HTTP isteklerinin ve yanıt...| Posts on Murat Genc
Bu noktada, geliştirmemiz gereken bir diğer önemli konu da güvenlikle ilgili olabilir. Özellikle, API çağrıları genellikle belirli bir kimlik doğrulama yöntemi gerektirir. Bunu sağlamak için, HTTP istemcimizi çok kullanılan iki kimlik doğrulama yöntemiyle, yani Basic Authentication ve Bearer (Token) Authentication ile uyumlu hale getirebiliriz. Bu amaçla, istemcimize iki yeni metot ekleyelim: public void SetBasicAuthentication(string username, string password) { var basicAut...| Posts on Murat Genc
Birkaç özelleştirilebilir başlık ayarlama yeteneği ekleyelim. Bu özellik, belirli bir istek için özel HTTP başlıkları ayarlamayı kolaylaştıracaktır. using Newtonsoft.Json; using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class MyHttpClient : IDisposable { private readonly HttpClient...| Posts on Murat Genc
HTTP yanıtının durum kodlarını kontrol edebilme yeteneğini ekleyelim. Bu özellik, HTTP isteğinin başarılı olup olmadığını veya belirli bir hata durumunu gösterip göstermediğini belirlememize olanak sağlar. using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class MyHttpClient : IDis...| Posts on Murat Genc
Daha fazla işlevsellik eklemek için, hata günlüğü ve otomatik hata izleme ekleyebiliriz. Bu, hataların daha kolay izlenmesine ve işlenmesine olanak sağlar. Bunun için, ILogger arabirimi kullanılarak hataların kaydedilmesini sağlayabiliriz. using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; publ...| Posts on Murat Genc
Bir sonraki adımda, HTTP istemci sınıfımızda önbellekleme ve otomatik yeniden deneme gibi özellikler ekleyebiliriz. Bu özellikler, API isteklerini daha verimli ve dayanıklı hale getirir. Bu geliştirmeleri yapmak için, Polly adlı bir kütüphaneyi kullanacağız. using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class MyHt...| Posts on Murat Genc
Geliştirme vakti BaseAddress özelliği, zaman aşımı süresini ayarlamak ve özelleştirilebilir bir HttpMessageHandler ekleyelim. Ayrıca, bu sınıf artık bir Authorization header ı alabilsin. using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class MyHttpClient : IDisposable { private readonly HttpClient _client; public MyHttpClient(HttpClient client, string baseAddress, TimeSpan? timeout = null, HttpMessageH...| Posts on Murat Genc
Bu versiyonda, bir dizi başlık bilgisi, özelleştirilmiş zaman aşımı süresi ve daha fazla hata kontrolü ekleyelim: using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class MyHttpClient : IDisposable { private readonly HttpClient _client; public MyHttpClient(TimeSpan? timeout = null) { _client = new HttpClient(); if (timeout.HasValue) { _client.Timeout = timeout.Value; } } private HttpRequestMessage CreateRequ...| Posts on Murat Genc
Şimdiye kadar, mock nesnesinin belirli bir metodu çağırıldığında belirli bir sonuç döndürmesini, bir dizi sonuç döndürmesini veya bir hata fırlatmasını ayarlayabiliyoruz. Ancak, bazen bir metodu çağırıldığında belirli bir eylemi gerçekleştirmesini isteyebiliriz. Bu, genellikle “Callback” olarak adlandırılır. Bu özellik, bir metot çağrıldığında gerçekleşecek bir eylemi ayarlamak için kullanılabilir. Bu eylem, bir metot çağrıldığında herhangi bi...| Posts on Murat Genc
Şu anda, bizim Mock sınıfımızda bir metodun belirli bir sonucu döndürmesini veya bir dizi sonuç döndürmesini ayarlayabiliyoruz. Ancak, belirli bir durumda bir metot çağrıldığında bir hata fırlatmasını isteyebiliriz. Bu, genellikle “Throws” olarak adlandırılır. using System; using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; using System.Collections.Generic; public class Mock<T> : DispatchProxy { private ConcurrentDictionary<s...| Posts on Murat Genc
Mocklama kütüphanemizi daha da geliştirelim. Şu anda, bir metodun belirli parametrelerle çağrılmasını ve belirli bir sonuç döndürmesini bekliyoruz. Ancak, bazen belirli bir parametre türüne sahip bir metodu çağrıldığında belirli bir sonuç döndürmesini isteyebiliriz, parametrenin kendisinin ne olduğu önemli olmayabilir. Bu özellik, genellikle mocklama kütüphanelerinde “It.IsAny” olarak adlandırılır. Ayrıca, bir mock nesnesinin bir metodu birden fazla kez ça...| Posts on Murat Genc
Bu sefer belirli parametrelerle çağrılan metotları simüle edeceğiz ve geri dönüş değerini ayarlayabileceğiz. Ayrıca, belirli bir metot çağrısını doğrulayabileceğiz. using System; using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; public class Mock<T> : DispatchProxy { private ConcurrentDictionary<string, object> _methodResponses = new(); private ConcurrentDictionary<string, int> _methodCalls = new(); protected override object Invoke...| Posts on Murat Genc
Artık interface lerle çalışalım. Öncelikle, System.Reflection.DispatchProxy‘yi kullanacağız. Bu, bir proxy sınıfı oluşturmanıza ve ona method çağrılarını yönlendirmenize olanak sağlar. DispatchProxy‘yi kullanarak belirli bir arayüzün metotlarını mocklayalım. using System; using System.Collections.Generic; using System.Reflection; public class Mock<T> : DispatchProxy { private readonly Dictionary<string, object> _methodResponses = new(); protected override object I...| Posts on Murat Genc
Mocklama, testlerinizde belirli sınıfların veya metodların davranışlarını taklit etmek için kullanılır. Örneğin, bir veritabanı çağrısı yapmak yerine, bir mock veritabanı çağrısını simüle edebilirsiniz. Bu, testlerin daha hızlı çalışmasını sağlar ve testlerin bağımlılıklarını azaltır. .NET’de birçok popüler mock kütüphanesi varken neden böyle bir şey yapalım ki. Sadece nasıl çalıştığını anlamak ve biraz pratik yapmak. Ve başlayalım us...| Posts on Murat Genc
Testlerin belirli bir süre sınırlamasına tabi olması önemlidir. Bazı testlerin beklenenden daha uzun sürmesi veya sonsuz bir döngüye girmesi durumunda, süre sınırlaması olan bir test, bu tür sorunları belirlemeyi ve test sürecini düzgün bir şekilde yönetmeyi kolaylaştırır. Her test için bir süre sınırlaması ayarlamak için TestRunner‘ı güncelleyelim: using System; using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Thread...| Posts on Murat Genc
Test raporlama, testlerin sonuçlarını görselleştirmek ve anlamak için önemlidir. Testlerin sonuçlarını almak ve bunları daha anlamlı bir formatta raporlamak için bir özellik ekleyebiliriz. Basit bir test raporlama özelliği, testlerin adlarını, testlerin ne kadar sürede tamamlandığını ve hangi testlerin başarılı olduğunu veya başarısız olduğunu içerebilir. TestRunner‘ı geliştirelim: using System; using System.Reflection; using System.Collections.Generic; usi...| Posts on Murat Genc
Testlerin birbirinden izole olması önemlidir, çünkü bir testin durumu başka bir testi etkilememelidir. Bunun için, her bir test metodu çalıştırıldığında, test sınıfının yeni bir örneğini oluşturabiliriz. Bu, her bir testin kendi durumunu korumasını sağlar ve testler arasında durum paylaşımını önler. Aşağıda, bu özelliği eklemek için TestRunner‘ı güncelleyelim: using System; using System.Reflection; using System.Collections.Generic; using System.Linq; u...| Posts on Murat Genc
Özellikle I/O yoğun işlemler veya işlemlerin paralel olarak yürütülmesi gereken durumlar için önemlidir. Asenkron testler, testlerin tamamlanmasını beklemek için Task veya Task<T> döndürürler. Örneğin, bir HTTP isteği gönderme veya bir veritabanı sorgusu çalıştırma gibi bir işlemi test etmek isteyebilirsiniz. Bu tür işlemler genellikle asenkron olarak gerçekleştirilir, çünkü bu işlemler genellikle bloklama yapar ve programın diğer işlemlerini engeller. Asen...| Posts on Murat Genc
Testlerin daha iyi organize edilmesine ve belirli test gruplarının seçilerek çalıştırılabilmesini istesek ne yaparız. Testleri belirli grup veya kategori halinde düzenlesek? Bu özelliği eklemek için, bir TestSuiteAttribute oluşturabiliriz. Bu attribute, bir test sınıfına veya test metoduna uygulanabilir. Ayrıca, TestRunner‘ı güncelleyerek, belirli bir test grubu için testleri çalıştırabiliriz. using System; using System.Reflection; using System.Collections.Generic; ...| Posts on Murat Genc
Genellikle bir test framework’ünde “Parameterized Tests” veya “Data-Driven Tests” adı verilen bir özellik kullanılır. Bu özellik, bir test metodunun farklı veri setleriyle birden çok kez çalıştırılmasını sağlar. Bizde bu özelliği ekleyelim. Aşağıda, TestCase adında bir attribute ve TestRunner‘da bu attribute’u işleyecek kodu tanımlayalım, bu sayede TestRunner ıda refactor edelim. using System; using System.Reflection; using System.Collections.Generic; u...| Posts on Murat Genc
Assert sınıfına HasElements işlevini ekleyelim. Bu işlev, bir koleksiyonun belirli öğelere sahip olup olmadığını kontrol eder. using System; using System.Collections.Generic; using System.Linq; using System.Threading; // ... önceki exception sınıfları ... public class AssertHasElementsFailedException : AssertFailedException { public AssertHasElementsFailedException(IEnumerable<object> missingElements) : base($"Expected collection to contain {string.Join(", ", missingElements)},...| Posts on Murat Genc
Şimdi, IsSameAs ve IsNotSameAs işlevlerini ekleyelim. Bu işlevler, iki nesnenin aynı referansa sahip olup olmadığını kontrol eder. using System; using System.Collections.Generic; using System.Linq; using System.Threading; // ... önceki exception sınıfları ... public class AssertIsSameAsFailedException : AssertFailedException { public AssertIsSameAsFailedException(object value, object other) : base($"Expected {value} to be the same as {other}, but it was not.") { } } public class A...| Posts on Murat Genc
Bu sefer Assert sınıfına IsEmpty ve IsNotEmpty işlevlerini ekleyelim. Bu işlevler sayesinde, bir koleksiyonun boş olup olmadığını kontrol edebiliriz. using System; using System.Collections.Generic; using System.Linq; using System.Threading; // ... önceki exception sınıfları ... public class AssertIsEmptyFailedException : AssertFailedException { public AssertIsEmptyFailedException() : base("Expected collection to be empty, but it was not.") { } } public class AssertIsNotEmptyFail...| Posts on Murat Genc
Evet, Assert sınıfımıza IsInstanceOfType ve IsNotInstanceOfType işlevlerini ekleyelim. Bu işlevler, bir nesnenin belirli bir türden olup olmadığını kontrol eder. Ayrıca, her biri için özel hata türleri oluşturalım. using System; using System.Collections.Generic; using System.Linq; using System.Threading; // ... önceki exception sınıfları ... public class AssertIsInstanceOfTypeFailedException : AssertFailedException { public AssertIsInstanceOfTypeFailedException(object val...| Posts on Murat Genc
Bu sefer, ‘Assert’ sınıfına ‘LessThan’, ‘LessThanOrEqual’, ‘GreaterThan’, ve ‘GreaterThanOrEqual’ işlevleri ekleyelim. Bu işlevler sayesinde, iki değerin birbirine göre sıralamasını kontrol edebiliriz. Ayrıca, her biri için özel hata türleri oluşturalım. using System; using System.Collections.Generic; using System.Linq; using System.Threading; // ... önceki exception sınıfları ... public class AssertLessThanFailedException : AssertFailedException { publ...| Posts on Murat Genc
Assert sınıfını daha da geliştirelim. Şimdi, özel hata mesajları içeren Assert hata türleri ekleyelim. Bu, hataları daha iyi yönetmeyi ve test hatalarını daha iyi tanımlamayı sağlayacaktır. using System; using System.Collections.Generic; using System.Linq; using System.Threading; public class AssertFailedException : Exception { public AssertFailedException(string message) : base(message) { } } public class AssertEqualFailedException : AssertFailedException { public AssertEqu...| Posts on Murat Genc
Assert sınıfımıza daha fazla method ekleyelim. using System; namespace SimpleTestFramework { public class Assert { public static void Equal(object expected, object actual, string message = null) { if (!expected.Equals(actual)) { throw new Exception(message ?? $"Expected {expected}, but got {actual}"); } } public static void True(bool condition, string message = null) { if (!condition) { throw new Exception(message ?? "Expected condition to be true, but was false."); } } public static void...| Posts on Murat Genc
Basit test framework’ümüze birkaç özellik ekleyelim. SetUp ve TearDown metodları, bu metodlar, her test öncesi ve sonrası çalışır ve testler arasında tekrar eden kodu azaltmaya yardımcı olabilir. using System; namespace SimpleTestFramework { public class TestAttribute : Attribute { } public class SetUpAttribute : Attribute { } public class TearDownAttribute : Attribute { } public class Assert { public static void Equal(object expected, object actual) { if (!expected.Equals(act...| Posts on Murat Genc
Unit test yazarken genellikle NUnit veya XUnit gibi mevcut unit test framework’leri kullanılırız. Ancak, eğer basit bir unit test framework’ü kendimiz yazmak istersek, nasıl yaparız?. Ve başlayalım. Tek bir assert methodumuz ve runner ımızla başlangıcı yapalım. using System; namespace SimpleTestFramework { public class TestAttribute : Attribute { } public class Assert { public static void Equal(object expected, object actual) { if (!expected.Equals(actual)) { throw new Exce...| Posts on Murat Genc
Daha önce çalıştığımız reflection makalelerini kullanarak, .NET 6 ile AutoMapper benzeri bir yapıda mapping uygulamasını reflection ve IL emit kullanarak performanslı olacak şekilde yazalım. Mapping API’sini oluşturmak için, MyMappingLibrary projesine IMapper adında bir arayüz ve Mapper adında bir sınıf ekleyin. IMapper.cs public interface IMapper { TDestination Map<TSource, TDestination>(TSource source); void CreateMap<TSource, TDestination>(); } Mapper.cs using System...| Posts on Murat Genc
Veritabanları ile çalışırken, eşzamanlı transactionların doğru bir şekilde yönetilmesi ve veri bütünlüğünün korunması büyük önem taşır. LINQ (Language Integrated Query) ile veritabanı işlemlerinde transactionlar (transactions) kullanarak çakışmaların nasıl çözüleceği konusunda örnekler ve ve öneriler gösterilecektir. Transactionlar (Transactions) Nedir? Transactionlar, veritabanı üzerinde gerçekleştirilen bir dizi işlemi gruplayan ve bu işlemlerin ta...| Posts on Murat Genc
Reflection, .NET’te çalışma zamanında tür bilgilerini keşfetmek ve işlem yapmak için kullanılabilen güçlü bir özelliktir. Bu makalede, Reflection Emit ve dinamik kod oluşturma, ileri düzey kavramlar ve gerçek dünya örnekleri ve uygulamaları ele alacağız. Reflection Emit ve Dinamik Kod Oluşturma Reflection Emit, çalışma zamanında dinamik olarak yeni türler, yöntemler ve özellikler oluşturmanıza olanak tanır. Bu, türlerin yapılarını ve işlevselliğini derl...| Posts on Murat Genc
Reflection, .NET’te çalışma zamanında tür bilgilerini keşfetmek ve işlem yapmak için kullanılabilen güçlü bir özelliktir. Bununla birlikte, Reflection’ın performans etkileri de göz önünde bulundurulmalıdır. Bu makalede, Reflection kullanımının performans etkilerini, performansı artırmak için önerileri ve yöntemleri ve Reflection yerine kullanılabilen alternatif teknolojileri ve uygulamaları ele alacağız. Reflection Kullanımının Performans Etkileri Reflect...| Posts on Murat Genc
Reflection, çalışma zamanında extension metodlar ve özel durumlarla işlem yapmak için kullanılabilir. Bu makalede, Reflection ile extension metodları ve özel durumları nasıl kullanabileceğinizi inceleyeceğiz. Extension Metodlarla Çalışma Extension Metodları Bulma Belirli bir tür için extension metodları bulmak için, derlemedeki tüm türleri inceleyin ve ‘MethodInfo.IsDefined()’ ile ‘ExtensionAttribute’ kontrolünü kullanarak extension metodları filtreleyin. Ty...| Posts on Murat Genc
Reflection, çalışma zamanında olaylar (events) ve delegelerle işlem yapmak için kullanılabilir. Bu makalede, Reflection ile olaylar ve delegeleri nasıl kullanabileceğinizi inceleyeceğiz. Olaylarla (Events) Çalışma Olayları Elde Etme Belirli bir türün olaylarını elde etmek için, ‘Type.GetEvent()’ ve ‘Type.GetEvents()’ metodlarını kullanabilirsiniz. Type myType = typeof(MyClass); EventInfo myEvent = myType.GetEvent("MyEvent"); EventInfo[] events = myType.GetEvents()...| Posts on Murat Genc
Mikroservis mimarileri, modern uygulamaların ölçeklenebilirlik, esneklik ve performans gereksinimlerini karşılamak için giderek daha yaygın hale geliyor. CAP ve PACELC teoremleri, mikroservis mimarilerinin temel prensiplerini anlamak ve uygulamak için önemli kavramlardır. Bu makalede, CAP ve PACELC teoremlerinin mikroservis mimarilerinde nasıl kullanıldığına dair örnekler ve şekiller sunacağız. CAP Teoremi ve Mikroservisler CAP teoremi, dağıtık sistemlerde Tutarlılık (...| Posts on Murat Genc
Memory safety is a cornerstone of Zig’s design philosophy. While maintaining the performance benefits of manual memory management, Zig incorporates sophis| Murat Genc