Kapsamlı Bilgisayar Mühendisliği Eğitimi Rehberi 2 - Ayrık Matematik ve Ivır Zıvır

ENG 102 (İngilizce 2): ENG101 çok tutulunca devamının çekilmesine karar verilir ve ortaya bu ders çıkar. Bu ders öncekinden biraz daha hafiftir, yine dersteki kaynakları kullanırsınız ama bir de ek kaynak bulup ona göre "Research Paper" (makalenin daha kapsamlısı) yazarsınız. Bu kadar.

MATH 102 (Calculus II): Çift integral öğretilir, bilgisayar mühendisleri için gereksizdir geçiyorum.

TURK 102 (Türkçe II): Önceki Türkçe'nin aynısı.

MATH 132 Discrete Mathematics (Ayrık Matematik)

Ayrık'tan kasıt tam sayılardır, yani sayılar birbirinden ayrıdır, 1 ile 2 arasında kesin çizgiler bulunur. (Devamlı Matematik olsaydı bu olmazdı, 1'den sonra gelen sayı 1+x limit x 0'a giderken olurdu.) Bu temadaki konular dersinin hocasının kafasına göre verilir. Bize Graph Theory, Permütasyon, Kombinasyon, Tümevarım ve Coding Theory dersi verildi. Bu dersler Bilgisayar Biliminin "Teori" alt alanında çalışacaklar için elzem olup Google mülakatlarına girecekler için de hayati önem taşır. Ben pek beceremediğimden ikisini de atlamıştım. Bilgisayar olimpiyatlarına giren arkadaşlar iyi biliyorlardı.

Permütasyon ve kombinasyonu biliyorsunuz, tümevarım = ispat yöntemi, geçiyorum.

Coding Theory'de derste öğrendiğimiz ve şu an hatırladığım kısım şuydu, örneğin A noktasındasınız B noktasına tebrik kartı göndereceksiniz. "Ramazan Bayramınız Mübarek Olsun" yazdınız kartı attınız. İyi de ya yolda kartın üzerindeki yazılar silinirse ve yazı bir anda "Ayranınız Mübarek Olsun" olursa? Tabii gerçekte absürt oluyor ama dijital ortamda bu hata çok kötü sonuçlara gebe olabilir. Dolayısıyla bir çeşit şifre kullanarak mesajın doğru gidip gitmediğini test ediyoruz. En basit yöntem gönderilen sayının (sayı 0 ve 1'lerden oluşuyor) rakamları toplamının tek mi çift mi olduğu. Örneğin 10101 bu tek, sonuna bir de 1 ekleyip gönderiyoruz. 101011. Alan kişi bakıyor kendisine 11101 gelmiş ama rakamları toplamı tek. Mesajın bir tarafları oynamış, bana yeniden gönder diyor. Coding theory bu tip şifreleme işleriyle ilgileniyor işte. Bunu da detaylı olarak Kriptografi ve Bilgisayar Ağları dersine öğreniyorsunuz.

Graph Theory: Bu derste bir sürü hayali grafik türü ve bunların özellikleri ve buna bağlı problemler var, ilkokuldan beri hayali üçgenlerle dikdörtgenlerle uğraşırız ya burada da hayali ağaçlar, çemberler falan var. Grafikler noktalar ve onları birleştiren kenarlardan oluşuyor. Her hangi bir noktadan başlayıp kenarlar üzerinde gidip başladığınız noktaya dönemiyorsanız o grafik bir ağaçtır mesela. Geçebiliyorsanız içinde bir tane çember (circle) vardır. Örnek ağaç:


Kulağa oldukça tırıvırı gelen bu kavramlar karışık bilgisayar problemlerini kullanmakta kullanılır. Örneğin çok ünlü bir problem olan "Traveling Salesman Problem" yani Gezgin Satıcı problemi. Bu problemde gezgin satıcımızın gitmesi gereken şehirler ve bu şehirlerin arasındaki bağlantı ve bu bağlantıların uzunlukları bulunur. Problem kısaca en kısa yolu sorar. Bu problemi çözmek için önce şehirler nokta, aralardaki uzaklıklar ise kenar olacak şekilde grafik çıkarmak gerekir. Bu probleme bulunan çözümlerin çalışma hızı kestirilemediğinden (yani çözümün sonsuza kadar çalışma ihtimali olduğundan) kestirilsin diye grafik "Minimum Spanning Tree" isimli ağaç türüne çevrilir falan fisman. Sıkılmadıysanız ve bu tip problemlerle uğraşmayı seveceğinize inanıyorsanız bilgisayar mühendisliği çok güzel, gelsene. Sıkılanlar için (ben de sıkıldım) geçiyorum.

CS 102 Introduction to Programming and Algorithms II : 

Bu derste sırasıyla: Nesne Tabanlı Yazılım temel ögelerinden Inheritance (Miras) ve Interface (Arayüz), Grafik Arayüzü verilir. Algoritma ve veri yapılarına da şöyle bir dokundurulmaya devam ettirilir.

Inheritance

Geçen yazıda GidenAraba objesi oluşturmuştuk ya. Diyelim biz şimdi bir de GidenKırmızıAraba objesi oluşturmak istiyoruz ama zaten bu da bir tür GidenAraba oluşturacağı için her şeyi baştan yazmakla uğraşmıyoruz. Şöyle yaparız:

public class GidenKırmızıAraba extends GidenAraba {
    String renk = "Kırmızı";
}

Böyle yazınca GidenKırmızıAraba GidenAraba'nın tüm değişkenlerini, constructorlarını, fonksiyonlarını miras edinmiş olur.

Bunun güzel yanı şu, GidenAraba'nın fonksiyonlarını GidenKırmızıAraba'da hatta bir de GidenÖküzArabası objesi yaratırsak onda, kullanabiliriz.

int hız = GidenKırmızıAraba.tekerleklerinHızıToplamı();

veya

int hız = GidenÖküzArabası.tekerleklerinHızıToplamı();

yalnız bunu yapmak için objeyi

GidenKırmızıAraba yeniAraba = new GidenKırmızıAraba();

diye değil

GidenAraba yeniAraba = new GidenKırmızıAraba(),

diye oluşturmak gerek ki bilgisayar oluşturduğumuz objenin GidenAraba olduğunu anlayıp fonksiyonu kullanmamıza izin versin.

Interface

Interface bir fonksiyonlar listesidir. Evet bu kadar. Örnek interface:

interface GidenHerhangiBirşey {
    public void hızıNe();
    public void maksimumHızıNe();
}

Not: void boş dönmek yani bir şey dönmemek demek. Hatırlarsanız int döneceğimiz zaman oraya int yazardık.

Bu interface'i kullanan herhangi bir class bunu belirtmek için implements GidenHerhangiBirşey demelidir ve o fonksiyonları tanımlayıp içini doldurmalıdır.

Örneğin

public class GidenAraba implements GidenHerhangiBirşey {
     // blablabla
    public void hızıNe() {
        // asdadadasd
    }
    public void maksimumHızıNe() {
        // asdadadasd
    }
}

Bir çok öğrenci ilk bakışta niye böyle bir şey yaptığımızı anlayamaz çünkü görünen o ki interface'i ha yazmışsın ha yazmamışsın. Ama interface yine Nesne Tabanlı Yazılım'ın temel taşlarındandır. Örneğin ben mühendis olsam ve bir program yazacak olsam, bu programda olan bir değişiklik on tane farklı ekranı etkilese, şöyle yaparım; ekibime döner arkadaşlar bana on tane ekran yazın ama hepsi bu interface'deki fonksiyonları kullansın derim. Atıyorum doların değişimini kaydeden bir program yazıyorum, bu değişim 1. Televizyon ekranında altyazı geçiyorum, 2. Sitede yayımlanıyor, 3. Teletext'te (liseliler bilmez gerçi) yayınlanıyor. Interface kullanmasaydım ekibimdeki dingolar bu güncellemeyi nasıl yaptıklarına, hangi fonksiyon isimlerini kullandıklarına bakmam gerekirdi ama Interface kullanmışlarsa buna gerek yok.

interface Ekran{
    public void güncelle();
}

Benim kodum:
televizyonEkranı.güncelle();
site.güncelle();
teletext.güncelle();

Hatta bunu daha da abartabiliriz de çünkü Interface bize Inheritance imkanı sunar. Bir "Ekran" interface'i kullanan ekranlar derneği, aman şey dizisi yaratırız, oradan while döngüsüyle yardırırız.

Ekran[] ekranlar = {televizyonEkranı, site, teletext};

int güncellenenEkranlar = 0;
while (güncellenenEkranlar < ekranlar.length) {
    ekranlar[0].güncelle();
    güncellenenEkranlar++;
}

Not: ++ yapınca otomatik olarak sayıyı bir arttırır. yani güncellenenEkranlar 0 ise 1 olur.

GUI (Grafik Arayüzü)

Bu derste öğrenciler öğrendiklerini uygulayabilsinler diye proje yaptırırlar, tabii proje de güzel bir şey yapsınlar resimli mesimli olsun isterler, öğrenciler de nereden başlayacağını bilsin diye koca koca profesörler bir web tasarımcı edasıyla GUI anlatır. Avantajı ileride GUI'li iş yaparken mantığını kavramak kolay olur. Burada GUI anlatmanın bir yararı olmayacağı için geçiyorum. Zaten Javanın grafik kütüphanelerinin hiçbirinin yüzüne bir daha bakmadım :)

Recursion

Recursion çok zevkli ama hayli zordur. Farklı bir düşünme şekli gerektirir. Recursion sorusunu çözen veya çözemese bile problemin çözümünü gören bir bilgisayar mühendisi adayı keyif almıyorsa kariyerini bir daha gözden geçirmelidir. Biraz net konuştum ama bence öyle.

Recursion'ı en iyi linkteki ekşi sözlük yazarı anlatmış.

Geniş özet: Hani fonksiyonlara return diyip döneceğimiz şeyi yazıyorduk ya, istersek fonksiyonun kendisini de yazabiliyoruz.

public int naber(){
    return naber();
}

Böyle olunca fonksiyon sürekli kendini çağırıp duruyor ve belli bir süre sonra bilgisayarımız çöküyor, geçmiş olsun tamire vermeye gidin. Ben şu ana kadar altı bilgisayar harcadım recursion yüzünden.

Şaka şaka, program duruyor ve "Stack overflow!" diyor.

Recursion en güzel faktöriyel hesaplamakta kullanabiliriz.

public int faktöriyel (int sayı) {
   if (sayı == 1)
      return 1;
   else
      return sayı * faktöriyel (sayı - 1);
}

Yani şöyle oluyor, önce fonksyion verilen sayı 1 mi diye bakıyor, değilse o sayıyı alıyor ve bir eksiğinin faktöriyeliyle çarpıyor, tabii o faktöriyeli bulmak için bir daha fonksiyona sokuyor. 6 * 5! = 6 * 5 * 4! diye gidiyor.

Algoritmalar ve Veri Yapıları

Bu dönem de aslında ikinci sınıf konuları olan bu konulara dokundurma var, ikinci sınıfı anlatırken anlatacağım.

Yorum Gönder