C# 6.0 Null Kontrolü

tip

Bir nesnenin özelliklerine ya da metotlarına erişmeden önce, nesne değerinin null olup olmadığının kontrol edilmesi gerekmektedir. Aksi halde NullReferenceException hatası fırlatılır.

Örneğin, str adı tanımlanmış bir string nesnesinin uzunluğu alınmak isteniyor. Uzunluk alınmadan önce ilk olarak str değerinin null olup olmadığının kontrol edilmesi gerekiyor. C# 6.0 ile beraber, bu kontrol aşağıdaki gibi ?. operatörü ile yapılabilir.

var length = str?.Length;

İşlem sonunda, eğer str değeri null ise, null değeri döndürülür. Aksi halde string uzunluğu elde edilir.

Etiketler:  C#

Generic Singleton Pattern & C#

Generic Singleton pattern with C# and .NET 4 (or higher)

// T is a class and must have a public default constructor.

public sealed class Singleton<T> where T : class, new()
{
    private static readonly Lazy<T> instance = new Lazy<T>(() => new T());
        
    public static T Instance
    {
        get
        {
            return instance.Value;
        }
    }

    private Singleton() { }
}

Usage:

var myClass = Singleton<MyClass>.Instance;
Etiketler:  C#

.NET Proje - Website Health Monitoring

Website Health Monitoring sistemleri, web sitesinin çalışır durumda olup olmadığını, veritabanı bağlantısı, e-posta gönderimi gibi işlemlerin sorunsuz bir şekilde yapılıp yapılmadığını düzenli aralıklarla kontrol eden ve sorun tespit etmesi durumunda, ilgili kişileri uyaran sistemlerdir.

Proje ile, birçok web uygulamasını aynı anda kontrol eden, sonuçlara İnternet tarayıcısı ya da mobil uygulama üzerinden erişebileceğimiz, bulut üzerinden çalışan bir .NET uygulaması hazırlanması amaçlanmıştır.

Website Health Monitoring

Projede bileşenleri ve kullanılacak teknolojiler aşağıdaki gibidir:

ASP.NET MVC Web Uygulaması

Kontrol edilecek web sitelerini kaydetmek ve monitör edilen web sitelerinin raporlarına erişmek için hazırlanacak web uygulaması

Apache Cordova Mobil Uygulaması

Monitör raporlarına mobil cihazlar üzerinden erişmek ve sorunlar hakkında anlık uyarılar almak için hazırlanacak mobil uygulama

Windows Service

Web sitesi kontrol işlemlerinin, belirli aralıklarla otomatik olarak yapılması ve sorun tespiti sırasında yetkililerin uyarılması için hazırlanacak Windows servisi

SQL Server

Web sitesi verilerinin ve kontrol sonuçlarının tutulacağı veritabanı

LINQ to SQL

Veritanını üzerinde sorgulamalar yapma ve verileri yönetmek için kullanacağımız .NET bileşeni

SMTP

Sorunları web sitesi sahibi yetkililere bildirmek için kullanılacak, elektronik posta gönderme protokolü

C#, HTML, CSS

Uygulama C# ile yazılacaktır. Ekranlar için HTML ve CSS konuları konusunda bilgi sahibi olmak gerekecektir.

Julia Fraktal Çizimi & C#

Fraktal; matematikte, çoğunlukla kendine benzeme özelliği gösteren karmaşık geometrik şekillerin ortak adıdır. En bilinen fraktal kümelerinden birisi olan Julia kümesinin C# ile oluşturulmuş hali aşağıdadır.

julia

using System.Drawing;
using System.Numerics;

namespace SG.Algoritma
{
    public class JuliaFractal
    {
        // Julia kümesinde, yarıçağı 2'den büyük her karmaşık sayı çemberi sonsuza götürmektedir.
        private const int MaxMagnitude = 2;

        // Maksimum iterasyon sayısı
        private const int MaxIterations = 1000;

        // Karmaşık sayı koordinat sisteminde, Julia kümesinin bölgesi.
        // Julia kümesinin sadece bir kısmını çizmek için farklı bir bölge verilebilir. 
        private static Complex AreaMin = new Complex(-2, -2);
        private static Complex AreaMax = new Complex(2, 2);

        private Complex C;

        public JuliaFractal(Complex c)
        {
            this.C = c;
        }

        /// <summary>
        /// Julia kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="dimension">Oluşacak imajın genişlik ve yükseklik değeri (Kare imaj oluşturulacak)</param>
        public Bitmap GenerateBitmap(int dimension)
        {
            return this.GenerateBitmap(dimension, JuliaFractal.AreaMin, JuliaFractal.AreaMax);
        }

        /// <summary>
        /// Julia kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="width">Oluşacak imajın genişliği. Yükseklik, çizilmek istenen bölgeyenin genişlik ve yükseklik değerlerine bakılarak belirlenecek.</param>
        /// <param name="areaMin">Karmaşık sayo kooordinat sisteminde, Julia kümesinin sadece belirli bir bölgeye karşılık düşen kısmı çizdirilmek istendiği zaman, bu bölgenin sol alt kösesi</param>
        /// <param name="areaMax">Sağ üst köşe</param>
        public Bitmap GenerateBitmap(int width, Complex areaMin, Complex areaMax)
        {
            var height = (int)(width * (areaMax - areaMin).Imaginary / (areaMax - areaMin).Real);

            // Boş bir bitmap oluştur
            var bitmap = new Bitmap(width, height);

            // Oluşturulacak imajın her piksel değerine karşılık düşen karmaşık sayı oluşturulacak.
            // Oluşturacağımız karmaşık sayıların, seçtiğimiz bölge içerisinde kalması gerekmektedir.

            var rScale = (areaMax - areaMin).Real / width;
            var iScale = (areaMax - areaMin).Imaginary / height;

            for (var x = 0; x < width; x++)
            {
                // Karmaşık sayısının real kısmı
                var real = areaMin.Real + x * rScale;

                for (var y = 0; y < height; y++)
                {
                    // Karmaşık sayısının imaginary kısmı
                    var imaginary = areaMin.Imaginary + y * iScale;

                    // Julia kümesi iterasyon değeri hesaplanıyor.
                    var iteration = this.CalculateIteration(new Complex(real, imaginary));

                    // Iterasyon değerine göre noktanın rengi ayarlanıyor.
                    bitmap.SetPixel(x, y, JuliaFractal.GetColor(iteration));
                }
            }

            return bitmap;
        }

        private int CalculateIteration(Complex z)
        {
            var iteration = 0;

            while (iteration < JuliaFractal.MaxIterations && z.Magnitude < JuliaFractal.MaxMagnitude)
            {
                z = z * z + this.C;
                iteration++;
            }

            return iteration;
        }

        /// <summary>
        /// // Iterasyona karşılık renk seçiliyor.
        /// </summary>
        private static Color GetColor(int iteration)
        {
            // Rasgele bir renk seçiliyor.
            // 256 tane rengin olduğu bir liste oluşturularak, listeden iteration % 256. renk de seçilebilir.
            // Ya da renk oluşturmak için farklı bir yöntem izlenebilir.

            return Color.FromArgb(0, iteration % 256, 0);
        }
    }
}

Julia kümesini fraktal resmini oluşturmak için, ilgili metot aşağıdaki şekilde çağrılabilir. Bu durumda en üstte yer alan resim oluşacaktır.

var fractal = new JuliaFractal(new Complex(0.285, 0.01));
var bitmap = fractal.GenerateBitmap(800);

bitmap.Save(@"D:\julia.png", ImageFormat.Png);

Julia fraktalının sadece belirli bir bölgesini çizdirmek için, ilgili metot aşağıdaki şekilde çağrılabilir. Böylece fraktalın istenilen bölgesi daha detaylı bir şekilde çizdirilebilir.

var bitmap = fractal.GenerateBitmap(800, new Complex(-0.85, 0.1), new Complex(-0.45, 0.37));

julia

Etiketler:  C#

Database Management / Index

Not : Özet bilgi içerir.

Veritabanı verilerin ilişkisel depolandığı alanlardır. Metin, tarih, sayısal değer, resim dosyası vb. farklı veri tipleri veritabanı üzerinde yer alabilir. Veritabanı Yönetim Sistemi (Database Management System DBMS) ise, veritabanlarının oluşturulması ve yönetilmesi için kullanılan sistemlerdir.

Klasik veritabanlarında veriler, B+ ağaçları (B+ tree) üzerinde saklanır. B+ ağaçları, verileri okumak için gerekli olan disk erişim sayısının en aza indirilmek için tercih edilir. B+ ağaçları:

  • Dengeli ağaçlardır. Ağaç üzerindeki tüm yaprak düğümler aynı seviyededir.
  • Her düğümde birden fazla değer saklanır.
  • Tüm değerler, ağacın yaprak düğümleri arasında mutlaka bulunur.

B+ ağacının yaprak düğümleri, bağlantılı liste (linked list) şeklindedir ve tüm değerler yaprak düğümler üzerinde sıralı bir şekilde saklanır.

Örnek bir B+ ağacı aşağıda verilmiştir. (Bu ağaç adresinde yer alan animasyon kullanılarak oluşturulmuştur.)

b plus tree

B+ ağacı üzerinde hangi değerlerin hangi sıra ile tutulacağını, tablolar üzerinde tanımlanmış olan index yapıları belirler.

Clustered Index

Tablo verisinin tutulduğu B+ ağacıdır. Dolayısıyla, bir tablo için sadece bir adet clustered index bulunabilir. Tüm tablo verisi, B+ ağacının yaprak (leaf) düğümleri üzerinde sıralı bir şekilde tutulur. Verilerin sırasını tablo üzerindeki Primery Key belirler.

Tablo üzerinde belirli bir ID değerine sahip satırın verileri getirilmek isteniyorsa, ilk olarak ağaç üzerinden bu ID değerine sahip yaprak düğüm bulunur. B+ ağacı yaprak düğümü üzerinde ise, tablonun o satırına ait verinin disk üzerinde hangi alanda bulundu bilgisi yer alır. Bu yüzden belirli bir ID değerine sahip satıra erişimek için (SELECT * FROM [TABLO_ADI] WHERE ID=5), { Ağaç üzerinden ID değerinin saklandığı yaprak düğümü bul => Yaprak düğüm içeriğini diskten oku => Satır verilerini diskten oku } yolu izlenir.

Nonclustered Index

Clustered index dışında, tablo üzerindeki veriye erişim için farklı indeksler tanımlanabilir. Tablo üzerinde seçilen bir ya da birkaç sütun üzerinden nonclustered index oluşturulabilir. Seçilen sütunların aldığı tüm değerler, yine B+ ağacı üzerinde tutulur. B+ aşağı disk üzerinde saklanır.

Ağacın yaprak düğümlerinde, düğümde yer alan değerlere karşılık gelen primary key değerleri ve bu değerlerin clustered index üzerinde nerede tutulduklarına ait işaretçiler yer alır. Örneğin, [OGRENCI] tablosunda, öğrencinin yer aldığı [SINIF] sütunu üzerinden bir nonclustered index oluşturulmak istediğinde, B+ aşağı üzerinde tüm sınıf değerleri yer alır. Bu ağacın yaprak düğümlerinde ise, yaprak düğümde yer alan sınıfa ait öğrencilerin ID değerleri ve bu ID değerlerinin ağacın clustered indeksi üzerinde nerede bulunduğu bilgisi (pointer, disk üzerindeki adresi) yer alır. Pointer ile, öğrencilerin diğer bilgilerine ihtiyaç duyulduğunda, her ID için clustered index üzerinden yeniden bir arama yapma ihtiyacı ortadan kalkar.

Modern veritabanı yönetim sistemleri, nonclustered indeks yaprak düğümlerinde, primary key dışında, tablo satırına ait farklı sütun değerlerinin de saklanmasına imkan verir. Bu durum disk üzerinde saklanan nonclustered index boyutunun büyünesine sebep olacaktır.

Her nonclustered indeks veritabanı boyutunu büyüteceği ve insert/update/delete maliyetlerini artıracağı için, index tanımlama konusunda dikkatli olmak gerekmektedir.

Heap

Primary Key değeri, dolayısıyla clustered indekse sahip olmayan tablo verilerini disk üzerinde saklamak için kullanılan bir yapıdır. Özellikle satır sayısı çok az olan tablolar dışında tercih edilmemelidir.

Etiketler:  SQL

Mandelbrot Fraktal Çizimi & C#

Fraktal; matematikte, çoğunlukla kendine benzeme özelliği gösteren karmaşık geometrik şekillerin ortak adıdır. En bilinen fraktal kümelerinden birisi olan Mandelbrot kümesinin C# ile oluşturulmuş hali aşağıdadır.

mandelbrot

using System;
using System.Drawing;
using System.Numerics;

namespace SG.Algoritma
{
    public class Fractal
    {
        // Mandelbort kümesinde, yarıçağı 2'den büyük her karmaşık sayı çemberi sonsuza götürmektedir.
        private const int MaxMagnitude = 2;

        // Maksimum iterasyon sayısı
        private const int MaxIterations = 1000;

        // Karmaşık sayı koordinat sisteminde, Mandelbort kümesinin bölgesi.
        // Mandelbort kümesinin sadece bir kısmını çizmek için farklı bir bölge verilebilir. 
        private static Complex AreaMin = new Complex(-2, -2);
        private static Complex AreaMax = new Complex(2, 2);

        /// <summary>
        /// Mandelbort kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="dimension">Oluşacak imajın genişlik ve yükseklik değeri (Kare imaj oluşturulacak)</param>
        public static Bitmap GenerateBitmap(int dimension)
        {
            return Fractal.GenerateBitmap(dimension, Fractal.AreaMin, Fractal.AreaMax);
        }

        /// <summary>
        /// Mandelbort kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="width">Oluşacak imajın genişliği. Yükseklik, çizilmek istenen bölgeyenin genişlik ve yükseklik değerlerine bakılarak belirlenecek.</param>
        /// <param name="areaMin">Karmaşık sayo kooordinat sisteminde, Mandelbort kümesinin sadece belirli bir bölgeye karşılık düşen kısmı çizdirilmek istendiği zaman, bu bölgenin sol alt kösesi</param>
        /// <param name="areaMax">Sağ üst köşe</param>
        public static Bitmap GenerateBitmap(int width, Complex areaMin, Complex areaMax)
        {
            var height = (int)(width * (areaMax - areaMin).Imaginary / (areaMax - areaMin).Real);

            // Boş bir bitmap oluştur
            var bitmap = new Bitmap(width, height);

            // Oluşturulacak imajın her piksel değerine karşılık düşen karmaşık sayı oluşturulacak.
            // Oluşturacağımız karmaşık sayıların, seçtiğimiz bölge içerisinde kalması gerekmektedir.
            
            var rScale = (areaMax - areaMin).Real / width;
            var iScale = (areaMax - areaMin).Imaginary / height;

            for (var x = 0; x < width; x++)
            {
                // Karmaşık sayısının real kısmı
                var real = areaMin.Real + x * rScale;

                for (var y = 0; y < height; y++)
                {
                    // Karmaşık sayısının imaginary kısmı
                    var imaginary = areaMin.Imaginary + y * iScale;

                    // Mandelbort kümesi iterasyon değeri hesaplanıyor.
                    var iteration = Fractal.CalculateIteration(new Complex(real, imaginary));

                    // Iterasyon değerine göre noktanın rengi ayarlanıyor.
                    bitmap.SetPixel(x, y, Fractal.GetColor(iteration));
                }
            }

            return bitmap;
        }

        private static int CalculateIteration(Complex c)
        {
            var z = new Complex();
            var iteration = 0;

            // MaxIterations adedince f(z) = z^2 + c işlemini uygula
            // İşlem sonucu Mandelbort kümesi içerisinde kalmaya devam ettiği sürece işlemi tekrarla
            while (iteration < Fractal.MaxIterations && z.Magnitude < Fractal.MaxMagnitude)
            {
                z = z * z + c;
                iteration++;
            }

            return iteration;
        }

        /// <summary>
        /// // Iterasyona karşılık renk seçiliyor.
        /// </summary>
        private static Color GetColor(int iteration)
        {
            // Rasgele bir renk seçiliyor.
            // 256 tane rengin olduğu bir liste oluşturularak, listeden iteration % 256. renk de seçilebilir.
            // Ya da, oluşan imajın tek renkten oluşmasını istiyorsak, Color.FromArgb(iteration % 256, 0, 0) rengi seçilebilir. Bu durumda kırmızı toplanda imaj oluşacaktır.

            return Color.FromArgb((iteration * iteration * iteration) % 256, (iteration * iteration) % 256, (iteration) % 256);
        }
    }
}

Mandelbrot kümesini fraktal resmini oluşturmak için, ilgili metot aşağıdaki şekilde çağrılabilir. Bu durumda en üstte yer alan resim oluşacaktır.

var bitmap = Fractal.GenerateBitmap(800);

bitmap.Save(@"D:\mandelbort.png", ImageFormat.Png);

Mandelbrot fraktalının sadece belirli bir bölgesini çizdirmek için, ilgili metot aşağıdaki şekilde çağrılabilir. Böylece fraktalın istenilen bölgesi daha detaylı bir şekilde çizdirilebilir.

var bitmap = Fractal.GenerateBitmap(800, new Complex(-0.4, -1.3), new Complex(0.1, -0.5));

mandelbrot

Etiketler:  C#

Encrypt & Decrypt a String in C#

Encrypt and decrypt data using a symmetric key in C#.

Usage

var str = "String to be encrypted";
var password = "p@SSword";
var strEncryptred = Cipher.Encrypt(str, password);
var strDecrypted = Cipher.Decrypt(strEncryptred, password);

Encryption

Cipher class

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SG.Algoritma
{
    public static class Cipher
    {
        /// <summary>
        /// Encrypt a string.
        /// </summary>
        /// <param name="plainText">String to be encrypted</param>
        /// <param name="password">Password</param>
        public static string Encrypt(string plainText, string password)
        {
            if (plainText == null)
            {
                return null;
            }

            if (password == null)
            {
                password = String.Empty;
            }

            // Get the bytes of the string
            var bytesToBeEncrypted = Encoding.UTF8.GetBytes(plainText);
            var passwordBytes = Encoding.UTF8.GetBytes(password);

            // Hash the password with SHA256
            passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

            var bytesEncrypted = Cipher.Encrypt(bytesToBeEncrypted, passwordBytes);

            return Convert.ToBase64String(bytesEncrypted);
        }

        /// <summary>
        /// Decrypt a string.
        /// </summary>
        /// <param name="encryptedText">String to be decrypted</param>
        /// <param name="password">Password used during encryption</param>
        /// <exception cref="FormatException"></exception>
        public static string Decrypt(string encryptedText, string password)
        {
            if (encryptedText == null)
            {
                return null;
            }

            if (password == null)
            {
                password = String.Empty;
            }

            // Get the bytes of the string
            var bytesToBeDecrypted = Convert.FromBase64String(encryptedText);
            var passwordBytes = Encoding.UTF8.GetBytes(password);

            passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

            var bytesDecrypted = Cipher.Decrypt(bytesToBeDecrypted, passwordBytes);

            return Encoding.UTF8.GetString(bytesDecrypted);
        }

        private static byte[] Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
        {
            byte[] encryptedBytes = null;

            // Set your salt here, change it to meet your flavor:
            // The salt bytes must be at least 8 bytes.
            var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);

                    AES.KeySize = 256;
                    AES.BlockSize = 128;
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);

                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                        cs.Close();
                    }

                    encryptedBytes = ms.ToArray();
                }
            }

            return encryptedBytes;
        }

        private static byte[] Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
        {
            byte[] decryptedBytes = null;

            // Set your salt here, change it to meet your flavor:
            // The salt bytes must be at least 8 bytes.
            var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);

                    AES.KeySize = 256;
                    AES.BlockSize = 128;
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);
                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                        cs.Close();
                    }

                    decryptedBytes = ms.ToArray();
                }
            }

            return decryptedBytes;
        }
    }
}
Etiketler:  C#

SQL ROW_NUMBER

SQL sorgu sonucunda, satırlara numara vermek için kullanılır. kendime not

En yüksek değere sahip etiketin sıra numarası 1 olacak şekilde, tüm satırlar DEGER sütununa göre sıralanıyor.

SELECT AD, DEGER, SIRA = ROW_NUMBER() OVER (ORDER BY DEGER DESC)
FROM ETIKET

PARTITION BY ile, sorgu sonucu etiket kategorisine göre gruplandıktan sonra, her bir grupta yer alan etiketlere kendi içerisinde sıra numarası veriliyor. Gruplarda, en küçük değere sahip etiketlerin sıra numarası 1'dir.

SELECT AD, DEGER, SIRA = ROW_NUMBER() OVER (PARTITION BY KATEGORI_ID ORDER BY DEGER)
FROM ETIKET
Etiketler:  SQL

CDN Çift Slah // Kullanımı

tip

Jquery, Twitter Bootstrap vb. third party javascript, css, resim ve font dosyalarını CDN üzerinden kendi web sitemize eklerken, http:// ve https:// protokolü yerine sadece // kullanabiliriz. Eğer sitemiz http protokülü ile çalışıyorsa, // yerine http:// ifadesi eklenecektir. Eğer SSL sertifikası kullanıyorsak, // yerine https:// ifadesi eklenecektir.

SSL sertifikası ile sitemizi yayınlıyorsa, harici içeriklerin http:// protokolü ile eklenmesi, güvenlik dolayısıyla, bu içeriklerin tarayıcı tarafından yüklenmemesine ve dolayısıyla saylarımızın düzgün çalışmamasına sebep olabilir.

Örnek kullanım: <link href="//fonts.googleapis.com/css?family=Roboto" rel="stylesheet" />

stackoverflow.com

Etiketler:  HTML

Database Management & SQL Workshop İçeriği

Database Management & SQL konusunda düzenlenecek workshop içeriği aşağıdaki gibidir.

Toplam çalışmanın 3 hafta sürmesi planladık. Katılımcıların durumuna göre, bir hafta kısa ya da uzun sürme ihtimali, az da olsa, mevcut.

Workshop
  • 1. Hafta

    Veritabanı yönetim sisteminin ne olduğu ve temel kavramlar üzerinde durulacak.

    • DBMS nedir?
    • Temel kavramlar
      • Table
      • Architecture
        • Clustered & Nonclustered Index
        • B-tree
        • Heap

  • 2. Hafta

    Veritabanı normalizasyon kuralları üzerinde durulacak ve seçilecek bir konu hakkında örnek bir ilişkisel varitabanı tasarlanacak.

    • Normalizasyon
    • Örnek veritabanı tasarımı

  • 3. Hafta

    SQL komutları hatırlanarak, önceki hafta hazırlanan örnek veritabanı üzerinde örnek sorgular çalıştırılacak. Sorgu optimizasyonu üzerinde durularak, sorguların daha performanslı çalışması için neler yapılabileceği tartışılacak.

    • SQL
    • Hazırlanan veritabanı üzerinde çalışacak örnek sorguların hazırlanması
    • Sorgu optimizasyonu

Sayfa 1 2 3 4

Kategoriler

Algoritma (5), Cheat Sheet (2), Framework (3), İpucu (5), Kendime Not (1), Kitap (4), Kod (5), Matematik (1), Proje (5), Veritabanı (3), Workshop (3)

Etiketler

C# (13) HTML (1) JavaScript (2) SQL (3)

İngilizce / Türkçe

İngilizce / Türkçe kelime listesi kendime not