Daha üst düzey bir dilde prototip oluşturmak yaygın mıdır? [kapalı]


18

Şu anda (C) 'de çok az gerçek dünya deneyimine sahip olduğum bir dilde mevcut programlama yeteneğimi aşan bir projeye başlama fikri ile oynuyorum. Genel tasarımın başlayabilmesi için daha aşina olduğum (Perl / Python / Ruby / C # gibi) daha üst düzey bir dilde prototip oluşturmak değerli olur mu?

Nihayetinde, son ürün performansa duyarlıdır (bu bir veritabanı motorudur), bu nedenle C'nin seçimi, ancak C'nin iyi olduğunu bilmemenin ağaçlar için ormanı kaybetmeme neden olacağını korkuyorum.

Benzer soruları ararken, programcıların Prolog'da prototip oluşturduklarını, ardından montajcıda krank kullandıklarını belirttim.


4
İlk olarak C'de istediklerini kodlayarak, sonra söküp elde edilen montajı elle ayarlayarak montajcı yazacak insanları duydum.
user16764

9
Performansın, algoritma seçimini ve uygulamasını düzeltmek, büyük ölçüde paralel problemler için paralel kod yazmak ve iyi veri sunumları için daha sık kaybolmadığını unutmayın. Tasarımı doğru şekilde elde edene kadar C için endişelenmeyin.
Peter Smith

1
@ user16764: Aslında bunu yaptı. Dil dışında Fortran vardı. Ancak derleyici çıktısını tam olarak tanımladığınız şekilde el ile ayarladık.
S.Lott

C'nin daha hızlı olması gerekmez. Özellikle performans IO'ya bağlıysa. CPU'ya bağlı performans için bile, bir C uzmanı değilseniz, optimize edilmiş bir VM muhtemelen kendiniz yazdığınız her şeyden daha iyi performans gösterebilir.
jiggy

Genellikle bu prototipleme tekniğini kullanıyorum: bir sorun DSL olarak uygulanmakta olan en doğal dilinde ifade ediliyor. Ardından, prototip bittiğinde, bir DSL parçasını daha düşük bir dile yeniden kodlamak yerine, performans kabul edilebilir olana kadar bu DSL derleyicisinin uygulamasını geliştiririm.
SK-logic

Yanıtlar:


27

C kullanmak uygulamanızı otomatik olarak hızlandırmaz. Platformunuz için farklı bir programlama dili seçebildiğinizde kesinlikle tavsiye ederim.

As Bill Harlan belirtti :

Doğru kodu optimize etmek, optimize edilmiş kodu düzeltmekten daha kolaydır . Erken optimizasyon aslında uzun vadede optimizasyonu engeller. Gereksiz optimizasyon tasarımları bozar, modülerliği ve bilgi gizlemeyi yok eder ve kodun değiştirilmesini çok daha zorlaştırır. Gizli hataların bulunması daha uzun sürer. Genellikle profillememizle veya makinelerimizi veya derleyicileri değiştirerek kodumuzun hesaplama çabalarını yanlış değerlendirdiğimizi keşfediyoruz. Bil bakalım ne oldu? Şimdi, optimizasyon olması gerekenden çok daha zor.

Performans sorunlarını gerçekten tahmin edebiliyorsanız, C ++ kullanmayı düşünün. cprogramming.com çok güzel sözler :

Bununla birlikte, C ++ ile performansta küçük bir artış elde etmek için C ++ 'ın yeniden kullanılabilirliğinden vazgeçmeye değip değmeyeceğini merak edebilirsiniz, özellikle C ++, gerektiğinde C programlama tarzında yazılabilir .


Asıl sorunuza daha iyi cevap verebilmek için: Sadece prototip değil, daha yüksek seviyeli bir dilde kod yazarım ve performans sorunlarıyla karşılaştığınızda daha düşük seviyeli dillerde optimizasyon yaparım.


25
+1: Ayrıca, Perl, Python ve Ruby C işlevlerini çağırabilir, böylece gerekirse performansa duyarlı parçaları C'ye yazabilirsiniz.
Larry Coleman

Java'da yapay görme kodunu prototipledim; ki aslında yeterince hızlıydı. C'ye kayıt yapmak oldukça kolay olurdu (sadece C gibi yazıyorsunuz; ilkel sabitleme
antipatternini

Java ile gerçek zamanlı kod yazdım. Bu projede dosya erişimi C ++ ile yapıldı ve gerçek zamanlı kod Java ile yapıldı - deli! Ancak, gerçek zaman kodu çok hızlıydı. Çok karmaşık değildi, ama zaman zaman inanılmaz miktarda veriyi işledi. Dolayısıyla, performansa duyarlı uygulamalar için kesinlikle üst düzey diller kullanabileceğinizi söyleyebilirim.
yapılandırıcı

@Tim Williscroft: Bu sayfayı sadece "ilkel fiksasyon karşıtı madde" için google'da açtığımda görünüyor. O nedir?
SingleNegationElimination

@TokenMacGuy: ilkel takıntı daha fazla vuruş yaptı (aynı
antipattern

7

Bunu yapmak değerli olmayacaktır, çünkü a) bu dillerin doğrudan C'ye çevrilen bölümleri daha basit olmayacaktır ve b) doğrudan C'ye çevirmeyen bölümlerin C'de yeniden yazılması daha zor olacaktır. ilk etapta C dilinde yazdıysanız.


+1 - Özellikle, dili bilmiyorsanız OO kodunu C'ye kaydırmak zor olacağından veya yordamsal bir şekilde yazmanız durumunda üst düzey dili kullanmayı daha zor hale getireceği için.
Jetti

Evet kesinlikle. Hala çok fazla sihir veya şeker kullanıyormuşum gibi C'ye kolayca çevrilemeyen daha yüksek kavramları düşünüyor olabileceğimden endişeleniyorum.
Mark Canlas

4

Bu, kategorik bir evet veya hayır cevabı olan bir soru değildir. Bir fıkra ile tartmama izin ver.

örnek 1

Java ile yazılmış bir oyunu Flash, AS3'e taşımakla görevlendirildim. Yüzeyde, bu nispeten sorunsuz gitme potansiyeline sahiptir. Sonuçta, böyle bir işi ortalama müşteri çalışmanızdan daha net olarak düşünebilirsiniz, çünkü zaten kaynak oyun şeklinde tamamen yerleşik bir işlevsel spesifikasyona sahipsiniz. Java ve AS 3 her ikisi de üst düzey dillerdir ve AS3, Java ile ortak olarak paket yapıları, tek miras / çoklu arabirim, (kaydolma) güçlü yazma ve genel / korumalı / özel değişken kavramları gibi birçok özelliği paylaşır. ve işlev bildirimleri. O zamanlar Java'da hala çok yeşildim ve orijinal kaynak kod tabanına tamamen yeniydim. Bu yüzden hızlı ve kolay olacağını ümit ederek ne bulabileceğimi görüyorum.

Anlaşıldığı üzere, kodun yazarı, Java'dan tanımsız başka bir ortama taşınabilecek soyut bir motor yaratmaya çalıştı. Bu bana limana açık olacağını umuyordu. Ne yazık ki, bunun yerine keşfettiğim şey, Threads'ın avantajı olmadan Flash'ın kendisini Flash'ın üstünde yeniden icat etme ihtimaline bakıyordum. Gerçek bir liman, ortaya çıktığı gibi, sadece kötü bir fikir olurdu ... bir performans kabusu. Bunun üzerine, tüm orijinal kaynak veri dosyalarını kullanmayı umuyorsam, oyunun kendi dili için bir ayrıştırıcı ve sözcük oluşturucu anlamına gelen kendi özel harici kodlama dilini uyguladı.

Sonunda, zaman ve bütçe kısıtlamaları göz önüne alındığında, orijinal kaynak kodu gerçekten çok yardımcı olmadı. Sahip olmanın en yararlı yanı, oyunun mantığının kontrol akışını tam olarak nasıl taklit edeceğimi bilmemdi ... ama bunun için orijinal kaynağa gerçekten ihtiyacım oldu mu? Muhtemelen değil.

Ancak bu örnek o kadar alakalı olmayabilir, çünkü durumunuzun tersi. Yazmadığım bir kod tabanını kullanmayı umuyordum, o zaman bilmediğim bir dilde, aşina olduğum bir ortamda gelişimi hızlandırmayı biliyordum. İşte farklı bir örnek

ÖRNEK 2

Java geliştiricisinin taşınabilir bir kod tabanı oluşturmaya çalışırken ne yaptığını belirterek, Flash çalışmamda kendime benzer bir şey yapmaya karar verdim ... flash.display. * Sınıflarını genişletmeye çok fazla güvenmeyen bir kod yazma. ve görünüm oluşturmak için kompozisyon kullanma. Flash.event. * 'A çok fazla güvenmemek ve bunun yerine kendime ait hafif bir mesaj yazma sistemi yazmak, özellikle bir dile veya platforma bağlı değil. Son zamanlarda adı geçen çerçeveyi kullanarak bir oyunu bitirdim ve bir Unity 3D projesi olarak C # 'a (Java ve AS3'e çok benzer bir şekilde bildiğim bir dil) taşımanın kolay olup olmayacağını görmek istedim. Sonuç olarak, bu çok daha başarılı oldu! AS3'te C # 'dan daha akıcı bir şekilde düşündüğüm için, algoritmaların önceden yazılması tonlarca zaman kazandırdı. Tek yapmam gereken sözdizimini değiştirmekti.

Yani, sadece kendi kişisel deneyimimle, cevabın her zaman evet ya da hayır olacağını söyleyemem. Yüksek seviyeli seçim dilinizde belirli dil deyimlerine ne kadar bağımlı olduğunuzu ve bunları yeniden oluşturmanın C'de kolay mı yoksa zor mu olacağını hesaba katmalısınız.


İkinci hikayeniz nasıl hissettiğimi gösteriyor. Prototip uygulamasını genel ve sihir / hile yapmayı serbest tutmaya çalıştım, öyle ki çoğu fikir olmasa bile çoğu fikir C'ye çevrilebilir. Açıkçası şeytan ayrıntıda gizlidir.
Mark Canlas

@ Mark Canlas "şeytan ayrıntıda gizlidir." Kesinlikle. Daha önce diller veya ortamlar arasında hiç kod taşımamış olsaydınız ilk denemenizin kötüleşebileceğini düşünüyorum çünkü bunlarla karşılaşıncaya kadar tüm olası sorunları öngörmek zor.
scriptocalypse

2

Bence sözde kodla başlamak değerli olacaktır. Başka bir dilde bir prototip yazmak, potansiyel bir zaman kaybı gibi görünüyor, çünkü üst düzey dilinizin neredeyse sahte kodun yanı sıra 'C' ye dönüşmesi olası değildir.

Ayrıca, sözde kod kullanarak, sisteminizin gerçekte nasıl çalıştığını daha iyi anlayacaksınız.

Sahte kod üzerinde çalıştığınız aynı dönemde, C üzerinde çalışmalısınız. Daha sonra, planlamanızı bitirdiğinizde, aslında bu şeyi uygulamaya hazır olabilirsiniz.

Başka bir dilde yazmak için önerilen nedeniniz, tasarımın devam etmesine yardımcı olmak olduğu için, başlamanız için bunun yerine bazı UML diyagramları veya bu tür bir şey kullanmak isteyebilirsiniz.


2

Algoritmayı prototipleyebilirsiniz - kesinlikle "çok yüksek" bir dil kullanarak çekirdek mantığın tasarım hatalarını ortadan kaldırın (örneğin, Matlab, belki Ruby). Bunu algoritmanızın çalıştığını ve düzgün çalıştığını kanıtlamak için kullanın, ardından "düşük düzey" bir dilde sıfırdan uygulayın.

C ++ veya Java veya C # 'ı "yüksek seviye" ve C'yi "düşük seviye" olarak seçerseniz fazla kazanmazsınız çünkü okunabilirlikteki kazanç önemli olmayacak ve "çeviri" hala oldukça acı verici ve oldukça hata olacaktır. yatkın. Fikir özüdür, projenizin üst düzey uygulamadaki motoru bir veya iki ekrandan daha fazla işgal etmemeli, kavranması kolay, okunması kolay ve tüm uyarıların acı verici bir şekilde açık olması gerekir - esasen çalışan, çalıştırılabilir bir blok diyagram.


2

Bir veritabanı motoru çoğunlukla düşük seviyeli G / Ç'yi en iyi şekilde ele almak ve b-ağacı ve bağlantılı listeler gibi karmaşık yapıları verimli bir şekilde ele almakla ilgilidir.

Kesinlikle bir C / C ++ sorunu, orada bazı oldukça iyi Java uygulamaları var.

İyi performans gösteren doğru algoritmalar geliştirmek, daha üst düzey bir dilde çok daha kolaydır. Genellikle birkaç varyasyonu denemek ve sonuçları karşılaştırmak için bir durumdur. Daha sonra "kazanan" algoritmayı C'ye çevirebilirsiniz.

Bir uzlaşma çözümü, ilk uygulamayı daha yüksek seviyedeki JVM dillerinden birinde (Jython, Groovy akla geliyor) yazmak ve ardından uygulama stabilize olduğunda sınıftan Java'ya taşımak olabilir.


2

Ortak olduğunu düşünmüyorum, ama bitti. Şimdiye kadar birlikte çalıştığım en keskin mimarlardan biri, modelini Python'da yapıyordu ve daha sonra bu kodu C ++ 'da uyguluyordu.

Genel olarak bunu değerli kılmak için, gerçekten hedef dilde kolay bir şekilde ifade edilmeyen karmaşık ve son derece optimize edilebilir algoritmalar gerçekleştirmeniz gerektiğini düşünüyorum. Çoğu "gerçek dünya / iş" durumu için, hedeflediğimiz dilde yüksek seviyedeki niyeti ifade etmek nispeten kolaydır ve bahsedilen dilde bir uygulama performans gereksinimlerimizi karşılar, bu nedenle daha yüksek bir modelleme ihtiyacı / arzusu yoktur düzey dili.

Daha üst düzey bir dil hakkında daha iyi bilgiye sahip olduğunuz durumunuz göz önüne alındığında, bu metodolojinin kısa vadede iyi çalıştığını görebiliyordum. Sadece işleri takip etmeniz için size bir yol haritası sunmakla kalmaz, sorularınız varsa daha büyük bir hassasiyetle sorabilirsiniz.


1

Şu anda C "performans nedeniyle" yazılan bir proje üzerinde çalışıyorum (bu orijinal motivasyon oldu), ama gerçekten profilli ise zamanının çoğunu diğer sistemleri (DB, diğer uygulamalar için beklemek) harcadığını ortaya koyuyor Java, bir soket üzerindeki "etkinlikler").

Yanlış algoritmayı kullanırsanız, C'de de kötü performans elde edersiniz (örneğin, bir anahtar için doğrusal arama yaparsanız, "C hash tabloları olmadığından ve diğer kütüphaneleri kullanmak istemediğimizden"), karma tabloları veya C ++, Java, C #, Python ... ve benzeri bir dil ile yapın).

Herhangi bir nedenden ötürü C'de yapmak zorunda kalırsanız, bildiğiniz diğer dilde prototip oluşturmak, sadece gerçek C uygulamasını yapacağınız hangi "problemleri" yapacağınızı bilerek prototip ederseniz, o kadar da kötü bir fikir değildir. C ile kendinizden emin değilsiniz. (Yakında örneğin C / C std kütüphanelerinin kapsayıcıları olmadığını, sadece "düz" bir dizinin olduğunu keşfedeceksiniz; std olmayan kütüphanelere ihtiyacınız var). Dahası C OO değildir, bu yüzden OO tarzında prototip oluşturuyorsanız, daha zor olacaktır.

Özetlemek gerekirse, yapılacak en iyi şey, "prototipleme" dilinizdeki gerçek uygulamayı yapmak ve daha sonra gerçekten gerekliyse, C'ye CPU yoğunluklu işlevler yazmaktır, ancak yalnızca C kabul edilebilirse, diğerlerinde prototip yapmadan önce daha iyi öğrenin diller ve tabii ki uygulama yazmadan önce.


1

Daha üst düzeyde bir dilde yazılmış birçok performans açısından kritik uygulama vardır.

Geçmişte Assembler ve C'de programladım ve metale çok yakın bir his olsa da, kullanımları günümüzde çok sınırlı.

Performansı engelleyecek çok şey var, dilin sınırlayıcı faktör olduğu kısma ulaşacağınızdan şüpheliyim. Bu C vs C # olduğunu düşünüyor.

Dile göre% 10 -% 15 performans artışı elde ettiğinizi varsayalım. Bu, doğru algoritmanın uygulanmasında büyüklük artışlarıyla karşılaştırıldığında hiçbir şey değildir.

C # 'da programlama yaparken, algoritmaların / veri yapılarının mimarisine ve uygulanmasına odaklanmak için daha fazla zamanınız olacak ve böylece daha iyi üst düzey optimizasyonlara yol açacaksınız.

Gerçek dünyada her zaman zaman kısıtlısınız, bu yüzden zamanınızı projenin doğru kısmında geçirin.


0

Aslında C planını oluşturmak için planınızın ne olduğunu merak ediyorum. Prototip yapıp C'yi öğrenecek ve C dilinde yeniden kodlayacak mısınız? Bana göre bu, yeni teknolojiler öğrenirken birçok programcının yakalandığını düşündüğüm meşhur "gözler mideden daha büyük" gibi görünüyor (sahip olduğumu biliyorum). Demek istediğim, nihayetinde yazılması gerektiğini düşündüğünüz dilin giriş ve çıkışlarını bilmeden, performansa duyarlı bir şey tasarlamaya çalışıyorsunuz, temelde sizden önce bir C uygulaması tasarlamaya başlamak istiyorsunuz Önce C'yi öğrenmek için zamanın ne zaman daha iyi harcanabileceğini bilmek ve daha sonra istediğiniz uygulamayı nasıl yazacağınız konusunda daha fazla fikir edinebilirsiniz. Belki de soruyu yanlış anladım ve bunu C'de programı oluşturmak için başka bir programcıya teslim etmeyi planlıyorsun,


Bazen "Bunu yapma." olduğu için doğru cevap "Nasıl X yapacağım?"
Larry Coleman

0

Prototipleme, bazen çözmeye çalıştığınız problemi anlamak için yapılır. Ve bazen, zaten aşina değilseniz, altta yatan teknolojileri tanımak için.

Bahsedilen durum için, bir kodlama dilinde prototip yazmayı, örneğin python'u ve gerçek kodu C olarak yapmayı düşünüyorsunuz.

Bazı olasılıkların değerlendirilmesi:

1 . Python'da prototip üretiyorsunuz ve yazılımı C olarak yazıyorsunuz.

Komut dosyası dilinde prototip oluşturma, çıktıyı girişe karşı hızlı bir şekilde kontrol etmek istediğiniz yere yardımcı olabilir . Bu, öncelikle bir sorunu çözmek için mantığınızı test etmeniz gerektiğinde yararlıdır . Ayrıca, hızlı bir şekilde diğer insanlar için bir demo koymak istiyorsanız yararlı .

Python'da yazdığınız kod ne olursa olsun son yazılımda kullanılmayacaktır. Ancak, prototipinizi python okuyabilen ve C yazabilen birine iletiyorsanız yardımcı olabilir. Burada, prototipleme bir fikir iletişimine yardımcı olabilir .

Bu yöntem, çözeltinin mantıksal fizibilitesini test etmek için uygundur.

2 . C prototip ve C yazılım yaz.

C'de yeni olan prototiplemenin iki avantajı var. Eğer prototip yazarken biri, sen olsun dilin ilgili bölümlerini anlama nihai yazılım inşa ederken şunları yapabilirsiniz vb Two, kütüphane, API, tuzaklar, prototip başlamak size zaman kazandırır ve kendisi kodu yeniden kullanır .

Bu yöntem, çözümün hem mantıksal hem de teknolojik uygulanabilirliğini test etmek için uygundur.

3 . Eldeki soruna bağlı olarak prototip oluşturmanın kodlama yollarını düşünebilirsiniz.

Prototip oluşturmak istediğiniz mantık ve fikirlerin bir parçasıysa; sahte kod , akış şemaları ve blok diyagramları kağıt üzerinde de iyidir.

Bir UI prototipi ise, bazı UI mock-up aracını veya tekrar bazı kağıtları düşünün.


0

Ben (Pytho / Ruby / C # ne değil) bildiğiniz bir dilde prototip gerekir bence:

  1. Dilin sağladığı olanaklardan / kütüphanelerden en iyi şekilde yararlanabilirsiniz.
  2. Zamanınızı dil kısıtlamaları yerine tasarım tercihlerine karar vererek geçirirsiniz.

Daha sonra, şişe boynu bölgelerini bulmak için bir profil oluşturma aracı kullanabilirsiniz. C / C ++ ile yeniden uygulayın. Prototipinizin 'yeterince hızlı' olabileceğini bilen yukarıdaki adımı birkaç kez tekrarlayın!


0

Açıkladığınız yaklaşımla bir şey kazandığınızı sanmıyorum ve birkaç kişi nedenini ayrıntılı olarak açıkladı.

Katıldığım bir proje bu tür bir yaklaşımı kullandı: Cell / BE ve Power7 mimarileri için matematik kütüphanesi geliştirme. Fonksiyonlar Haskell'de modellenmiştir (CoCoNUT kullanılarak) ve çıkış fonksiyonları belirli bir hedef mimari için optimize edilmiş montajdaydı.

Bu durumda hedefler, ayarlanmış montaj talimatları ve birden fazla mimariyi hedefleme yeteneği ile yüksek performanstı.

Gıda olsa, umarım açlıktan yoksun :)


0

Yüksek performanslı bir veritabanı motoru için muhtemelen ihtiyacınız olacak:

  • çoklu kullanım,
  • açık bellek yönetimi,
  • eşzamansız bildirimler,
  • semaforlar veya senkronizasyon ilkelleri,
  • düşük seviyeli dosya sistemi işlevlerine kolay erişim.

Seçtiğiniz algoritmalar performans açısından kritik öneme sahiptir.

Genel tavsiye, üst düzey bir dil ile başlamak, daha sonra yalnızca daha düşük düzeyli bir dile optimize edilmesi gereken bitleri taşımaktır.

Bununla birlikte , seçtiğiniz yüksek düzeyli dil, yazmanız gereken algoritmaları destekleyebilmelidir: ve buradaki verimli algoritmalara en sonunda iş parçacığının kontrolü, etkin bellek kullanımı ve en iyi düşük düzey dosya sistemleri işlemlerinin kullanımı hakim olabilir. mevcut. Dolayısıyla, nihai hedef performanssa, kullanmanız gereken ilkelleri desteklemeyen dillerde prototip oluşturamazsınız.

Prototipinizi test etmeniz gerekiyorsa (veya başkalarının arayüzlerine karşı yazılım geliştirmesi gerekiyorsa), amaçlanan API'ları destekleyen bir dilde de çalışmanız gerekir. Daha sonra optimizasyon sırasında diğer kişilerin kodlarını test etmelerine ve kendi regresyon testlerinizi yapmalarına izin verebilirsiniz.

Bu düşünceler muhtemelen bu durumda üst düzey prototipleme için birçok dili ve muhtemelen bahsettiğiniz tüm dilleri (muhtemelen C # hariç) dışlamaktadır. Ancak, elbette, herhangi bir dilde (İngilizce dahil) sözde kod yazabilir ve gerekirse projenin bölümlerini (örneğin işlevleri sıralayabilirsiniz) tercih ettiğiniz dilde prototipleyebilirsiniz.

C ++ ve C arasındaki yakın ilişki (ve ihmal edilebilir performans farklılıkları), nihai üründe C ++ 'ı C yerine tercih etmemenin çok az nedeni olduğu anlamına gelir.

(Belirli bir amaç için yüksek performanslı bir veritabanı motoruna ihtiyacınız olduğu varsayımına cevap veriyorum: niyetleriniz daha mütevazı ise, muhtemelen mevcut bir motoru raftan alırsınız).


-2

Bence C'nin şöhreti hak ediyor, çünkü muhteşem Unix C dilinde yazıldı. Ancak, C'yi en iyi bilen insanlarla karşılaştırıldığında, neden kullanılması gerektiğine oldukça şüpheliyim. Ken Thompson'ın (montaj dilinde Unix'in ilk bir versiyonunu yazdıktan sonra) Fortran'da Unix yazmaya başladığı, ancak bir hafta veya bir ay sonra vazgeçtiği ve meslektaşı Ken Ritchie tarafından geliştirilen C'yi kullanmaya başladığı söyleniyor. Aynı zaman.

Son zamanlarda Fortran'ın C ve C ++ 'dan daha hızlı olduğunu okumak beni şaşırttı.

Richard Mullins


1
bu sorulan soruya nasıl cevap veriyor?
gnat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.