JavaScript'te Veri Yapıları
Giriş
As iş mantığı daha arkadan öne doğru hamle, uzmanlık Frontend Mühendisliği zamankinden daha önemli hale gelmektedir. As Frontend Mühendisleri gibi, biz görünümü kütüphaneleri bağlıdır Tepki üretken olmak için. Kitaplıkları görüntüleme , verileri yönetmek için Redux gibi durum kitaplıklarına bağlıdır . React ve Redux birlikte, UI güncellemelerinin veri değişikliklerine tepki verdiği reaktif programlama paradigmasına abone olurlar . Artan bir şekilde, arka uçlar yalnızca API sunucuları olarak hareket ederek yalnızca verileri almak ve güncellemek için uç noktalar sağlar. Gerçekte, arka uç yalnızca veritabanını "iletir"Ön uç Mühendisinin tüm denetleyici mantığını ele almasını bekliyoruz. Mikro hizmetlerin ve GraphQL'in artan popülaritesi, bu büyüyen trendi kanıtlıyor.
Artık, HTML ve CSS'nin estetik anlayışına sahip olmanın yanı sıra, Frontend Engineers'ın JavaScript'e de hakim olması bekleniyor. İstemci üzerindeki veri depoları, sunucudaki veritabanlarının "kopyaları" haline geldikçe, deyimsel veri yapılarına ilişkin derinlemesine bilgi çok önemli hale gelir. Aslında, bir mühendisin deneyim seviyesi, belirli bir veri yapısının ne zaman ve neden kullanılacağını ayırt etme yeteneğinden anlaşılabilir .
Kötü programcılar kod hakkında endişelenir. İyi programcılar veri yapıları ve bunların ilişkileri hakkında endişelenir.
- Linus Torvalds, Linux ve Git'in Yaratıcısı
Yüksek düzeyde, temelde üç tür veri yapısı vardır. Yığınlar ve Sıralar , yalnızca öğelerin nasıl eklendiği ve kaldırıldığına göre farklılık gösteren dizi benzeri yapılardır. Bağlı Listeler , Ağaçlar , ve Grafikler ile yapılardır düğümler tutmak başvuruları diğer düğümlere. Karma Tablolar , verileri kaydetmek ve bulmak için karma işlevlere bağlıdır .
Karmaşıklık açısından Stacks
ve Queues
en basit olanıdır ve inşa edilebilir Linked Lists
. Trees
ve Graphs
en karmaşık olanıdır çünkü bağlantılı liste kavramını genişletirler. Hash Tables
güvenilir bir şekilde çalışmak için bu veri yapılarını kullanma ihtiyacı duyuyor. Verimlilik açısından Bağlantılı Listeler , verilerin kaydedilmesi ve depolanması için en uygun olanıdır ; Karma Tablolar ise verilerin aranması ve alınması için en iyi performansı gösterir .
Nedenini açıklamak ve ne zaman olduğunu göstermek için , bu makale bu bağımlılıkların sırasına uygun olacaktır. Hadi başlayalım!
Yığın
Muhtemelen en önemli Stack
JavaScript olan çağrı yığını biz itmek kapsamı a function
onu çalıştırmak zaman. Programlı olarak, sadece array
iki ilkeli işlemden oluşur: push
ve pop
. İtme ekler için elemanlar üst ederken, dizinin Pop kaldırır aynı yerden onları. Başka bir deyişle, Yığınlar "Son Giren İlk Çıkar" protokolünü (LIFO) izler.
Aşağıda bir Stack
kod içi örneği verilmiştir . Yığının sırasını tersine çevirebileceğimize dikkat edin : alt üst, üst alt olur. Bu nedenle , sırasıyla ve yerine dizi unshift
ve shift
yöntemlerini kullanabiliriz .push
pop
Öğelerin sayısı arttıkça push
/ pop
, unshift
/ shift
çünkü her öğenin ikincisinde yeniden dizine alınması gerekir, ancak ilkinde yeniden dizine eklenmemesi gerekir.
Kuyruk
JavaScript, engellemesiz işlemleri desteklemeyi mümkün kılan olay odaklı bir programlama dilidir . Dahili olarak, tarayıcı yalnızca yöneten bir iplik kullanarak, tüm JavaScript kodu çalıştırmak için olay kuyruğu için enqueue ve olay döngü için dinlemek kayıtlı için . Tek iş parçacıklı bir ortamda eşzamansızlığı desteklemek için (CPU kaynaklarından tasarruf etmek ve web deneyimini geliştirmek için), sırayı çıkarın ve yalnızca çağrı yığını boşken çalıştırın. diğer işlemleri engellemeyen eşzamansız kodun "eşzamanlı tarzda" yürütülmesine izin vermek için bu olay güdümlü mimariye bağlıdır .listeners
events
listener functions
Promises
Programlı olarak, Queues
yalnızca iki birincil işlem içeren dizilerdir: unshift
ve pop
. Unshift enqueues için ürün sonunda dizinin iken Pop dequeues onları başından dizinin. Diğer bir deyişle, Kuyruklar “İlk Giren İlk Çıkar” protokolünü (FIFO) takip eder. Yönü tersine edilirse, yerini alabilir unshift
ve pop
birlikte push
ve shift
sırasıyla.
Bir Queue
kod içi örneği :
Bağlantılı liste
Diziler gibi, Linked Lists
veri öğelerini de sıralı sırada saklayın . Dizinleri tutmak yerine, bağlantılı listeler diğer öğelere işaretçiler tutar . İlk düğüm denir başını ise son düğüm denir kuyruk . Bir de , tek başına bağlanmış liste , her bir düğümün sadece bir gösterici olan bir sonraki düğüm. Burada baş , listenin geri kalanında yürümeye başladığımız yerdir. Bir de çift bağlı bir listede , bir gösterici önceki düğüm de tutulur. Bu nedenle, kuyruktan başlayıp başa doğru “geriye” yürüyebiliriz.
Bağlı listelerde sabit zamanlı eklemeler ve silmeler vardır çünkü sadece işaretçileri değiştirebiliriz. Dizilerde aynı işlemleri yapmak doğrusal zaman gerektirir çünkü sonraki öğelerin kaydırılması gerekir. Ayrıca, bağlantılı listeler alan olduğu sürece büyüyebilir. Ancak, otomatik olarak yeniden boyutlandırılan "dinamik" diziler bile beklenmedik şekilde pahalı hale gelebilir. Tabii ki, her zaman bir değiş tokuş vardır. Bağlantılı bir listedeki bir öğeyi aramak veya düzenlemek için, doğrusal zamana eşit olan tüm uzunluğu yürümek zorunda kalabiliriz. Ancak dizi indekslerinde bu tür işlemler önemsizdir.
Diziler gibi, bağlantılı listeler de yığınlar olarak çalışabilir . Takma ve çıkarma işlemi için kafanın tek yer olması kadar basit. Bağlı listeler ayrıca kuyruk olarak da çalışabilir . Bu, girişin kuyrukta meydana geldiği ve çıkarma işleminin başta meydana geldiği veya tam tersi olan çift bağlantılı bir liste ile elde edilebilir. Elementlerin çok sayıda için, sıraları uygulanması bu şekilde çünkü diziler kullanmaktan daha performanslısı shift
ve unshift
diziler başında operasyonları yeniden indeksi sonraki her eleman için doğrusal bir zaman gerektirir.
Bağlı listeler hem istemcide hem de sunucuda kullanışlıdır. İstemcide, Redux gibi durum yönetimi kitaplıkları , ara yazılım mantığını bağlantılı liste biçiminde yapılandırır. Ne zaman eylemler sevk tüm ulaşmadan önce ziyaret edilene kadar, bunlar sonraki bir katman gelen borulu edilir düşürücüler . Sunucuda, Express gibi web çerçeveleri de benzer şekilde ara katman mantığını yapılandırır. Bir istek alındığında, bir yanıt verilene kadar bir ara yazılımdan diğerine aktarılır .
Bir Doubly-Linked List
kod içi örneği :
Ağaç
A Tree
bir gibidir bağlantılı listeye bu başvurular tutar hariç, birçok çocuk düğümler bir de hiyerarşik yapıda. Başka bir deyişle, her düğümün birden fazla ebeveyni olamaz. Doküman nesne modeli (DOM) bir kök ile, böyle bir yapı, bir html
düğüm olduğu dallandığını head
ve body
düğümler, bilinen tüm içine daha fazla olan Subdivide html etiketlerinin . Kaputun altında, prototip kalıtım ve React bileşenleri ile kompozisyon da ağaç yapıları üretir. Elbette, DOM'un bellek içi temsili olarak React'in Sanal DOM'u da bir ağaç yapısıdır.
İkili arama ağacı her bir düğüm en fazla olabileceğinden özeldir iki çocuk . Sol çocuk olan bir değere sahip olmalıdır daha küçük iken, ya da ebeveyne eşit sağ alt olması gerekir fazla değer . Bu şekilde yapılandırılmış ve dengelenmiş olarak , logaritmik zamanda herhangi bir değeri arayabiliriz çünkü her yinelemede dallanmanın yarısını görmezden gelebiliriz. Ekleme ve silme , logaritmik zamanda da gerçekleşebilir. Ayrıca, en küçük ve en büyük değer , sırasıyla en soldaki ve en sağdaki yaprakta kolaylıkla bulunabilir .
Ağaçta geçiş, dikey veya yatay bir prosedürde gerçekleşebilir. Gelen Derinlik-ilk geçişi (DFT) dikey yönde, yinelemeli bir algoritma, yinelemeli bir daha zarif. Düğümler ön sırayla , sırayla veya sonradan sırayla geçilebilir . Yaprakları incelemeden önce kökleri keşfetmemiz gerekirse ön sipariş vermeliyiz . Ancak yaprakları kökten önce keşfetmemiz gerekirse sipariş sonrası tercih yapmalıyız . Adından da anlaşılacağı gibi, in-order , düğümleri sıralı sırayla geçmemizi sağlar . Bu özellik İkili Arama Ağaçlarını sıralama için en uygun hale getirir .
Gelen Genişlik-ilk geçişi yatay yönde (BFT), tekrarlayıcı bir yöntem, bir özyinelemeli bir daha zarif. Bu, queue
her yinelemeyle tüm alt düğümleri izlemek için a'nın kullanılmasını gerektirir . Ancak böyle bir kuyruk için gereken bellek önemsiz olmayabilir. Bir ağacın şekli derinden daha genişse, BFT, DFT'den daha iyi bir seçimdir. Ayrıca, BFT'nin herhangi iki düğüm arasında aldığı yol, mümkün olan en kısa olanıdır.
Bir Binary Search Tree
kod içi örneği :
Grafik
Bir ağaç birden fazla ebeveyne sahip olmakta özgürse, a olur Graph
. Düğümleri bir grafikte birbirine bağlayan kenarlar yönlendirilmiş veya yönsüz, ağırlıklı veya ağırlıksız olabilir . Hem yönü hem de ağırlığı olan kenarlar vektörlere benzer .
Şeklinde birden çok miras Katmalar ve veri nesneleri bir çok-çok ilişki grafiği yapılarını üretir. Bir sosyal ağ ve internetin kendisi de grafiklerdir. Doğadaki en karmaşık grafik, sinir ağlarının makinelere süper zeka sağlamak için kopyalamaya çalıştığı insan beynimizdir .
Bir Graph
kod içi örneği :
TK
Hash Tablosu
Bir Karma Tablosu bir sözlük benzeri bir yapı olduğunu çifttir anahtarlar için değerler . Her bir çiftin belleğindeki konum, hash function
bir anahtarı kabul eden ve çiftin girilmesi ve alınması gereken adresi döndüren a tarafından belirlenir . İki veya daha fazla anahtar aynı adrese dönüştürülürse çarpışmalar meydana gelebilir. Sağlamlık için getters
ve setters
tüm verilerin kurtarılabilmesini ve verilerin üzerine yazılmamasını sağlamak için bu olayları önceden tahmin etmelidir. Genellikle linked lists
en basit çözümü sunar. Çok büyük masalara sahip olmak da yardımcı olur.
Adreslerimizin tamsayı dizileri halinde olacağını biliyorsak, Arrays
anahtar-değer çiftlerimizi saklamak için kullanabiliriz . Daha karmaşık adres eşlemeleri için Maps
veya kullanabiliriz Objects
. Karma tablolar , ortalama olarak sabit zaman ekleme ve arama özelliğine sahiptir . Çarpışmalar ve yeniden boyutlandırma nedeniyle, bu ihmal edilebilir maliyet doğrusal zamana kadar büyüyebilir. Ancak pratikte, hash işlevlerinin yeterince akıllı olduğunu varsayabiliriz ki, çarpışmalar ve yeniden boyutlandırma nadir ve ucuzdur. Anahtarlar adresleri temsil ediyorsa ve bu nedenle hashing gerekmiyorsa, basit bir çözüm object literal
yeterli olabilir. Tabii ki, her zaman bir değiş tokuş vardır. Anahtarlar ve değerler arasındaki basit yazışma ve anahtarlar ile adresler arasındaki basit ilişkilendirme, veriler arasındaki ilişkileri feda eder . Bu nedenle, karma tablolar verileri depolamak için yetersizdir .
Bir değiş tokuş kararı depolamaya göre geri almayı tercih ederse, başka hiçbir veri yapısı arama , ekleme ve silme için karma tabloların hızıyla eşleşemez . Bu nedenle, her yerde kullanılması şaşırtıcı değil . Veritabanından sunucuya, istemciye, karma tablolar ve özellikle karma işlevler , yazılım uygulamalarının performansı ve güvenliği için çok önemlidir. Veritabanı sorgularının hızı, büyük ölçüde kayıtları sıralı bir şekilde gösteren dizin tablolarının tutulmasına bağlıdır . Bu şekilde, ikili aramalar logaritmik zamanda gerçekleştirilebilir ve bu özellikle Büyük Veri için büyük bir performans kazanımıdır .
İstemci hem de sunucu üzerinde birçok popüler kütüphaneler kullanan Memoization performansı en yükseğe çıkarmak için. Bir hash tablosunda giriş ve çıkışların kaydını tutarak , fonksiyonlar aynı girişler için yalnızca bir kez çalışır. Popüler Reselect kitaplığı, Redux özellikli uygulamalardaki mapStateToProps
işlevleri optimize etmek için bu önbelleğe alma stratejisini kullanır . Aslında, kaputun altında, JavaScript motoru aynı zamanda yığınlar adı verilen karma tabloları da kullanır ve oluşturduğumuz tüm verileri depolamak için. Onlar erişilir işaretçiler üzerinde çağrı yığını .variables
primitives
İnternet kendisi de dayanıyor algoritmalar karma güvenli işleve. İnternetin yapısı, herhangi bir bilgisayarın birbirine bağlı cihazlardan oluşan bir ağ aracılığıyla başka herhangi bir bilgisayarla iletişim kurabileceği şekildedir. Bir cihaz internette oturum açtığında, aynı zamanda veri akışlarının geçebileceği bir yönlendirici haline gelir . Ancak, bu iki ucu keskin bir kılıçtır. Bir merkezi olmayan mimari aracı ağdaki herhangi bir cihaz dinlemek ve röle yardımcı olduğunu veri paketleri ile kurcalamaya yapabilirsiniz. MD5 ve SHA256 gibi karma işlevler, bu tür ortadaki adam saldırılarının önlenmesinde kritik bir rol oynar . HTTPS üzerinden e-ticaret, yalnızca bu hashing işlevleri kullanıldığı için güvenlidir.
İnternetten esinlenen blockchain teknolojileri , web'in yapısını protokol düzeyinde açık kaynak yapmaya çalışır . Her veri bloğu için değişmez parmak izleri oluşturmak için karma işlevlerin kullanılmasıyla , esasen tüm veritabanı, herkesin görmesi ve katkıda bulunması için web üzerinde açık bir şekilde var olabilir . Yapısal olarak, blok zincirleri, kriptografik karmaların ikili ağaçlarının tek tek bağlantılı listeleridir. Hashing o kadar şifreli ki, bir finansal işlem veritabanı herkes tarafından açıkta oluşturulabilir ve güncellenebilir ! İnanılmaz çıkarım, paranın kendisini yaratmanın müthiş gücüdür . Bir zamanlar yalnızca hükümetler ve merkez bankaları için mümkün olan şey, artık herkes güvenli bir şekilde kendi para birimini oluşturabilir ! Ethereum'un kurucusu ve Bitcoin'in sahte kurucusu tarafından fark edilen temel fikir budur .
Giderek daha fazla veritabanı açığa çıktıkça, tüm düşük seviyeli kriptografik karmaşıklıkları soyutlayabilen Ön Uç Mühendislerine olan ihtiyaç da artacaktır. Bu gelecekte, ana farklılaştırıcı olacak kullanıcı deneyimi .
Bir Hash Table
kod içi örneği :
Bu veri yapılarını ve daha fazlasını kullanan algoritma alıştırmaları için bkz: JavaScript'te Algoritmalar: 40 Problemler, Çözümler ve Açıklamalar
Sonuç
Mantık, sunucudan istemciye gittikçe daha fazla ilerlerken , ön uçtaki veri katmanı en önemli hale gelir. Bu katmanın doğru yönetimi, mantığın dayandığı veri yapılarının ustalığını gerektirir. Hiçbir veri yapısı her durum için mükemmel değildir, çünkü bir mülk için optimizasyon her zaman diğerini kaybetmeye eşittir. Bazı yapılar veri depolamada daha verimlidir, bazıları ise bunlar arasında arama yapmak için daha başarılıdır. Genellikle biri diğeri için feda edilir. Bir uçta, bağlantılı listeler depolama için idealdir ve yığınlar ve kuyruklar ( doğrusal zaman) haline getirilebilir . Diğer yandan, hash tablolarının arama hızıyla ( sabit zaman) başka hiçbir yapı eşleşemez . Ağaç yapıları ortada bir yerde bulunur ( logaritmik zaman) ve doğanın en karmaşık yapısını yalnızca bir grafik gösterebilir: insan beyni ( polinom zamanı ). Bir rock yıldızı mühendisinin ayırt edici özelliği ne zaman ve neden olduğunu ayırt etme ve ifade etme becerisine sahip olmak .
Bu veri yapılarının örnekleri her yerde bulunabilir . Veritabanından sunucuya, istemciye ve hatta JavaScript motorunun kendisine kadar, bu veri yapıları , silikon yongalar üzerindeki açık ve kapalı "anahtarları" gerçekçi "nesnelere" dönüştürür. Sadece dijital de olsa, bu nesnelerin toplum üzerindeki etkisi muazzam. Bu makaleyi özgürce ve güvenli bir şekilde okuyabilme yeteneğiniz, internetin müthiş mimarisine ve verilerinin yapısına kanıtlar. Yine de bu sadece başlangıç. Önümüzdeki yıllarda yapay zeka ve merkezi olmayan blok zincirleri, insan olmanın ne anlama geldiğini ve hayatımızı yöneten kurumların rolünü yeniden tanımlayacak. Varoluşçu içgörüler ve kurumsal aracılık, nihayet olgunlaşmış bir internetin özellikleri olacaktır.
Bu daha adil bir gelecekte, biz doğru yardım geçiş bize To HeartBank® kanal şebekeleri yapay nöronların bizim aşılamak için Kiitos insanlığın durumunu empati kapasitesi ile birleştiğinde blockchain üzerine konu para gücü ile. Gönderen isimsiz teşekkür verdiğimiz ve yazarak alma Kiitos , Kiitos bizim hakkında öğrenir kindnesses ve bunların etkileri kişisel özgürlük ve özgürlük koruyan kademeli ve gizemli süreçte, aramızdaki ekonomik eşitsizlikleri azaltan şekilde bize ödüllendirme. Belki de doğadaki nihai grafik yapısı insan beyni değil, insandır, keşke hepimizi birbirine bağlayan kalp tellerini görebilirsek .
Blockchain ile ilgileniyor musunuz? Ethereum öğrenin ve gelin bizim için çalışın!
Ethereum dApp Geliştirme İçin Tam Bir Zihinsel Model