Skip to content

Commit 8b7f065

Browse files
authored
Update FinalExam.md
1 parent b5523ee commit 8b7f065

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

FinalExam.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,183 @@ pub fn do_something() {
500500
**c)** Deadlock
501501

502502
**d)** Handles değişkeni için derleme zamanında Value Moved Here hatası alınır
503+
504+
## Soru 12
505+
506+
Rust’ın güçlü bir paket yönetim sistemi vardır. Yardımcı küfeler **Crates.io** portali üzerinde yayınlanır. **rand**, **tokio**, **serde** gibi birçok araç vardır. Aşağıdaki komutlardan hangisi bir rust projesine doğru şekilde paket ekler.
507+
508+
**a)** cargo add tokio -F full
509+
510+
**b)** cargo expand with tokio
511+
512+
**c)** add crate tokio
513+
514+
**d)** crate add tokio
515+
516+
## Soru 13
517+
518+
**Thread**’ ler arasında veri transferi için kanallar _(channels)_ kullanılır. Rust standart kütüphanesi varsayılan olarak **Multi-Producer Single Consumer _(MPSC)_** modelini kullanır. Aşağıdaki örnek kod parçasında örnek bir kanal kullanımı ele alınmaktadır. Bu programın çıktısı şıklardan hangisinde doğru şekilde açıklanmıştır.
519+
520+
```rust
521+
use std::sync::mpsc::channel;
522+
use std::thread;
523+
use std::time::Duration;
524+
525+
use rand::Rng;
526+
527+
fn main() {
528+
process_reports();
529+
}
530+
531+
pub fn process_reports() {
532+
let (transmitter, receiver) = channel();
533+
534+
let reports = [
535+
"salary.json",
536+
"invoices.json",
537+
"summary.json",
538+
"personnel.json",
539+
];
540+
541+
for report in reports {
542+
let transmitter = transmitter.clone();
543+
thread::spawn(move || {
544+
let mut rng = rand::thread_rng();
545+
let sleep_time = rng.gen_range(2..=5);
546+
transmitter
547+
.send(format!("Processing '{}' report...", report))
548+
.unwrap();
549+
550+
thread::sleep(Duration::from_secs(sleep_time));
551+
552+
transmitter
553+
.send(format!(
554+
"Finished processing '{}' in {} seconds",
555+
report, sleep_time
556+
))
557+
.unwrap();
558+
});
559+
}
560+
561+
drop(transmitter);
562+
println!("Started the processing reports");
563+
for result in receiver {
564+
println!("Status {}", result);
565+
}
566+
println!("Completed the processing reports");
567+
}
568+
```
569+
570+
**a)** Transmitter nesnesi klonlanmasına rağmen value moved here hatası oluşmasına neden olur, bu yüzden kod derlenmez.
571+
572+
**b)** thread :sleep metodu ile gerçekleşen duraksama ana thread’ in kilitlenmesine neden olacağından deadlock durumu oluşur
573+
574+
**c)** Program rapor dosyalarını sıralı olarak ele alan thread’ ler başlatır. Dosya işlemleri sembolik olarak rastgele üretilen sürelerde tamamlanır, işlem sonuçları kanal üzerinden yakalanır ve durumları ekrana basılır.
575+
576+
**d)** Program rapor dosyalarını sistemde bulamayacağından FileNotFoundException vererek sonlanır.
577+
578+
## Soru 14
579+
580+
Rust dilinde **meta programlama** yetkinlikleri için **makrolar** yaygın şekilde kullanılır. Makrolar yardımıyla kod tekrarları azaltılabilir, daha okunabilir kodlar oluşturulabilir, derleme zamanında kaynak kod üzerinde değişiklikler yapılabilir.
581+
582+
```rust
583+
macro_rules! create{
584+
($struct_name:ident, $($field_name:ident: $field_type:ty),*) => {
585+
#[derive(Debug)]
586+
struct $struct_name {
587+
$(
588+
$field_name: $field_type,
589+
)*
590+
}
591+
592+
impl $struct_name {
593+
fn new($($field_name: $field_type),*) -> $struct_name {
594+
$struct_name { $($field_name),* }
595+
}
596+
}
597+
};
598+
}
599+
```
600+
601+
Yukarıda örnek bir makro tanımı yer almaktadır. Aşağıdaki şıklardan hangisi bu makronun doğru kullanımıdır?
602+
603+
**a)** create!::new(Product, id: i16, title: String, unit_price:double, category: String);
604+
605+
**b)** create{name:Product,{id: i16, title: String, unit_price: f32, category: String}};
606+
607+
**c)** $field_name identifier şeklinde kullanılamaz bu nedenle kod derlenmez
608+
609+
**d)** create!(Product, id: i16, title: String, unit_price: f32, category: String);
610+
611+
## Soru 15
612+
613+
Makrolar, Declarative ve Procedural olmak üzere iki ana katgoriye ayrılır. Bu enstrümanlarla ilgili olarak aşağıdaki seçeneklerde bahsedilen kavramlardan hangisi/hangileri doğrudur?
614+
615+
- **I.** Declarative makrolar hızlıdır ve derleme zamanına etkisi minimal seviyededir ancak Procedural makrolar derleme sürelerinin artmasına neden olur.
616+
- **II.** Procedural makrolar proc-macro olarak adlandırılan ayrı kütüphaneler içerisinde tasarlanır ve dilin sentaksını anlamak için TokenStream’ ler kullanılır.
617+
- **III.** Procedural makrolar derive direktifi ile birlikte kullanılabilirler.
618+
- **IV.** Declarative makrolar macro_rules! makrosu ile oluşturulurlar.
619+
620+
**a)** Sadece IV
621+
622+
**b)** I, II, III
623+
624+
**c)** Hepsi doğrudur
625+
626+
**d)** II ve IV
627+
628+
## Soru 16
629+
630+
Rust eş zamanlı programlama haricinde **asenkron** programlamayı da destekler. Asenkron programlama dosya I/O işlemleri, network stream operasyonları, zaman bazlı görevler ve servis iletişimi gibi alanlarda sıklıkla kullanılır. Asenkron görevlerde **async** ve **await** operatörleri yer alır. Asenkron yapılarda genellikle bir yürütücü mekanizma olur. **Tokio** küfesi bu amaçla kullanılan harici küfelerdendir. Aşağıda bu kabiliyet ile ilgili örnek bir kod parçası verilmiştir.
631+
632+
```rust
633+
use rand::Rng;
634+
use std::time::Duration;
635+
use tokio::sync::mpsc;
636+
use tokio::task;
637+
use tokio::time::sleep;
638+
639+
#[tokio::main]
640+
async fn main() {
641+
let (log_transmitter, mut log_receiver) = mpsc::channel(100);
642+
643+
let cpu_task = task::spawn(fetch_metrics("CPU Service", log_transmitter.clone()));
644+
let memory_task = task::spawn(fetch_metrics("Memory Service", log_transmitter.clone()));
645+
let disk_task = task::spawn(fetch_metrics("Disk Service", log_transmitter));
646+
647+
let logger_task = task::spawn(async move {
648+
while let Some(metric) = log_receiver.recv().await {
649+
println!("LOG: {}", metric);
650+
}
651+
});
652+
653+
let _ = tokio::join!(cpu_task, memory_task, disk_task, logger_task);
654+
}
655+
656+
async fn fetch_metrics(service_name: &str, tx: mpsc::Sender<String>) {
657+
let interval = Duration::from_secs(5);
658+
for i in 1..=10 {
659+
let metric = format!("{} - Metric {}: {}", service_name, i, get_metric());
660+
if tx.send(metric).await.is_err() {
661+
println!("{}: Channel isn't active!", service_name);
662+
break;
663+
}
664+
sleep(interval).await;
665+
}
666+
}
667+
668+
fn get_metric() -> f64 {
669+
let mut rng = rand::rng();
670+
rng.random_range(50.0..100.0)
671+
}
672+
```
673+
674+
Yukarıdaki kod parçası ile ilgili olarak aşağıda verilen bilgilerden hangisi **yanlıştır**?
675+
676+
**a)** Kodda başlatılan görevler(task) fetch_metrics isimli fonksiyonu işletirler.
677+
678+
**b)** Concurrent başlatılan görevler Sender nesnesini kullanarak kanala metric bilgilerini bırakırlar.
679+
680+
**c)** logger_task isimli değişken farklı bir asenkron görevi işletir ve kanala gelen metrik değerleri Receiver nesnesi aracılığıyla okuyarak ekrana yazdırır.
681+
682+
**d)** Concurrent başlatılan görevler birbirine bekler konumda kalan thread’ler oluşmasına sebep olur ve bu durum çalışma zamanında deadlock oluşmasına sebebiyet verir.

0 commit comments

Comments
 (0)