content:
Belum lama ini saya diminta tolong memperbaiki aplikasi lama dalam PHP 5. Aplikasi ini sudah lama dan masih dipakai sampai development aplikasi baru selesai. Aplikasi ditulis dalam PHP dengan framework Code Igniter dengan database MySQL. Deskripsi masalahnya begini: di aplikasi ini setiap hari ada satu halaman yang semakin lambat sampai suatu hari error, tidak bisa diakses lagi.
Pesan popup itu muncul dari komponen datatables.net di browser. Setelah diselidiki: penyebabnya adalah error di sisi server, tepatnya lagi ternyata out of memory di sisi server.
Allowed memory size of 134217728 bytes exhausted (tried to allocate 7077931 bytes) /var/www/html/application/XXX.php
Aplikasi ini meload data dari database menjadi satu file JSON berisi beberapa belas ribu baris. Dari hasil membaca dokumentasi komponen datatables ini, seharusnya mudah membuat paging dengan pemrosesan di sisi server cukup dengan menambah OFFSET dan LIMIT pada query SQL. Tapi ternyata tidak mudah di aplikasi ini.
Kira-kira aplikasinya begini:
$q = "select puluhan_kolom from table where belasan_filter;";
$data=array()
foreach ($rows as $row){
    //isi loop for ini ratusan baris
    //ada beberapa puluh query berdasarkan nilai $row
    //dalam kondisi tertentu data baru ditambahkan ke $data
}
echo json_encode($data);
Jadi untuk tahu berapa jumlah row-nya perlu menjalankan banyak query, bukan hasil count dari query utama. Andaikan tahu jumlah row-nya pun, tetap akan sulit untuk pergi ke halaman-N karena harus memfilter lagi dari awal. Dari berbagai kondisi di dalam loopnya sepertinya banyak hal ad-hoc ditambahkan, atau mungkin juga designnya salah dari awal.
Lalu setelah saya pikirkan lagi: Jika bisa paging pun, fitur lain harus diubah. Datatables menyediakan fitur filtering dan search built in. Jika kita meload data per page, search dan filter ini harus diimplementasikan ulang dengan kode baru di sisi server.
Jadi apa yang bisa saya lakukan? permintaan tolong ini di hari kerja, jadi saya cuma bisa melakukan ini:
menaikkan memory limit PHP
menambah ukuran cache mysql
menginstall PHP opcode cache (APC)
Beberapa hal lain yang tidak saya lakukan:
menginstall PHP 7, karena distribusi Linuxnya terlalu tua. Ribet jika harus menginstall manual
mengubah kode program karena terlalu rumit
Programnya bisa berjalan lagi walau seringkali butuh beberapa menit mendownload JSON sekitar 5.5 MB. Dengan koneksi di indonesia, jika bisa stabil 100 kilobyte/second maka butuh 55 detik untuk mengirim datanya. Itu di luar waktu query, karena transfer data baru bisa dimulai setelah semua data siap. Dari cerita yang saya dapat: Koneksi 100 kilobyte/second (kira-kira 1 Mbit/s) sebenarnya tidak sulit dicapai tapi ketika sambil sharing screen di meeting Zoom, kecepatannya bisa sangat tidak stabil. Belum lagi jika dua orang mengakses halaman yang sama untuk didiskusikan.
Mungkin ada yang heran: memory limit kan 128 MB dan ukuran JSON 5.5MB itu sebenarnya sangat kecil, kenapa bisa out of memory? Struktur internal PHP (terutama PHP versi sebelum 7) sangat tidak efisien, ukuran memori yang dipakai bisa belasan kali lipat dari tipe data dasar di bahasa lain (pernah saya tuliskan di artikel tahun 2009). File JSON itu hanya bentuk akhir saja, array yang menyimpan data sebelum jadi JSON memakai memori besar dan setiap query juga memakan memori.
Quick Fix
Di akhir pekan, saya ubah kodenya seminimal mungkin agar cukup cepat. Pertama yang terlihat jelas adalah mengkompres data. Saya sudah menguji bahwa data JSON hasil aplikasi jika dikompres ukurannya menjadi kurang dari 700kb. Dari kecepatan download saja: data 700 kb bisa didownload dalam 7 detik jika koneksinya 100 kilobyte/second vs 55 detik data aslinya.
Di PHP, kompresi bisa dilakukan dengan:
    ob_start("ob_gzhandler", 16*1024);
    //outputkan data seperti biasa dengan echo
    @ob_end_flush();
Dengan modifikasi kecil ini hasilnya: data bisa diakses kurang dari 7 detik setelah dihasilkan. Masih ada masalah lain: harus menunggu dulu sampai semua query selesai baru bisa dikompresi. Langkah berikutnya adalah mengoutputkan JSON per elemen array. Jadi loopnya diganti kira-kira menjadi seperti ini:
ob_start("ob_gzhandler", 16*1024);
echo '{"data":[';
$first = false;
foreach (/*row*/) {
        if ($data_ok) {
              if ($first)   $first = false; else echo ",";
              echo json_encode($current_data);
        }
}
echo "]}";
@ob_end_flush();
Dengan ini sambil melakukan query, data sudah bisa mulai dikirim ke browser. Aplikasi juga menjadi lebih cepat karena tidak menyimpan data di memori, dan tidak perlu menghasilkan string ukuran besar dengan JSON.
Dengan dua quickfix tersebut plus yang sudah dilakukan sebelumnya (menambah limit memori, memakai cache APC, dan menaikkan limit cache mysql), aplikasi bisa diakses kurang dari 10 detik. Menurut saya ini masih lambat, seharusnya dengan design yang baik, aplikasinya bisa instan menampilkan halaman pertama, dan setiap halaman berikutnya bisa meminta request baru. Tentunya akan lebih banyak kode yang perlu ditulis baik di sisi client maupun server.
Pelajaran
Sebagai catatan: posting ini bukan kritik terhadap PHP. Dalam bahasa manapun kesalahan seperti ini bisa terjadi. Tapi faktor kerakusan memori PHP dan lambatnya PHP versi lama membuat bugnya lebih cepat muncul.
Jika Anda adalah seorang client yang meminta dibuatkan aplikasi: perhatikan ukuran data. Selain menguji bahwa aplikasi sudah berjalan, ujilah juga aplikasi dengan jumlah data yang besarnya sesuai dengan pemakaian. Misalnya ingin membuat aplikasi untuk sekolah offline, jumlah murid mungkin bisa ratusan, atau ribuan sampai beberapa tahun ke depan. Dalam kasus ini jumlah murid tapi tidak akan sampai level jutaan.
Ini juga cerita secara umum: membuat aplikasi sederhana memang tidak sulit, tapi membuat aplikasi yang scalable akan butuh waktu lebih lama dan/atau kode yang lebih banyak. Cerita ini hanya sekedar scaling dari ratusan data (sangat cepat ketika didemokan) sampai ke belasan ribu data (aplikasi sangat lambat lalu mati), belum sampai ke level jutaan atau ratusan juta data yang butuh perencanaan yang lebih matang dan implementasi yang lebih sulit.
This entry was posted in php, umum on July 1, 2020 by admin.
Mencoba Bahasa Dart dan SDK Flutter
Leave a reply
Posting ini akan membahas pengalaman singkat saya memakai bahasa pemrograman Dart dan Software Development Kit (SDK) Flutter di sebuah proyek kecil. Flutter merupakan SDK pembuatan user interface (UI) yang membuat Dart jadi dikenal untuk UI Development. Ini seperti seperti Rails yang membuat Ruby jadi terkenal untuk web development (Ruby on Rails).
Dart programming language
Saya akan bahas sedikit mengenai sejarah bahasa Dart ini supaya jelas bahwa: bahasa ini bukan bahasa baru, dibuat perusahaan besar (Google), memiliki standard resmi (ECMA), dan sudah memiliki sejarah cukup panjang.
Sejarah Dart
Bahasa pemrograman Dart diumumkan Google sejak 2011 dan dirilis publik tahun 2013. Tadinya bahasa ini dikembangkan untuk web browser untuk menyaingi Java Script. Awalnya ada kabar bahwa Virtual Machine untuk Dart akan dimasukkan Chrome, tapi rencananya berubah: Dart ditranslasikan (transcompile) saja ke JavaScript, jadi tidak ada VM khusus Dart dalam browser.
Bahasa Dart ini sempat distandardkan dalam ECMA standard 408 tahun 2014, tapi tahun 2018 bahasanya diubah dengan rilis 2.0 sehingga tidak sepenuhnya kompatibel lagi dengan versi sebelumnya. Spesifikasi terbaru saat ini bisa dilihat di sini. Tapi JavaScript juga terus berubah, plus masih ada saingan bahasa lain yang ditranslasikan ke JavaScript (misalnya TypeScript, CoffeeScript, dsb) jadi Dart kurang menonjol.
Selain Dart, Google juga memiliki bahasa lain yang lebih populer: Go. Selama beberapa tahun nasib dan tujuan Dart ini menurut saya kurang jelas, sampai ketika tahun 2015 Flutter diumumkan.
Bahasa Dart
Bahasa Dart ini menurut saya cukup normal, tidak memiliki konsep yang sangat aneh. Menurut saya ini bagus karena beralih dari berbagai bahasa ke Dart tidak sulit.: “the Dart language aims to be unsurprising“. Contoh sederhana hello world seperti ini:
main()
{
       print("hello world");
}
Berbagai konstruksi standar bahasa Dart mirip dengan bahaca lain yang C-like. Misalnya:
komentar seperti C/C++: /*block comment*/ dan //line comment
sintaks if adalah: if (x) { /*aksi*/ } else { /*aksi lain*/)
sintaks for loop: for (int i=0; i < 10; i++) {/* aksi */}
sintaks while loop: while(kondisi) { /*aksi*/} atau do { /*aksi*/} while (kondisi)
Sintaks OOP-nya juga tidak terlalu jauh dari bahasa C++/Java/C#. Berbagai konsep dari bahasa modern, misalnya mixin, nullable type, null safety, named parameter, async, dsb juga ada di Dart. Ringkasannya: beralih dari bahasa lain ke Dart ini cukup mudah.
Flutter
Flutter adalah SDK yang untuk membuat aplikasi GUI di Android, iOS, Windows, Linux, Web dan Google Fuschia dari satu kode Dart. Flutter juga memungkinkan kita melakukan “live editing“, jadi begitu kode diubah dan disimpan, user interface juga langsung terupdate. Flutter ini diklaim mampu menampilkan user interface 120fps dengan mudah.
Setelah beberapa tahun sejak diumumkan, akhir tahun 2018, Flutter versi 1.0 dirilis. Tapi ternyata sampai saat ini menurut saya Flutter masih belum matang. Masih banyak breaking changes yang muncul. Ini artinya kode yang Anda tulis sekarang mungkin tidak jalan di versi berikutnya.
Kebetulan ada proyek yang saya kerjakan yang membolehkan saya menggunakan Flutter. Ini sekedar proyek Proof Of Concept, jadi nanti bisa ditulis ulang ke bahasa lain. Salah satu alasan kenapa sebuah perusahaan memilih atau menolak bahasa atau teknologi tertentu adalah: takut tidak ada yang bisa meneruskan.
Aplikasi yang saya buat sederhana, memanfaatkan kamera dan Firebase Machine Learning (Firebase ML). Firebase ML adalah bagian dari platform Firebase untuk memudahkan pemakaian machine learning di aplikasi mobile. Contohnya: kita bisa mendeteksi sebuah wajah, dan mendeteksi apakah sedang tersenyum.
Hal-hal yang sudah bagus
Bahasa Dart cukup menyenangkan dan mudah dipakai. Seperti tujuan designnya, bahasa ini dirancang agar tidak mengejutkan dan menurut saya cukup berhasil. Saya tidak punya keluhan khusus di bahasa Dart-nya sendiri.
Flutter sudah didukung oleh Visual Studio Code dengan baik. Instruksi untuk mulai menggunakan Flutter sangat jelas dan saya bisa membuat Hello World dengan cepat. Untuk target Android, Android Studio juga sudah mendukung Flutter dengan baik. Ada tool command line “flutter doctor” yang bisa membantu mendeteksi beberapa masalah dasar.
Library Dart masih sedikit
Beberapa bahasa dianggap terbaik untuk teknologi tertentu karena ketersediaan librarynya. Contoh: Python dianggap terbaik untuk Machine Learning karena sudah ada banyak library Machine Learning tersedia. Jumlah library Dart/Flutter masih sedikit dibandingkan bahasa lain. Library Dart adalah library yang terpakai untuk Dart dan Flutter, sedangkan library Flutter untuk Flutter saja.
Jika dilihat sekilas, memang sepertinya banyak library Dart/Flutter sudah ada, tapi baru terasa ketika membangun aplikasi tertentu. Kadang librarynya sudah ada, tapi fungsi tertentu tidak tersedia.
Kadang sebuah library hanya berjalan untuk versi OS tertentu saja. Plugin resmi juga sifatnya sebagian masih beta, misalnya WebView dan In App Purchase. Kadang library memiliki bug yang lama belum diperbaiki, misalnya di iOS camera memiliki memory leak sejak 2018.
Perlu dicatat bahwa untuk berbagai aplikasi sederhana, library yang tersedia sudah cukup. Aplikasi yang sekedar memakai form yang tidak terlalu kompleks, mengirim data ke web mudah dibuat dan bisa dibuat lebih cepat dibandingkan memakai teknologi lain.
Flutter Masih berkembang
Sistem plugin flutter untuk Android belum lama ini diupdate (Desember 2019), jadi beberapa plugin versi lama tidak berjalan atau memiliki warning. Untuk yang masih berjalanpun, tidak cepat updatenya ke versi terbaru. Saya juga sempat mendapati masalah dengan contoh dari github yang ternyata masih memakai versi plugin lama dan dicampur dengan plugin lain yang memakai library baru.
Semoga saja tidak ada update penting lagi dari Flutter/Dart, karena jika sering ada update maka semakin banyak plugin yang tidak berjalan. Secara umum ini adalah masalah teknologi baru: masih banyak perubahan yang membuat kode lama menjadi tidak berjalan.
Dart kurang cepat
Dibandingkan C, Dart masih puluhan kali atau ratusan kali lebih lambat lebih lambat. Contohnya jika kita ingin memproses gambar dalam Dart, hasilnya akan butuh beberapa detik. Jadi untuk pemrosesan tingkat rendah, sebaiknya memakai plugin atau kode dalam bahasa C.
Dalam kasus aplikasi kecil saya: stream data dari kamera formatnya adalah YUV, sedangkan image library untuk mengencode JPG/PNG perlu input dalam format RGB. Sudah ada yang memberikan kode ini dalam Dart, tapi memproses jutaan piksel ternyata lambat. Supaya cepat, kita harus memanggil kode dalam C.
Komentar: https://github.com/flutter/flutter/issues/26348#issuecomment-617266911
Ini kasus yang nyata dan penting. Contohnya adalah Issue ini di github yang masih aktif dari awal tahun hingga saat ini: https://github.com/flutter/flutter/issues/26348. Untuk pemrosesan di sisi server yang tidak butuh interaktif, 4 detik mungkin cepat, tapi jika tiap kali mengambil foto kamera berhenti selama 4 detik, maka ini akan membuat pengguna kesal.
Foreign Function Interface (FFI) di Dart masih Beta
Jika sebuah bahasa tidak memiliki library atau fitur untuk melakukan sesuatu, maka biasanya kita perlu memakai library dari bahasa lain. Ada banyak cara untuk melakukan ini, misalnya dengan plugin, tapi cara lain adalah dengan FFI (foreign function interface). Intinya kita ingin menulis dalam bahasa tertentu (biasanya C) lalu dipanggil langsung dengan Dart. FFI ini juga kadang dipakai jika Dart terlalu lambat melakukan hal tertentu.
Masalahnya fitur FFI di Dart masih beta, dan tidak bisa dipakai di Dart rilis stabil terbaru. Dalam kasus github yang saya sebutkan sebelumnya: proses yang lambat (butuh beberapa detik dalam dart) bisa selesai dalam hitungan miliseconds di C. Selain itu masih ada kemungkinan berubah:
As of Dart 2.7, dart:ffi is in beta, and breaking API changes might still happen. If you’re developing a Flutter app, you can get access to dart:ffi by using the Flutter dev channel, as described in the Flutter dart:ffi page.
https://dart.dev/guides/libraries/c-interop
Digabungkan dengan beberapa hal di atas, ini jadi masalah yang cukup serius:
Ingin memakai plugin tertentu: ternyata belum ada atau belum diupdate
Ingin diimplementasikan dalam Dart, tapi ternyata tidak cukup cepat
Ingin memakai kode C: tapi FFI tidak bisa jika tidak memakai versi beta
Library kurang cepat diupdate
Saya berharap library Firebase dari Google untuk Flutter cepat diupdate karena Firebase ini adalah produk Google dan Flutter juga produk Google, tapi ternyata tidak demikian. Flutter ini masih dinomorduakan oleh Google dibandingkan yang lain.
Di awal Juni 2020 Ada update Firebase untuk memisahkan bagian AI offline dari yang online di Firebase, tapi sampai saat ini (akhir Juni) belum juga library flutter di update setelah hampir sebulan.
Penutup
Saya berharap Google lebih memperhatikan Flutter lagi. Untuk sistem operasi Google Fuschia, Google akan perlu bahasa yang cocok untuk development aplikasi GUI. Bahasa Go kurang cocok karena sifatnya yang harus dikompilasi (walau kompilasi cukup cepat), sedangkan Google selalu memliki masalah dengan lisensi Java dengan Oracle (dan Kotlin masih sangat erat dengan Java).
Untuk pengembangan cross platform, masih banyak teknologi cross platform lain yang lebih matang (seperti misalnya React Native atau bahkan Cordova). Tapi Flutter ini menurut saya sangat menarik dan developmentnya cukup fun. Jika perkembangannya lancar, mungkin ini bisa jadi bahasa pilihan untuk pembuatan aplikasi GUI.
This entry was posted in Uncategorized on June 27, 2020 by admin.
Assembler di browser berbasis Keystone dengan WebAssembly
2 Replies
Sebenarnya saat ini saya sedang sibuk dengan banyak hal, tapi karena sedang berduka, saya ingin melakukan sesuatu untuk mengalihkan pikiran. Bapak saya suka membongkar mobil untuk mengalihkan pikiran, sedangkan saya lebih suka memprogram sesuatu yang tidak berhubungan dengan pekerjaan. Hasilnya: hari ini saya mengkompilasi framework Keystone dengan target WebAssembly (Wasm) lalu memberi interface HTML dengan Preact (alternatif React yang ukurannya jauh lebih kecil).
Assembler ini bisa diakses online di https://asm.x32.dev dan sourcenya saya berikan di https://github.com/yohanes/online-assembler . Aplikasinya bisa diakses dengan semua browser modern (Safari, Chrome, Firefix, Edge), termasuk juga mobile browser (sudah ditest di iOS 13 dan Android 10).
WebAssembly (Wasam)
Supaya tidak bingung dengan penjelasan assembler dan webassembly, akan saya jelaskan apa itu WebAssembly (biasa disingkat dengan Wasm). WebAssembly adalah format instruksi biner untuk virtual machine (bisa dibayangkan seperti bytecode Java) . Saat ini target utamanya adalah web browser (saat ini sudah disupport di Firefox, Google Chrome, Safari dan Edge). Di masa depan web assembly ini dihrapkan akan bisa dipakai juga di aplikasi desktop maupun server.
Sekarang ini sudah ada compiler supaya kita bisa mengkompilasi bahasa C, C++, Rust, dsb ke kode WebAssembly. Setelah dikompilasi, kodenya bisa dijalankan di browser. Sayangnya API web browser tidak bisa diakses oleh kode web assembly, jadi diperlukan jembatan berupa kode JavaScript.
Keystone
Keystone merupakan library assembler untuk berbagai arsitektur. Diberikan teks assembly, kita bisa memakai library ini untuk mengubahnya menjadi bahasa mesin. Keystone ini sebenarnya memakai bagian dari libary LLVM, tapi diekstrak bagian assemblernya saja. LLVM sendiri merupakan proyek infrastruktur compiler yang memiliki banyak fitur (parser, optimizer, assembler, linker, debugger, dsb) tapi terlalu kompleks dan terlalu besar jika hanya ingin fitur assemblernya saja.
Untuk keperluan development program dalam assembly, Keystone ini belum terlalu layak pakai karena banyak bugnya dan tidak memiliki fitur macro yang ada di banyak assembler modern. Untuk development, sebaiknya pakai saja assembler dari berbagai compiler yang ada. Keystone ini lebih terpakai untuk riset security, patching program, dan berbagai fungsi kecil lain yang overkill jika memakai assembler lengkap dari sebuah compiler. Contoh pemakaian Keystone adalah untuk menyelesaikan soal CTF semacam yang saya selesaikan dua tahun yang lalu.
Jadi supaya jelas: assembly di WebAssembly tidak berhubungan dengan assembler di library Keystone (saat ini keystone belum mendukung web assembly).
EMSDK
Dengan menggunakan emscripten SDK (emsdk), sekarang kita bisa mengkompilasi banyak library dan program yang ditulis dalam bahasa C/C++ dengan target Web Assembly dengan relatif mudah. Jika program atau library memakai configure, kita bisa menjalankan emconfigure ./configure dan jika memakai cmake, kita bisa menjalankan emcmake cmake. Program emconfigure dan emcmake merupakan wrapper, agar ketika configure/cmake dijalankan, maka compiler dan library yang akan dipakai adalah untuk target WASM.
Tentunya tidak semua program dan library bisa dikompilasi dengan mudah. Contoh kode yang tidak bisa dicompile langsung: kode yang butuh library lain, kode yang butuh akses hardware, kode yang butuh akses layanan sistem operasi tertentu, kode yang memakai kode assembly dalam Intel x86 atau ARM, dan masih banyak lagi kasus khusus lain. Dalam kasus seperti ini, kita perlu melakukan porting manual.
Selain mengkompilasi file C menjadi WASM, emsdk juga menghasilkan file Javascript yang gunanya menjadi jembatan antara Javascript dan WASM. Jembatan ini dua arah: kode C yang memanggil fungsi library standar seperti printf akan memanggil kode JavaScript (misalnya kita arahkan menjadi memanggil console.log), dan kita bisa memanggil kode C dari Javascript.
Optimasi ukuran
Saat ini kode yang dihasilkan dari EMSDK masih belum efisien. Library Keystone ketika dicompile dengan target Web Assembly, hasilnya menjadi file 9.7 megabyte. Saat ini ada proyek lain bernama binaryen yang merupakan infrastruktur compiler untuk WebAssembly. Salah satu toolnya adalah wasm-opt yang dapat digunakan untuk mengoptimasi bytecode WASM. Tool yang lain adalah disassembler Web Assembly (disassembler ini saya pakai untuk menyelesaikan soal CTF).
Setelah dioptimasi, library Keystone yang berukuran 9.7 megabyte berkurang menjadi 5.7 megabyte saja. Ketika didistribusikan, file ini masih akan dikompresi dengan gzip dan hasilnya menjadi 1.5 megabyte. Ukurannya memang tidak kecil, tapi kebanyakan foto dan video ukurannya juga sudah ratusan kilobyte.
User Interface
Bagian berikutnya yang perlu dilakukan adalah membuat user interface yang bagus untuk library yang kita compile tersebut. Untuk program yang memakai Simple DirectMedia Layer (SDL) dan OpenGL, kadang kita bisa langsung menjalankannya karena emsdk sudah menyediakan wrapper untuk API HTML Canvas dan WebGL. Sedangkan untuk aplikasi lain, kita perlu membuat interface HTML dan menggunakan JavaScript untuk memanggil kode C.
Alasan saya memporting Keystone agar bisa memakai assembler keystone terbaru dari browser. Sudah ada yang membuat keystone.js tapi sudah lama tidak diupdate.
Tadinya saya hanya ingin memakai HTML + Javascript murni saja untuk user interfacenya. Tapi setelah saya pertimbangkan lagi, memakai library Javascript akan membuat kodenya jadi lebih terstruktur. Tadinya saya akan memakai React, tapi aplikasi kecil dalam React butuh ratusan kilobyte (terutama karena bagian ReactDOM). Jadi saya memakai Preact yang memakai API yang (hampir) sama dengan React tapi ukurannya hanya 9 kilobyte saja (bahkan hanya 4 kilobyte setelah dikompres).
Development JavaScript Modern biasanya dilakukan dengan menggunakan build system, tapi sebenarnya tidak wajib. Karena program saya ini sangat kecil, saya putuskan untuk tidak memakai build system. Semua kode langsung masuk ke file HTML dan JS. Karena saya memakai WASM, browser harus cukup modern, jadi saya bisa memakai berbagai fitur HTML/JS terbaru tanpa butuh berbagai library polyfill.
Penutup
Salah satu cara belajar teknologi Web Assembly adalah dengan memporting berbagai library dan program ke browser dan membuat atau menyesuaikan user interface agar berjalan di browser. Bahasa C/C++ sudah ada sejak lama, dan sudah banyak hal menarik yang dibuat dalam C, berbagai kode yang sudah ada ini bisa dibawa ke browser dan dieksekusi langsung tanpa butuh server (server hanya sekedar untuk menyimpan file saja, tidak untuk eksekusinya).
Semoga artikel singkat ini berguna untuk memulai eksplorasi Web Assembly, dan semoga assembler onlinenya juga bisa terpakai di masa depan, baik untuk saya sendiri maupun orang lain.
This entry was posted in c, html5, javascript, teknis on May 2, 2020 by admin.
Bahasa Pemrograman BASIC
Leave a reply
Setelah membahas Forth dan juga Lua, kali ini saya akan membahas bahasa BASIC (Beginners’ All-purpose Symbolic Instruction Code). Bahasa BASIC ini merupakan bahasa yang sudah ada lama sekali (sejak 1964), tapi ada beberapa hal yang baru-baru ini terjadi yang membuat saya ingin menuliskan tentang bahasa BASIC:
Smile Basic 4 baru dirilis untuk game console Nintendo Switch
Saya melihat seseorang di kontak Facebook yang sedang memberikan pelatihan bahasa BASIC dengan Just BASIC dan banyak peminatnya
Programmer COBOL kembali dibutuhkan di masa Covid-19
BASIC berulang tahun yang ke 56 tanggal 1 Mei
Tiga hal pertama tersebut menunjukkan bahwa:
Minat terhadap bahasa lama (BASIC dan COBOL) ternyata masih cukup besar
Bahasa-bahasa lama ini masih terpakai (tapi dalam artikel ini saya hanya membahas BASIC)
Setelah membaca mengenai SmileBASIC 4, saya segera membeli softwarenya dari Nintendo Shop. Harga softwarenya 25 USD (masih lebih murah dari kebanyakan game di Nintendo Shop), plus harus membeli slot upload seharga 5 USD jika kita ingin mengupload program kita ke server SmileBASIC.
Setelah mencoba-coba lagi Smile BASIC, ternyata memang bahasa BASIC ini masih bisa membuat saya tersenyum Saya masih bisa membuat program dalam bahasa ini dengan cepat, dan bisa membuat animasi sederhana untuk Joshua dalam waktu sangat sebentar (dalam hitungan menit). Saya juga teringat dulu masa-masa saya belajar sendiri bahasa BASIC. Jadi saya ingin bercerita lebih jauh mengenai bahasa BASIC ini.
Animasi huruf yang dibuat hanya dalam beberapa menit
Di masa kejayaannya, BASIC ada di mana-mana:
Ada novel petualangan yang di dalamnya ada kode bahasa BASIC (pernah saya tulis di sini)
Berbagai majalah memberikan listing program bahasa BASIC
Berbagai buku teks mahasiswa juga diberi kode dalam bahasa BASIC untuk bisa langsung dicoba
Banyak orang menghindari bahasa BASIC karena sifatnya yang tidak terstruktur. Ini memang benar untuk BASIC generasi pertama. Ilmuan komputer Djikstra sering dikutip karena mengkritik BASIC, begini katanya:
“It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration”,
Edsger W. Dijkstra – “How do we tell truths that might hurt” . Selected Writings on Computing: A Personal Perspective
Tapi sebenarnya di tulisan lengkapnya, Djikstra tidak cuma mengkritik BASIC, tapi juga bahasa lain seperti FORTRAN dan COBOL yang sampai saat ini masih dipakai.
Setelah kritiknya itu, sebenarnya bahasa BASIC masih berkembang dan generasi berikutnya sebenarnya sudah cocok menjadi bahasa pemula dan bisa digunakan untuk mengajarkan berbagai konsep pemrograman yang baik.
Beberapa Generasi
Bahasa generasi pertama memakai nomor baris, konsep fungsi dan subrutinnya terbatas, dan sulit membuat struktur data kompleks. Contoh keterbatasan adalah: fungsi hanya sekedar formula, tidak bisa membuat fungsi rekursif. Subrutin memakai nomor baris (tidak memakai nama) dan tidak memiliki variabel lokal. Beberapa implementasi bahkan tidak memiliki DEF untuk membuat fungsi. Contoh versi BASIC ini adalah yang ada pada ROM PC XT, dan ROM berbagai hardware komputer rumah tahun 80an.
Seperti apa sih program BASIC ini? ini adalah program sangat sederhana yang tidak berhenti menampilkan “HELLO WORLD”. Programnya mudah dimengerti: cetak tulisan hello world, dan berikutnya GOTO 10, artinya ulangi lagi baris 10, dst.
10 PRINT "HELLO WORLD"
20 GOTO 10
BASIC sangat populer sehingga pernah dibuat dua standard (ISO/ANSI) tentang bahasa BASIC (yang core dan yang full). Kedua standardnya hanya mencakup generasi pertama yang masih menggunakan nomor baris. Bahasa BASIC juga masuk ke banyak device yang bukan PC, misalnya game console dan juga kalkulator.
Saya program HP 39gs untuk menampilkan hari pasaran dari sebuah tanggal
BASIC generasi kedua (Structured Basic) tidak lagi memakai nomor baris (walau beberapa versi secara opsional membolehkan nomor baris), mendukung fungsi dan subrutin dengan variabel lokal, dan mendukung user defined type (struct/record). Contoh BASIC generasi kedua adalah Microsoft QuickBasic.
Tanpa nomor baris, program hello world bisa mirip Python 2 (Python 3 mewajibkan kurung). Apalagi BASIC ini sifatnya tidak case sensitive, jadi PRINT sama dengan print.
print "hello world"
BASIC generasi ketiga sudah seperti bahasa pemrograman lainnya yang berbasis objek, hanya saja syntax-nya meniru BASIC yang lama. Contoh BASIC generasi ketiga ini adalah Visual Basic .NET. Tapi saat ini minat bahasa BASIC generasi terbaru sudah mulai berkurang, bahkan Microsoft sudah tidak akan menambah lagi fitur di Visual Basic.NET.
Menurut saya sendiri, BASIC generasi kedua ini sudah cukup ideal untuk berbagai aplikasi kecil dan program ukuran kecil yang fun. Jika ingin memprogram berorientasi objek, sekalian saja pakai Java/C#/Python atau bahasa lain.
Sederhana
Kenapa bahasa BASIC sempat populer dibandingkan bahasa lain? menurut saya ini gabungan beberapa hal. Masalah utama adalah Keterbatasan hardware: sulit membuat compiler dengan memori terbatas di hardware awal masa komputer personal (awal 1980an). Jadi alternatifnya adalah: memprogram dalam assembly, atau dalam bahasa lain yang sederhana. BASIC menang dibandingkan bahasa lain (misalnya FORTH yang pernah saya bahas di sini), karena sangat mudah dimengerti walaupun baik BASIC maupun FORTH keduanya merupakan bahasa yang interaktif.
Cassette Basic. Pengguna PC XT dulu akan ingat ini. Memori yang bisa diakses kurang dari 64kb
Kesederhanaan Bahasa BASIC ini bisa dilihat dari jumlah statement dasar yang dimiliki. Versi awal yang dikembangkan pencipta BASIC: John G. Kemeny dan Thomas E. Kurtz (disebut Darmouth BASIC) hanya punya 15 statement (LET, PRINT, END, DATA, READ, GOTO, IF, FOR/NEXT, GOSUB, RETURN, DIM, REM, STOP, DEF). Plus ada beberapa fungsi built in seperti misalnya ABS untuk mendapatkan nilai absolute atau SIN/COS/TAN untuk trigonomoetri.
Dengan kesederhanaan ini, mengimplementasikan interpreter BASIC bisa dilakukan dengan memori kecil. Salah satu kesuksesan awal Microsoft (waktu itu namanya masih Micro Soft, bukan satu kata) adalah produk interpeter BASIC yang ditulis oleh Bill Gates dalam assembly (kodenya sudah dibuka, ada di github). Bahkan di kode assembly yang relatif kecil, Bill Gates bisa menyembunyikan Easter Egg.
Kesederhanaan bahasa BASIC juga bisa digunakan sebagai latihan ketika mengimplementasikan sebuah interpreter. Saya sendiri pernah mengimplementasikan interpreter BASIC dalam JavaScript 10 tahun yang lalu (masih berfungsi ada sampai sekarang).
Instan
Kebanyakan implementasi BASIC, bahkan dari jaman PC XT dulu, eksekusinya hampir instan. Dari mengetik kode hingga berjalan tidak dibutuhkan waktu berdetik-detik atau bermenit-menit. Selain itu hampir semua implementasi BASIC menggabungkan editor dan interpreter, jadi mengetik, menjalankan program, dan bahkan mendebug bisa dilakukan di environment yang sama.
Experience memprogram BASIC ini menurut saya masih sulit ditemui di sistem lain, kecuali jika kita mendownload IDE super lengkap dengan ukuran besar. Bahkan berbagai IDE modern dengan fitur lengkap sering sulit dikonfigurasi.
Meskipun cycle untuk mengedit dan menjalankan program bisa cepat, tapi program yang ditulis dalam BASIC relatif lambat. Untungnya sejak awal sebagian besar implementasi BASIC bisa memanggil kode mesin.
Kode dalam bahasa BASIC umumnya dijalankan dalam sebuah interpreter, tapi sejak puluhan tahun yang lalu sudah ada banyak compiler Bahasa BASIC yang bisa menghasilkan native code. Jadi tidak benar jika bahasa BASIC pasti harus diinterpretasi.
Menengok implementasi BASIC Modern
Saat ini ada banyak implementasi BASIC modern, dan saya sudah mencoba cukup banyak. Saya tidak akan membahas semuanya, dan hanya yang menurut saya menarik saja.
QB64
QB64 ini open source dan meniru user interface QBasic/QuickBasic. QB64 tersedia untuk multi platform. Meskipun meniru QBasic, fitur-fitur baru yang dimiliki sangat banyak, termasuk untuk membuat aplikasi serius atau game 3D dan bahkan aplikasi Android. Sayangnya saya tidak suka implementasinya: kode ditranslasikan ke C, alalu dicompile dengan compiler C. Hasilnya: waktu kompilasinya lama, tidak bisa menjalankan program dengan instan seperti QBasic/QuickBasic. Bahkan saat ini versi terbaru dari github yang saya download gagal menjalankan aplikasi hello world.
Just BASIC
Just BASIC ini hanya tersedia di Windows, gratis tapi tidak open source. Kelebihannya dibandingkan solusi yang lain adalah: bisa digunakan untuk membuat aplikasi Windows yang memakai native control di Windows. Just BASIC memakai pendekatan interpreter, dan eksekusinya instan, ketika mengklik RUN, program akan langsung berjalan.
AppGameKit Classic
AppGameKit Classic adalah implementasi BASIC berbayar untuk membuat game. Saya mengenal AppGameKit ini dari Humble Bundle beberapa tahun lalu dan ternyata sampai saat ini masih terus diupdate. Harga penuh aplikasi AppGameKit relatif mahal, tapi sering bisa dibeli murah dengan berbagai diskon dan bundle dari berbagai situs. AppGameKit dapat dipakai untuk membuat game, baik desktop, web, maupun mobile.
Engine utama AppGameKit ini ditulis dalam C++, dan bisa dipanggil langsung dari C++ jika kita mau, tapi mode untuk menjalankan kode BASIC adalah interpretasi. Bahasa BASIC yang didukung adalah generasi 2, jadi kita bisa membuat tipe data sendiri, tapi tidak bisa memakai OOP.
Beberapa tahun lalu ketika mencoba ini, rasanya cukup fun. Cukup mudah membuat game sederhana. Bahkan ada mode sangat bagus untuk membuat game mobile: mode broadcast. Asalkan device Android kita ada di subnet yang sama, kita cukup menjalankan AppGameKit Player di Android, tekan Broadcast di PC, dan akan muncul gamenya di device Androidnya, instan.
SmileBASIC 4
Saya mendengar berita rilis SmileBASIC di Hacker News, jadi ini relatif baru buat saya. SmileBASIC ini juga tersedia untuk game console Nintendo 3DS. Walaupun sulit sekali memprogram dengan layar kecil 3DS, ternyata aplikasi ini cukup populer sehingga mereka membuat versi Nintendo Switchnya.
Bandingkan jumlah memorinya dengan PC XT
Nintendo Switch bisa dihubungkan ke monitor dengan HDMI dan bisa dihubungkan juga ke keyboard dan mouse USB (dan bahkan juga headset USB). Tanpa keyboard USB, kita bisa memprogram dengan keyboard di layar sentuh, tapi ini kurang efisien. Jadi selama saya mencoba SmileBASIC, saya selalu menggunakan keyboard dan mouse dan layar besar (SmileBASIC mendukung sampai dengan resolusi 1280×720).
AppGameKit mudah diprogram, tapi memiliki kelemahan: kita harus mencari sendiri asset (gambar, musik, efek suara) untuk game atau membeli pack terpisah. Sedangkan SmileBASIC memiliki ratusan sprite built in, puluhan music background built in, dan juga puluhan sound effect. Tersedia juga editor bitmap built in jika gambar yang ada tidak seperti yang kita mau.
Tapi SmileBASIC memiliki kelemahan dari segi fitur bahasa BASIC-nya. Meskipun menggunakan BASIC generasi 2 (tanpa line number), tapi SmileBASIC tidak mendukung user defined type.
Penutup
Bahasa BASIC memang sudah tidak terlalu banyak dipakai dibandingkan masa kejayaannya, tapi belajar bahasa ini cukup menyenangkan. Masih ada orang yang bisa mendapatkan uang dari memprogram BASIC. Beberapa game ditulis dalam bahasa BASIC, demikian juga banyak aplikasi sederhana ditulis dalam BASIC. Beberapa aplikasi dalam berbagai bank masih ditulis dengan Visual Basic 6. Meski demikian, jika Anda pemula dan baru mulai belajar pemrograman sebaiknya belajar bahasa lain saja, seperti Python atau PHP.
Belajar bahasa BASIC bisa dipelajari sekedar untuk iseng. Bahasanya sederhana, tidak butuh banyak waktu untuk belajar, tidak seperti belajar Rust, Haskell atau Scala. Bisa juga belajar BASIC supaya bisa belajar membuat interpreter atau compilernya.
This entry was posted in bahasa, umum on May 1, 2020 by admin.
Multithreading dan Multiprocessing di Python
2 Replies
Python adalah salah satu bahasa yang sangat saya sukai, tapi bukan berarti bahasa ini tidak memiliki kekurangan, di tulisan ini saya ingin menunjukkan kekurangan Python dalam memproses data kompleks dengan Python murni (pemrosesan tidak dilakukan di modul native). Kompleks di sini maksudnya pemrosesannya CPU bound (batasan programnya adalah kemampuan CPU, bukan memori atau I/O).
Kelebihan python jelas sangat banyak: mudah dipakai, librarynya banyak, sintaksnya bersih dan mudah dibaca. Library Python untuk berbagai hal (terutama AI) sudah sangat banyak dan banyak yang ditulis dalam native code (C/C++). Dengan library eksternal yang ditulis dalam bahasa C/C++ (kebanyakan library AI), kita tidak perlu memikirkan apapun dalam hal pemrosesan data besar dan kompleks, karena itu dilakukan di level native code.
Multithreading dan Global Interpreter Lock
Dalam banyak bahasa (misalnya C atau Java): jika saya punya algoritma yang lambat untuk data besar, dan datanya masih masuk memori, saya biasanya bisa menyelesaikannya dengan thread. Saya hanya perlu mempartisi data, membuat banyak thread dan mengolah tiap potongan data di thread yang berbeda. Partisi data di sini biasanya mudah: jika bentuknya array, tinggal dibagi saja per N element.
Di Python, solusi dengan multithreading tidak akan berjalan baik karena adanya Global Interpreter Lock. Atau tepatnya lagi: bisa jalan, tapi tidak lebih cepat dari single thread. Adanya GIL berarti di kebanyakan kasus beberapa thread di Python tidak bisa jalan berbarengan. Threading di Python hanya berguna untuk proses yang menunggu I/O (akses file, akses socket, dsb). Jadi jika kita punya prosessor 32 core sekalipun, Python tidak bisa optimal memakai semua core tersebut dengan module threading.
Kadang-kadang mengganti interpreter dengan pypy sudah cukup menyelesaikan masalah komputasi yang berat. Pypy adalah implementasi interpreter Python yang memakai teknologi JIT (Just In Time Compiler), jadi lebih efisien walaupun tetap satu thread saja. Tapi Pypy ini tidak selalu berhasil:
Pypy tidak 100% kompatibel dengan Python
Ada modul-modul yang tidak bisa dipakai di Pypy
Versi Pypy ketinggalan dibandingkan versi Python resmi
Solusi lain seperti Cython juga bisa dipakai, tapi lebih rumit dari sekedar mengganti interpreter.
Multiprocessing
Python memiliki modul multiprocessing, artinya kita bisa menjalankan sebuah fungsi di subproses baru. Overhead untuk memulai proses baru cukup besar, jadi ada kita bisa juga memakai process Pool supaya lebih optimal. Di titik ketika kita membuat subprocess, isi memori saat ini di proses utama akan di-clone ke memori yang sifatnya copy-on-write (COW). Artinya: selama memori tersebut tidak diubah, maka tidak akan dibuat salinannya, hanya akan dishare (dipakai bersama).
Lalu bagaimana kita bisa memanggil fungsi di proses baru dan mendapatkan hasilnya di proses utama? jawabannya adalah: setiap parameter akan di-serialize dan dikirim ke subproses baru. Hasil kembalian fungsi diserialize oleh subproses dan dikembalikan ke proses utama. Ini cukup untuk menyelesaikan banyak masalah. Tapi pendekatan ini tidak sempurna. Proses serialization dilakukan menggunakan modul pickle. Ini titik yang harus diwaspadai, perhatikan contoh kecil ini di mana kita memproses XML dengan minidom.
from xml.dom import minidom
import pickle

myxml = """<?xml version="1.0"?>
<test>
	<item id="11">
		<name>red thing </name>
		<price>100</price>
	</item>
	<item id="12">
		<name>blue thing</name>
		<price>200</price>
	</item>
</test>
"""

doc = minidom.parseString(myxml)

items = doc.getElementsByTagName("item")

firstitem = items[0]

print(firstitem.toxml())

with open("test.bin", "wb") as f:
    f.write(pickle.dumps(firstitem))
Hasil dari pickle bisa dilihat di file test.bin dan jika dilihat dengan editor akan terlihat bahwa ada ‘blue thing’, padahal tidak ada di firstitem. Modul pickle akan melihat semua atribut yang dimiliki oleh sebuah node dan mempickle semuanya, dalam hal ini: parent-nya juga, dan karena parent memiliki semua child, maka semua child-nya juga ikut.
Jika kita menggunakan modul multiprocessing dan mengirimkan satu node ke subprocess, maka yang niatnya hanya mengirimkan satu node, ternyata mengirimkan seluruh DOM ke subprocess. Secara umum, ketika mengirimkan objek apapun, maka kita mulai harus memikirkan: ketika serialisasi dilakukan, apa saja yang akan dibawa oleh objek tersebut.
Objek yang diserialize ini tidak masuk ke memori COW, tapi Python akan mengalokasikan memori baru. Bayangkan jika kita mengirimkan copy seluruh DOM ke semua subprocess (misalnya ada 10 subprocess), hasilnya: penggunaan memori jadi sangat besar. Jika DOM-nya besar, proses serialisasi dan deserialisasi ini juga sangat lambat.
Dalam kasus tertentu, cara yang lebih efisien adalah: kita letakkan apa yang ingin kita proses di objek global, objek global ini akan di-clone ke proses baru (tidak melalui serialization). Ketika kita memanggil subprocess, kita hanya mengirimkan string atau bilangan yang berupa ID. Subprocess kemudian bisa mengakses variabel global berdasarkan ID tersebut. Cara ini efisien dalam mentransfer data dari proses utama ke subprocess, tapi tidak bisa dilakukan untuk sebaliknya. Ketika mengembalikan hasil proses, kita tetap harus memikirkan objek yang kita kembalikan. Untuk nilai kembalian ini, tidak ada trik yang mudah, kita harus berhati-hati agar serialisasi tidak berjalan liar.
Modul multiprocessing juga memiliki beberapa kelas khusus supaya kita bisa mentransfer data dengan lebih efisien antar proses (Queue, Pipe, Manager), tapi penggunaanna cukup rumit dan tidak intuitif, dan rawan salah. Ini juga tidak menyelesaikan masalah serialisasi data kompleks.
Mungkin sebagian orang akan bilang: ah kan gampang, cukup kita lihat setiap kelas yang kita miliki dan cek satu persatu membernya supaya jelas apa yang diserialisasi. Ada beberapa masalah:
Kode kadang ditulis anggota team lain, dan tidak jelas tipe data sebuah variabel member, lebih sulit lagi jika ada list atau dictionary yang tipe datanya tidak jelas
Kadang kita memakai library orang lain (contoh kecil: XML, Graph), yang tidak mudah untuk dimodifikasi. Andaikan bisa dimodifikasi: kita harus memaintain library itu jika ada versi baru
Untuk masalah pertama: Python saat ini memiliki type hint, kita bisa memberikan hint apa tipe sebuah variabel/member. Tipe data tidak akan dicek oleh interpreter python, tapi IDE yang kita pakai bisa membantu mengecek tipe data. Untuk masalah kedua: ini lebih sulit, kita bisa menulis serializer/pickler khusus untuk object tertentu (bisa dibaca di dokumentasi Python), atau menggunakan setstate__ dan __getstate untuk memproses secara khusus member variable tertentu.
Solusi Third Party
Dulu orang menyarankan: pakai saja Jython (implementasi Python dalam Java) atau IronPython (implementasi Python dalam .NET), keduanya tidak memakai Global Interpreter Lock, jadi thread bisa berjalan cepat. Tapi masalah dengan solusi dari pihak lain adalah: maintenance. Sekarang ini baik Jython maupun IronPython tidak dimaintain lagi. Belum lagi dukungan modul yang kurang lengkap.
Saat ini ada beberapa pendekatan lain untuk memudahkan masalah multithread/multiprocess, misalnya Ray, tapi ini masih kurang populer dan kode kita harus diubah untuk mengikuti model komputasi Ray, library ini pun punya masalahnya sendiri. Tentunya saya tetap khawatir dengan library apa saja dari 3rd party bahwa proyek semacam ini tidak bertahan lama.
Data Ukuran Sedang
Masalah yang saya contohkan di atas itu adalah kasus yang sudah saya temui beberapa kali. Jika dari awal diketahui bahwa data akan sangat besar, saya akan memecah data menjadi banyak bagian, lalu membuat proses khusus yang bisa memproses data yang sudah dipecah, atau bahkan menggunakan sistem terdistribusi. Jika data sangat kecil, saya juga tidak akan menggunakan threading sama sekali, cukup satu proses.
Perlu dicatat bahwa jika kita terlalu buru-buru berusaha memakai sistem terdistribusi untuk data yang masih muat di memori, performancenya justru tidak bagus (belum lagi biaya ekstra yang dikeluarkan untuk banyak server). Artikel tahun 2014 ini merupakan contoh yang bagus bahwa kadang command line tools bisa 235 kali lebih cepat dari Hadoop. Ini kasus yang sangat ekstrem, tapi pelajaran yang bisa dipetik adalah: kalau datanya kurang besar, overhead memakai Hadoop atau sistem lain kadang sangat besar.
Contoh yang biasa saya temui adalah: ada program yang hanya memproses sebuah file, biasanya ukurannya puluhan megabyte, tapi kemudian filenya bertumbuh jadi beberapa gigabyte, nilai ini besar (beberapa puluh kali lebih besar dari input biasanya) tapi masih jauh di bawah memori yang tersedia (misalnya server dengan memori 16-256 GB). Program yang tadinya butuh beberapa detik menjadi beberapa menit atau bahkan puluhan menit, sedangkan ketika diubah menjadi multiprocess, tiba-tiba pemakaian memori Python menjadi beberapa puluh gigabyte (karena masalah serialization) dan malah lebih lambat lagi. Memperbaiki skrip seperti ini bisa butuh waktu yang cukup lama.
Secara umum saya tidak suka dengan pendekatan multiprocessing ini: saya memakai bahasa yang managemen memorinya otomatis (contoh: java, C#, Python, Javascript) karena ingin memori diatur otomatis oleh sistem. Kalau memang ingin mengatur memori manual sendiri, lebih baik saya memakai C/C++ sekalian.
Penutup
Python tetap merupakan salah satu bahasa yang saya sukai dan saya tetap akan memakainya untuk berbagai hal. Posting ini hanya untuk menunjukkan bahwa Python juga memiliki keterbatasan. Dengan memahami batasan ini, kita bisa mempertimbangkan:menggunakan pendekatan lain dalam memproses data dengan Python atau memakai bahasa lain yang lebih cocok untuk masalah tersebut.
Perlu dicatat juga bahwa tiap bahasa bisa berubah, baik sintaksnya maupun implementasinya. Contohnya: NodeJS baru punya Worker Thread di Node JS 10 sebagai fitur experimental dan harus diaktifkan dengan flag khusus. Baru pada Node JS 12 yang baru dirilis April tahun 2019 API Worker Thread dianggap stabil dan layak dipakai produksi. Jadi mungkin saja suatu saat masalah multithread ini akan berubah di Python.
This entry was posted in bahasa, python on November 26, 2019 by admin.
Mengenal Bahasa Pemrograman Lua
Leave a reply
Di kesempatan kali ini saya akan memperkenalkan bahasa Lua. Bahasa ini sebenarnya sudah ada cukup lama (sejak 1993), tapi kurang terkenal secara umum. Lua lebih sering dijadikan bahasa scripting untuk aplikasi dan sering kali nama Lua tidak disebut sama sekali. Lua artinya “Bulan” (moon) dalam bahasa portugis. Lua diciptakan oleh Roberto Ierusalimschy, Luiz Henrique de Figueiredo, dan Waldemar Celes, anggota dari Computer Graphics Technology Group (Tecgraf) di Pontifical Catholic University of Rio de Janeiro, di Brazil.
Lua bisa dipakai untuk membuat program/aplikasi seperti bahasa lain, tapi kelebihan bahasa ini adalah dari awal dirancang untuk diembed dalam sebuah aplikasi lain (terutama dalam bahasa sejenis C). Di-embed ini artinya bisa bisa dipakai untuk sistem plugin atau bisa dipakai untuk mengontrol bagian business/game/app logic sementara bagian yang butuh performance tinggi memakai C atau bahasa lain. Lua juga bisa jadi file konfigurasi yang sangat fleksibel.
Lua dipakai di banyak software misalnya Adobe Lightroom, Nmap, Wireshark, dan lighttpd. Seperti saya sebutkan di awal, sering kali berbagai aplikasi menyebutkan bahasa Lua ini hanya sekilas, dan fitur aplikasinya yang lebih ditekankan dengan nama lain, misalnya dokumentasi Nmap menyebutkan tentang Nmap Scripting Engine (NSE) tapi Lua hanya disebut sekilas di tengah. Lua juga banyak dipakai di berbagai game (misalnya World Of Warcraft, Angry Birds) dan game engine. Interpreter Lua ukurannya sangat kecil sehingga bisa dipakai untuk embedded system/IOT (misalnya NodeMCU dan eLua).
Bahasa Lua
Bahasa Lua menurut saya relatif sederhana, tapi juga sangat fleksibel. Sintaksnya tidak aneh, sedikit mirip BASIC atau pascal. Contohnya seperti ini:
print "hello, berapa umur kamu?"
umur = io.read("*n")
if umur >= 17 then
   print("Halo kakak")
else
   print("Halo adik")
end
Bagi sebagian orang mungkin ini agak aneh mengingat bahasa sekarang sudah tidak lagi memakai kata-kata (“then”, “end”) tapi lebih memakai simbol ({} di C/C++/Java/.NET, indentasi di Python), tapi untuk yang dulu memakai Pascal dan BASIC ini terasa cukup wajar. Sebagian besar syntax Lua mirip dengan bahasa lain, tapi ada beberapa hal yang agak aneh. Di Lua, operator kurang dari, lebih besar, sama dengan, semuanya sama dengan bahasa lain (<, >, =) tapi untuk tidak sama dengan, syntax yang dipakai adalah ~=. Syntax untuk komentar juga agak kurang standar, memakai “–” untuk satu baris, dan memakai –[[ untuk komentar multi baris –]].
Secara umum bahasa Lua cukup mudah dibaca bahkan oleh pemula, tidak seperti bahasa Forth (yang saya bahas sebelumnya) atau bahasa fungsional seperti Scala.
Tipe primitif yang didukung Lua adalah: string, number, dan integer. Struktur data utama di Lua adalah table. Secara umum: tabel memetakan sesuatu ke sesuatu yang lain (seperti Map/Dictionary di bahasa lain). Hampir semua hal di Lua diimplementasikan dengan table. Sebuah array di Lua juga adalah tabel yang memetakan indeks dengan sebuah nilai, dengan nilai index awal default adalah 1. Masalah index ini agak mengganggu bagi saya, karena di bahasa lain biasanya array berbasis 0. Sebuah tabel bisa berisi tabel lain untuk merepresentasikan array multi dimensi.
Sebuah struktur (struct) juga bisa direpresentasikan dalam bentuk tabel (memetakan nama field sebagai string ke nilainya). Di Lua, sebuah fungsi juga bisa masuk ke dalam tabel. Contohnya kita bisa saja membuat tabel yang berisi berbagai operasi matriks yang berisi pemetaan nama operasi, misalnya “multiply” dengan implementasi fungsi perkalian matriks.
Lua juga memiliki konsep metatable, yang bisa digunakan untuk mendefinisikan operasi terhadap sebuah variabel. Dengan setmetatable(variabel, sebuahtabel), kita bisa mendefinisikan berbagai operator dan fungsi yang berlaku untuk variabel tersebut. Jadi jika kita ingin membuat sebuah variabel menjadi sebuah tipe matriks, kita bisa membuatnya dengan setmetatable(variabel1, tabel_operasi_matriks).
Lua tidak memiliki konsep OOP tapi dengan menggunakan berbagai trik table, metatable dan fleksibilitas function di Lua, kita bisa mengimplementasikan Object Oriented Programming. Saya sendiri kurang menyukai ini, kalau saya ingin memprogram dengan paradigma OO, saya akan memilih bahasa lain.
Fitur Lua lain yang menarik adalah coroutine, generalisasi dari subrutin, tapi fitur ini jarang saya pakai. Sebenarnya fitur ini powerful, tapi ketika melakukan embeding Lua ke bahasa lain (terutama C), fitur ini cukup merepotkan karena tidak mudah dipetakan ke C.
Embeding Lua ke bahasa C
Seperti sudah saya sebutkan di atas, fitur Lua adalah sangat cocok untuk diembed ke sebuah aplikasi. Sebenarnya bahasa lain seperti Python dan Ruby juga bisa diembed ke bahasa lain (misalnya C), tapi ada banyak kelebihan Lua:
Ukurannya sangat kecil, ratusan kilobyte. Python butuh minimal beberapa megabyte (disk space dan memori)
Mendukung multi thread (satu thread menjalankan instance Lua terpisah). Untuk embedding multi thread di Python sangat sulit, dan Python memiliki Global Interpreter Lock
Interfacing sangat mudah, baik coding manual atau dengan bantuan SWIG
Implementasi utama Lua adalah dalam bahasa C, walau ada juga Lua untuk Java. Kebanyakan bahasa memiliki build system yang kompleks dan butuh banyak library tambahan. Dalam kasus Lua: kita cuma perlu copy paste semua file .c (kecuali lua.c) ke project kita dan itu sudah cukup. Sebagai catatan: selain implementasi utama Lua, ada juga LuaJIT yang sangat cepat namun memiliki banyak batasan terutama di sistem 64 bit.
Setelah memasukkan semua file C dalam project kita, di bagian program yang butuh Lua, kita perlu menginclude beberapa file:

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

Lalu kita bisa menginstansiasi interpreter Lua. Jika diperlukan, kita bisa membuat banyak instance (misalnya satu di setiap thread). Setelah itu biasanya kita ingin agar library standar Lua diaktifkan, jadi kita memakai luaL_openlibs.
lua_State *L = luaL_newstate();
luaL_openlibs(L);
Biasanya skrip Lua akan diletakkan di luar program, supaya bisa diubah dengan mudah tanpa rekompilasi. Untuk meload dari file, kita bisa memakai luaL_loadfile atau luaL_loadstring jika ingin memakai string. Di banyak Game, file lua dienkrip di file (agar tidak mudah dimodifikasi), lalu didekrip dimemor, dan diload menggunakan luaL_loadstring.

int err = luaL_loadfile(L, "myscript.lua");
if (err) {
       fprintf(stderr, "Failed loading file: %s\n", lua_tostring(L, -1));
       exit(1);
}
Dalam passing parameter ke Lua dan dari Lua, kita menggunakan konsep stack. Kita bisa memasukkan nilai ke stack dengan lua_pushstring/lua_pushnumber/lua_pushinteger, dan bisa mengambil nilai di stack dengan lua_tointeger, lua_tostring, lua_tonumber dan beberapa fungsi lain. Jadi ketika memanggil fungsi di Lua: kita melakukan push value ke stack, dan untuk mengambil nilai dari lua kita akses hasilnya di stack juga.
Kita bisa mencari fungsi yang diimplementasikan di Lua dengan lua_getglobal(L, "namafungsi"), ini akan mempush reference fungsi ke stack. Setelah itu kita bisa mempush nilai parameter untuk fungsi, memanggil fungsinya, dan mendapatkan hasilnya di stack.

lua_getglobal(L, "myfunction");
lua_pushinteger(L, 1); //param 1
lua_pushinteger(L, 2);  //param 2
int err = lua_pcall(L,
    2 /*number of arguments*/,
    1 /*number of result*/,
    0 /*indeks ke error handler, jika 0 maka error akan dipush ke stack*/);
Membuat fungsi di C yang bisa dipanggil oleh Lua juga sangat mudah. Misalnya kita ingin membuat fungsi max yang menerima 2 double dari Lua dan mengembalikan angka terbesar, maka kita cukup membuat ini:

int max_for_lua(lua_State *L)
{
  double num1 = lua_tointeger(L, 1); //param 1 dari Lua
  double num2 = lua_tointeger(L, 2); //param 2 dari Lua

  double max = num1>num2?num1:num2; //logika utama

  lua_pushnumber(L, max); //push ke stack Lua
  return 1; //hanya ada satu nilai kembalian
}
Tentunya keberadaan fungsi ini perlu diberitahukan ke Lua agar bisa diakses oleh skrip Lua. Nama fungsi di C dan Lua bisa berbeda, contohnya fungsi max_for_lua di atas bisa didaftarkan menjadi “my_max” seperti ini:

lua_pushcfunction(lua_state, max_for_lua);
lua_setglobal(lua_state, "my_max");
Penutup
Sering kali saya menemukan di mana saya butuh eksperimen cepat dan tidak ingin sering mengcompile ulang kode program saya. Contoh penggunaan yang baru-baru ini saya lakukan adalah ketika eksplorasi fitur tertentu di iOS. Jika saya mengandalkan objective C atau Swift saja, tiap kali saya mengubah kode (biasanya hanya logic tertentu), akan butuh beberapa detik sampai beberapa puluh detik sampai bisa menjalankan ulang aplikasinya. Walau hanya menekan tombol “run” di XCode yang terjadi di latar belakang adalah: kodenya harus dicompile, dilink, ditandangani secara digital, dicopy ke device, lalu dijalankan. Dengan memindahkan logic ke Lua, saya hanya perlu me-mount direktori dokumen aplikasi dengan ifuse, mengedit file Lua, lalu merestart aplikasinya.
Menambahkan sebuah scripting ke language ke aplikasi memang butuh waktu tapi di sisi lain juga sangat fleksibel karena skrip bisa dimodifikasi dengan cepat dan tidak seperti kode C, tidak perlu dikompilasi ulang. Jika Anda sudah beberapa kali menambahkan fitur scripting ke sebuah aplikasi, menambahkan ke aplikasi berikutnya tidak butuh waktu lama. Untuk aplikasi kompleks kita bisa memakai Simplified Wrapper and Interface Generator (SWIG) untuk mempercepat membuat interface dari C/C++ ke Lua.
Semoga tulisan singkat ini cukup untuk memperkenalkan bahasa Lua dan mungkin juga membuat Anda tertarik untuk menambahkan Lua ke aplikasi yang Anda buat.
This entry was posted in bahasa, lua, teknis on August 3, 2019 by admin.
Dari keyboard ditekan sampai muncul karakter di layar (bagian 3)
Leave a reply
Di bagian sebelumnya sudah dibahas mengenai bagaimana layout text harus dilakukan. Setelah semuanya selesai, maka teks bisa ditampilkan ke layar. Di level aplikasi biasanya kita hanya perlu memanggil semua fungsi dasar untuk menampilkan teks. Di sisi library dan sistem operasi, masih ada langkah ekstra yang harus dilakukan. Teks perlu digambar ke sebuah buffer dan buffer perlu ditampilkan di sebuah permukaan gambar. Driver grafik akan menampilkan buffer tersebut ke layar.
Untuk aplikasi desktop, proses menampilkan teks ini di sisi programmer semudah memanggil fungsi print (mode teks) atau mengeset property tertenty. Jika kita memprogram microcontroller atau embedded system, akan lebih terasa proses berat yang harus dilakukan ketika menampilkan sesuatu. Contoh paling sederhana adalah 7 segment display.
Programmer perlu menyala matikan tiap garis dalam 7 segment display untuk menampilkan angka tertentu.
Display saat ini biasanya menggunakan akses per piksel. Mungkin yang paling sederhana adalah 8×8 dot matrix. Di sini kita perlu mengontrol tiap titik untuk menampilkan huruf/angka/bentuk yang kita mau.
Semakin canggih hardware, biasanya pekerjaan programmer high level akan semakin mudah. Contohnya adalah display LCD jenis seperti ini:
Jpeg
Demikian seri singkat kali ini. Saya akan berusaha membuat seri baru yang membahas dari segi yang lebih low level lagi.
This entry was posted in hardware, teknis, umum on April 11, 2019 by admin.
Dari keyboard ditekan sampai muncul karakter di layar (bagian 2)
Leave a reply
Meneruskan dari tulisan sebelumnya, sekarang kita ke bagian aplikasi. Pertama aplikasi perlu menerima “event” dari Desktop/Window environment. Event ini bermacam-macam, misalnya permintaan untuk meminimize Window, event gerakan mouse, dan event tombol keyboard ditekan.
Setelah tombol ditekan, maka aplikasi akan melakukan update pada struktur datanya. Sebagai pengingat, contoh aplikasi yang saya berikan ada Word Processor. Ini bergantung dari mode saat ini (apakah mode insert atau overwrite, apakah dokumen sifatnya read only dsb). Struktur data yang digunakan pun bisa sangat beragam, tergantung dari fitur yang dimiliki aplikasi.
Dalam sebuah word processor, berbagai algoritma perlu dijalankan sebelum tampilan diupdate di layar. Beberapa algoritmanya misalnya: hyphenation (pemotongan kata), pemeriksa ejaan (dalam kasus tertentu biasanya nanti kata tersebut perlu digaris bawahi merah), perhitungan jumlah kata.
Ketika data di memori perlu ditampilkan di layar, maka ada banyak langkah lagi yang harus dilakukan. Mulai dari pencarian font, layout setiap karakter, dsb.
Sebuah font perlu diload sebelum bisa ditampilkan di layar. Font jaman dulu merupakan font bitmap biasa, tapi font sekarang biasanya merupakan true type font yang memiliki banyak informasi untuk tiap glyph dalam font tersebut. Jika kita memiliki satu kata yang ingin ditampilkan, maka ada kemungkinan:
Satu huruf dipetakan ke satu glyph
Satu huruf dipetakan ke lebih dari satu glyph, contohnya jika ada diacritic
Dua huruf atau lebih dipetakan menjadi satu glyph (contohnya jika ada ligature)
Jika dokumen terdiri dari lebih dari satu bahasa maka hal ini menjadi lebih kompleks lagi, ada bahasa yang ditulis dari kiri ke kanan dan dari kanan ke kiri. Berbagai hal ini biasanya dilakukan dalam tahap yang dinamakan “text-shaping”. Setelah semuanya siap, maka teks bisa ditampilkan di layar.
Bagian berikutnya akan membahas bagaimana teks ditampilkan di layar.
This entry was posted in teknis, umum on December 30, 2018 by admin.
Dari keyboard ditekan sampai muncul karakter di layar (bagian 1)
Leave a reply
Seri tulisan ini akan mencoba menjelaskan apa yang terjadi dari sejak kita menekan tombol di keyboard sampai muncul huruf di layar. Untuk mempersingkat, saya akan mengambil beberapa asumsi:
Keyboard ditekan di sebuah aplikasi yang terbuka (jadi sudah selesai booting)
Sistem operasi yang dipakai modern (bukan DOS, tapi Windows/Linux/OS X)
Aplikasi yang akan saya contohkan adalah sebuah word processor (supaya sederhana, rencananya saya akan menulis dari mengetik di address bar sampai muncul web page)
Keyboard
Ketika tombol di tekan di keyboard, sebuah saklar akan aktif. Ada banyak jenis saklar ini (bisa dibaca di wikipedia) tapi intinya sebuah sirkuit akan tertutup ketika tombol ditekan. Karena jumlah tombol ada banyak, maka digunakan sirkuit matriks pada keyboard untuk mengurangi jumlah koneksi.
Keyboard tidak tahu apa yang tertulis di atas sebuah tombol. Tombol pertama di keyboard QWERTY adalah huruf ‘Q’, tapi di keyboard AZERTY menjadi ‘A’. Keyboard hanya akan mengirimkan kode sebuah tombol, nanti urusan setting di sistem operasi yang akan menginterpretasikan tombol itu menjadi suatu huruf tertentu.
Sebuah keyboard memiliki prosessor, sebuah chip khusus atau microcontroller yang akan melakukan scanning pada matrix keyboard. Di keyboard lama (PS/2), jika ada tombol ditekan maka akan mengirimkan sebuah interrupt ke PC. Di keyboard USB, PC akan melakukan polling (biasanya 150Hz), artinya dalam 1 detik komputer akan bertanya 150 kali pada keyboard: apakah ada tombol yang sedang ditekan?
Jika ingin mengenal bagian ini lebih dalam, kita bisa membeli Arduino, dan keypad matrix sederhana seperti dalam gambar berikut ini.
Atau seperti ini yang lebih jelas terlihat koneksinya
Kita juga bisa membeli keycap satuan untuk keyboard mekanis, dan bahkan merangkai sendiri circuit boardnya. Microcontroller yang digunakan dalam proyek DIY seperti ini biasanya Atmega32u yang mudah diprogram.
Jika ingin membuat keyboard custom sendiri juga tidak sulit. Misalnya kita bisa membuat keyboard yang mengetik alamat email jika satu tombol ditekan. Atau mungkin kita tidak ingin memakai tombol tapi pedal.
Sistem Operasi
Input dari keyboard akan diterima oleh sistem operasi. Untuk keyboard USB, driver HID (human interface device) akan menerima data dari keyboard. Di titik ini, setiap sistem operasi memiliki jalurnya sendiri dalam menangani keyboard.
Di Linux/Unix, jika kita memakai XWindow, maka X Server akan membaca input dari /dev/input/* dan meneruskan eventnya ke berbagai Window yang muncul. Di Windows driver akan mengirimkan message ke System Message Queue.
Shell/Desktop
Ketika sebuah tombol ditekan, maka ada Desktop manager yang akan mengatur: saat ini aplikasi yang aktif yang mana? mana yang menerima input keyboard? kadang ada lebih dari satu aplikasi yang menerima input keyboard, ada aplikasi yang mendaftarkan diri sebagai shortcut handler (misalnya ketika tombol print screen ditekan, maka isi layar akan disimpan ke DropBox).
Berikutnya …
Di sebuah aplikasi akan ada event handler yang menangani input dari keyboard. Ini akan saya bahas di bagian berikutnya.
This entry was posted in teknis, umum on November 30, 2018 by admin.
Membaca Source Code
Leave a reply
Ada beberapa pertanyaan yang ditujukan ke saya yang jawabannya mudah jika sang penanya bisa membaca source code. Sayangnya skill membaca source code ini sering kali tidak dimiliki, padahal sangat diperlukan oleh programmer dan juga para reverse engineer.
Saat ini mungkin sekitar 90% pertanyaan programming bisa dicari jawabannya dengan Google, dan biasanya jawabannya akan ditemukan di situs stack overflow, di blog seseorang, dan kadang di beberapa situs yang memang membahas topik khusus yang dicari.
Tentunya jawaban-jawaban tersebut bisa ditemukan kalau Anda bisa berbahasa Inggris. Minimal tahu beberapa kata kunci untuk mencari, dan sisanya adalah kemampuan membaca teks berbahasa Inggris. Segala macam pertanyaan sederhana sudah ada yang menanyakan, misalnya “how to split string in <java/c/javascript/..>”. Sering kali jawabannya disertai source code fungsinya, misalnya untuk pertanyaan cara split string di C yang tidak ada di library standar.
Selain berbagai jawaban di stack overflow, dan artikel di berbagai situs, ada juga berbagai buku dan dokumen yang bisa dibaca untuk mencari jawaban. Tapi ada satu sumber yang paling akurat untuk pertanyaan programming: source code. Kadang informasi dari dokumentasi bisa salah atau belum diupdate, tapi informasi dari source code tidak akan salah.
Saat ini sebagian besar software yang dipakai sudah open source. Berbagai sistem operasi sourcenya terbuka (Linux, FreeBSD, OS X, dan masih banyak lagi), compiler dan interpreter (gcc, llvm, go, php, python, dsb), editor text biasa ( emacs, notepad++, vi, dsb) atau bahkan IDE (IntelliJ, Eclipse, Visual Studio Code, dsb). Berbagai game, editor audio, konverter video, dsb semuanya ada versi open sourcenya. Berbagai library sudah ada untuk melakukan hampir apa saja, dari mulai decoding format file sampai mengenali wajah dan suara.
Tidak semua software memiliki dokumentasi yang lengkap. Contohnya: meskipun jutaan orang memakai OS X, dan kernel OS X ini open source, sedikit sekali dokumentasi dan buku mengenai internal kernel OS X. Jika untuk software yang sangat populer saja dokumentasinya tidak banyak, tentunya masih ada ratusan ribu software lain yang dokumentasinya lebih sedikit lagi.
Dokumentasi sebuah fungsi di sebuah bahasa juga sering kali tidak menyebut detail implementasi, yang kadang penting dari sisi security, misalnya dokumentasi mt_rand dan mt_srand di PHP tidak menyebutkan bagaimana proses seeding dilakukan jika tidak dinyatakan secara eksplisit. Tentunya ini bisa ditanyakan ke stack overflow, dan dalam kasus ini ada yang menjawab untuk versi PHP yang spesifik (dan dia mendapatkan jawabannya dari source code).
Dari sisi security, kita bisa menemukan kelemahan dari membaca source code. Dalam kasus mt_rand, sudah pernah ada dua bug ditemukan (tahun 2008 dan 2011). Bug di software yang menggunakan PHP sehubungan dengan penggunaan mt_rand juga masih sering ditemukan (misalnya salah satu yang relatif baru di Oktober 2017).
Membaca source code tanpa alasan yang kuat memang jarang dilakukan orang. Tapi ketika terpaksa, sebaiknya kita mampu membaca kode orang lain. Sering kali kita tidak perlu membaca dalam, biasanya hanya sekedar permukaan saja atau langsung spesifik ke bagian tertentu, tergantung kebutuhan. Membaca source code besar tidak bisa seperti membaca novel dari halaman pertama ke terakhir. Membaca source code besar harus memakai berbagai pendekatan.
Pendekatan pertama adalah skimming, sekedar melihat berbagai file yang ada, lalu membuka file tersebut. Cek apakah ada komentarnya. Hal paling penting adalah mengetahui apakah file tersebut dipakai atau tidak. Sebagian file ternyata tidak dipakai, sebagian ternyata hanya dikompilasi jika fitur tertentu diaktifkan (sedangkan defaultnya fitur tersebut tidak aktif).
Hal penting lain yang bisa didapat dari sekedar skimming adalah: library apa yang dipakai oleh program ini atau program eksternal apa yang dipanggil oleh program ini? Kadang ternyata source code yang kita temukan tidak sesuai harapan karena ternyata hanya membungkus library atau command line lain.
Pendekatan berikutnya adalah menjalankan program tersebut. Ini bisa langsung dilakukan jika program tidak perlu dicompile dan tidak butuh server tertentu (contoh: sebagian program butuh server database). Jika program perlu dicompile, langkah ini juga memberikan banyak informasi. Kita jadi tahu file apa saja yang ternyata dicompile, jadi tahu library apa yang dilink, dsb.
Jika sudah bisa menjalankan program, akan lebih baik lagi jika bisa mendebug program. Beberapa program memang sangat sulit didebug, contohnya kernel Linux di Android butuh setup yang tidak mudah, plus perlu belajar memakai GDB. Tapi jika debugger bisa dipakai, maka ini akan memudahkan pemahaman program. Jika debugger tidak bisa dipakai, maka cara lain adalah menggunakan “print” debugging.
Sebagai catatan: berbagai langkah bisa dilakukan bersamaan. Mengkompilasi source code kadang butuh waktu lama (berjam-jam) atau mendownload requirement (berbagai library yang dibutuhkan) butuh waktu berjam-jam. Sementara kompilasi dilakkan, kode bisa dibaca. Kalau kodenya terlalu besar untuk didownload (contoh: ukuran source code Qt ukurannya ratusan megabyte) bisa source code versi online yang dibaca (misalnya di github).
Sebuah IDE akan sangat membantu untuk membaca program: mencari tahu di mana sebuah fungsi didefinisikan, dari mana saja fungsi dipanggil bisa dialakukan dengan mudah. Untuk memahami program sangat besar (misalnya kernel Linux) biasanya sebuah IDE kurang bisa dipakai (terlalu lambat). Sebagai alternatif, program cross reference (misalnya LXR) bisa dipakai.
Jika program memiliki unit test, maka test ini juga bisa menjadi cara untuk memahami fungsi tertentu. Unit test hanya memanggil satu modul program saja untuk menguji kebenarannya, jadi kita bisa mengerti satu bagian kecil program tersebut.
Perhatikan juga bahwa kadang aplikasi yang populer sudah sangat kompleks karena memiliki banyak optimasi. Contohnya jika hanya ingin memahami membuat web server, maka bisa diawali dengan membaca source code sederhana, lalu kemudian bisa diteruskan dengan membaca yang lebih rumit. Jika Anda belum paham dasar web server, dan langsung membaca source code Apache, maka kemungkinan besar Anda akan bingung.
Beberapa hal butuh dasar teori yang baik, contohnya: memahami source code library kompresi butuh dasar teori mengenai kompresi. Memahami implementasi encoder/decoder MP3 juga akan mustahil jika tidak punya dasar teori mengenai pendengaran manusia (dan banyak konsep matematika).
Hal yang paling penting ketika membaca source code adalah: motivasi. Tanpa motivasi tertentu, membaca source code memang sangat membosankan. Motivasi membaca source code ini bisa banyak, dan tergantung masing-masing orang. Beberapa contoh hal yang pernah memotivasi saya:
Ada konfigurasi yang tidak jalan, dan saya tidak mengerti kenapa, sedangkan dokumentasinya kurang jelas
Saya ingin memahami bug tertentu (misalnya ini)
Saya perlu tahu implementasi algoritma tertentu
Saya perlu mencari bug untuk tujuan pentesting. Misalnya ada software lama tapi tidak menemukan eksploitnya di web

label: ceb


content:
Arti Mimpi Mall Yang Harus Anda Ketahui! | detikLifeArti Mimpi Mall Yang Harus Anda Ketahui! | detikLife
Skip to content
Cari untuk:
detik Life
Memperkaya Hidup Dengan Kumpulan Informasi Bermanfaat
Search
Arti Mimpi Mall Yang Harus Anda Ketahui!
Posted on Rabu, 06-Mei-2020 Rabu, 04-November-2020 by admin
Arti Mimpi Mall – detiklife.com. Mall adalah pusat perbelanjaan yang sering di kunjungi banyak orang. Hal ini dikarenakan, mal dianggap memiliki banyak sekali tempat yang menjual sesuatu sesuai dengan kebutuhan kita.
Dan apabila kamu memimpikan berkunjung ke sebuah mall maka menandakan sebuah kemewahan yang kamu miliki. Mal memang terkadang di lambangkan dengan kemewahan dan kemakmuran. Tak ayal jika seseorang bermimpi akan hal ini , artinya hidupnya bergelimang harta.
Nah, berbicara tentang arti mimpi mall, kamu sudah menyiapkan kumpulan dan penjelasan mengenai mimpi tersebut. Jika kalian tadi malam bermimpi tentang mall dan bingung mengenai makna dan artinya. Kalian bisa langsung menyimaknya dalam kumpulan tafsir mimpi mall. Yang mana telah kami sediakan ulasannya berikut ini. Selamat Menyimak!
Makna Mimpi Mall
Arti Mimpi Mall Dan Penjelasannya!
Arti Mimpi Pergi Ke Mall
Bermimpi dirimu pergi ke mall atau pusat perbelanjaan menandakan bahwa kamu sedang dalam posisi yang kuat dari segi finansial. Artinya keuanganmu saat ini sedang berada dalam fase tertinggi. Kamu mampu memenuhi semua kebutuhan yang kamu inginkan. Dan terkadang hal ini membuatmu menjadi boros dan berlebihan. Sebaiknya pergunakan uangmu ini untuk kebutuhan yang penting saja. Sebab kita tidak tahu keuangan kita kedepannya akan seperti apa.
Makna Mimpi Bekerja Di Mall
Memimpikan bahwa dirimu bekerja di mall mengindikasikan bahwa kamu harus memenuhi kebutuhanmu dengan baik. Dan mimpi ini juga menunjukkan bahwa kamu adalah seseorang yang bekerja keras. Kamu sangat gigih dalam bekerja untuk mencapai semua yang kamu inginkan.
Arti Mimpi Belanja Di Mall
Memimpikan membeli sesuatu atau belanja di mall mengindikasikan bahwa kekayaan akan segera mendekatimu. Ini artinya bahwa penghasilanmu saat ini mengalami peningkatan yang pesat. Hal ini dikarenakan bahwa kamu memiliki banyak sekali cara untuk mendapatkan uang. Dan akhirnya kamu bisa meraih kesuksesan yang besar dengan caramu sendiri.
Makna Mimpi Bertemu Musuh Di Mall
Bermimpi bertemu dengan musuhmu di mall menandakan bahwa kamu memiliki banyak peluang emas yang harus kamu manfaatkan. Namun ahli mimpi lain juga mengatakan bahwa bertemu musuh di mall menandakan bahwa kamu akan terlibat konflik dengan seseorang yang memiliki pandangan berlawanan denganmu.
Makna Mimpi Membantu Seseorang Di Mall
Ketika kamu membantu seseorang yang sedang berada di mall artinya kamu memiliki jiwa yang sangat baik. Kamu selalu ingin memberikan hal-hal yang terbaik untuk semua orang. Dan kamu pun adalah seseorang yang tidak egois dan memntingkan kepentinganmu daripada kepentingan orang lain.
Arti Mimpi Mencuri Di Mall
Dan apabila kamu memimpikan bahwa dirimu mencuri sesuatu di pusat perbelanjaan, artinya kamu harus lebih hati-hati lagi. Kamu harus bisa lebih menganalilis situasi yang kamu jalani setiap harinya. Bisa saja akan ada suatu hal yang hilang dari dalam dirimu.
Arti Mimpi Melihat Mall Yang Megah
Jika kamu memimpikan melihat mall yang sangat megah menandakan bahwa kamu adalah seseorang yang sangat detail. Selain itu mimpi ini juga mengindikasikan perubahan akan segera terjadi dalam hidupmu. Namun perubahan ini akan terjadi sesuai dengan lingkup sosialmu. Jika lingkup sosialmu baik maka kamu pun akan bisa berubah menjadi lebih baik lagi dan sebaliknya. Apabila lingkunganmu memberikan hal negatif kepadamu, artinya kamu pun akan berubah ke arah yang lebih buruk.
Arti Mimpi Tersesat Di Mall
Memimpikan tersesat atau nyasar di dalam pusat perbelanjaan yang sangat luas memiliki makna bahwa kamu adalah seseorang yang pemalu. Mimpi ini juga mengacu pada kebingungan dan juga kekhawatiran terhadap seseorang. Mugkin kamu mengkhawatirkan sahabatmu atau keluargamu yang jauh dari dirimu.
Share this:
Facebook
Twitter
WhatsApp
Posted in Arti MimpiTagged Arti Mimpi Bekerja Di Mall, Arti Mimpi Belanja Di Mall, Arti Mimpi Melihat Mall, Arti Mimpi Membeli Sesuatu Di Mall, Arti Mimpi Tentang Mall, Arti Mimpi Tersesat Di Mall

warc-type: conversion

content-type: text/plain

warc-identified-content-language: ind

label: id

annotation: short_sentences header footer

label: en


content: Kami memastikan untuk memberikan produk dan layanan yang dapat diandalkan dan terpercaya bagi para pelanggan, melindungi mereka sepanjang perjalanan dan menghilangkan semua kekhawatiran.

warc-identified-content-language: ind,eng


content:
Olahraga tinju merupakan salah satu jenis olahraga tradisional dan modern yang tidak asing lagi bagi banyak orang. Apalagi tinju termasuk olahraga yang menjadi ajang kejuaraan sampai ke dunia internasional. Maka dari itu olahraga ini termasuk olahraga yang populer. Namun untuk bisa ahli dalam olahraga tinju ini tentusaja anda perlu berlatih dengan baik dan memerlukan jangka waktu tertentu.
Walaupun jika dilihat secara kasat mata, tujuan olahraga ini terkesan seperti bentuk perkelahian atau saling memukul, namun dalam olahraga ini memerlukan teknik, atau cara tertentu dalam bertanding. Maka dari itu tidak sebuah orang bisa melakukan tinju dengan mudah apalagi bagi mereka yang tidak pernah mendapatkan pengalaman atau pembelajaran secara langsung mengenai tinju itu sendiri.
Daftar Isi Materi
Tinju
Tujuan Tinju
Manfaat Olahraga Tinju
Sebarkan ini:
Posting terkait:
Tinju
Tinju pada dasarnya memiliki istilah asing yaitu boxing. Sedangkan dalam bahsa Latin tinju dinamakan pugilism. Kata pugilism merupakan segala sesuatu yang berbentuk kotak. Sedangkan dalam catatan sejarah olahraga tinju itu sendiri pertama kali diperkenalkan oleh bangsa Romawi, Mesir, dan Yunani.
Awalnya seseorang yang melakukan tinju atau dinamakan petinju yang mengikuti pertandingan tidak menggunakan sarung tinju, namun mereka memakai sarung besi sehingga banyak petinju yang meninggal di area tinju karena terkena pukulan secara langsung dari sarung tangan besi tersebut.
Tujuan Tinju
Olahraga tinju merupakan salah satu cabang permainan yang mempunyai banyak tujuan. Antara lain;
Latihan untuk perlindungan diri
Olahraga tinju merupakan salah satu jenis olahraga yang membantu seseorang memperoleh ilmu bela diri sekaligus. Karena pada olahraga ini setiap individu akan dijarakn teknik tinju dengan baik mulai dari pukulan, tendangan, mengunci dan lain sebagainya. Maka dari itulah secara tidak langsung olahraga tinju mampu digunakan untuk perlindungan diri.
Meningkatkan kepercayaan diri
Olahraga tinju juga memiliki tujuan untuk meningkatkan kepercayaan diri. Rasa percaya diri ini bisa didapatkan karena setiap petinju di latih untuk berani menunjukkan kemampuannya dihadapan lawan maupun orang – orang sekitar yang melihatnya.
Dengan hal tersebut maka membuat petinju mengharuskan memiliki rasa percaya diri yang tinggi agar pertandingan berlangsung dengan baik dan mampu mendapatkan hasil yang maksimal.
Sebagai informasi bahwa kepercayaan diri ini biasanya akan lebih mudah muncul pada saat daya tahan tubuh memiliki kekuatan, felsibiltas, keseimbangan dan pikiran yang sehat. Maka dari itu olahraga tinju perlu dilatih beberapa kali sebelum pertandingan dimulai.
Cara untuk membentuk tubuh
Gerakan tinju terdiri dari beberapa gerakan. Pastinya hal itu membuat setiap petinju mendapatkan banyak latihan untuk memahami berbagai teknik yang diperlukan dalam tinju itu sendiri. Melalui gerakan tinju itu sendiri maka seseorang akan dilatih secara fisik maupun mental dengan begitu baik.
Sehingga hal itu membuat petinju memperoleh bentuk tubuh yang lebih ideal dan kuat yaitu berupa pembesaran otot-otot.
Melatih otot inti dan stabilitas tubuh
Perlu anda ketahui bahwa tujuan olahraga tinju salah satunya yaitu mampu melatih otot – otot inti dalam tubuh. Gerakan tinju pada dasarnya banyak melibatkan otot inti diantaranya yaitu mulai dari otot panggul, punggung, pinggang, dan perut.
Setiap teknik pukulan yang dilakukan petinju bisa membantu melatih otot menjadi lebih kuat. Pada saat otot sudah semakin kuat, maka hal ini juga berdampak meminimalisir risiko cedera dan nyeri punggung. Bahkan lebih untungnya lagi kekuatan otot inti juga dapat berdampak pada postur tubuh yang semakin baik.
Mengencangkan lengan serta menguatkan otot pundak
Apakah anda tahu bahwa petinju ternyata ada yang berjenis kelamin wanita. Dari hal ini pula ternyata ada kelebihan yang bisa diperoleh wanita yang melakukan latihan tinju. Keuntungan tersebut yaitu mereka bisa mengencangkan lngan serta mampu menguatkan otot pundak dengan lebih baik lagi.
Meningkatkan kecerdasan berfikir
Tinju bukan hanya bertujuan untuk memperbaiki atau menguatkan fisik saja. Akan tetapi tinju juga bisa bertujuan untuk meningkatkan kecerdasan berfikir.
Apakah anda tahu bahwa memukul samsak atau sparing tenyata sangat baik untuk membantu mengendalikan emosi dengan cara yang lebih sehat. Maka dari itu dengan bertinju, para petinju bisa meluapkan emosi atau amarah yang terpendam di dalam hati dan meningkatkan kecerdasan pula.
Meningkatkan kedisiplinan
Olahraga tinju tidak bisa dilakukan dengan baik tanpa latihan secara teratur dan displin. Maka secara tidak langsung dengan melakukan olahraga tinju ini anda bisa meningkatkan tingkat kedisiplinan agar menjadi lebih baik lagi. Melalui kedisiplinan anda juga bisa memperoleh teknik tinju semakin baik, karena latihan bisa terus dilakukan dengan jadwal yang sesuai dan sudah ditentukan.
Manfaat Olahraga Tinju
Berikut dibawah ini yang merupakan manfaat yang didapatkan dari berolahraga tinju. Antara lain;
Baik untuk kesehatan jantung
Perlu anda ketahui bahwa kekuatan jantung bisa dilihat dari seberapa banyak darah yang dapat dipompa. Melalui olahraga tinju anda bisa melakukan berbagai gerakan yang secara tidak langsung memberikan pasokan darah dan oksigen yang lebih cukup.
Maka dari itu dengan inilah denyut jantung istirahat menjadi lebih rendah dan detak jantung pun lebih teratur sehingga kesehatan jantung bisa lebih terjaga.
Melatih otot inti dan stabilitas tubuh
Gerakan pada olahraga tinju pada dasarnya banyak melibatkan otot inti yang meliputi otot punggung, panggul, pinggang, dan perut. Pada saat otot sudah semakin kuat maka risiko teradinya cedera dan nyeri punggung pun dapat diminimalisir. Selain itu kekuatan otot inti juga bisa berpengaruh pada postur tubuh yang lebih baik.
Meningkatkan koordinasi tubuh
Seseorang dalam melakukan gerakan di beberapa bagian tubuh secara bersamaan tentunya memerlukan kemampuan koordinasi yang baik. Arti olahraga tinju ini termasuk menjadi salah satu jenis olahraga yang tepat untuk meningkatan koordinasi tubuh. Gerakan tubuh bisa diatur semakin baik mulai dari tangan, kaki dan lain sebagainya.
Membakar kalori lebih
Tinju adalah olahraga yang memerlukan banyak gerakan dan menguras banyak energi. Bahkan otot di seluruh tubuh pun bisa bekerja lebih keras lagu. Maka dari itu manfaat tinju yang diperoleh ialah mampu membakar lebih banyak kalori dan berdampak pada penurunan berat badan.
Meningkatkan daya tahan tubuh
Olahraga tinju melatih kekuatan otot menjadi semakin baik dan hal ini membuat petinju tidak mudah merasa kelalahan. Artinya petinju memiliki daya tahan tubuh yang kuat pula. Bahkan tinju bisa membuat kerja paru-paru dalam menyerap oksigen dan menyalurkannya menuju aliran darah menjadi lebih efisien dan efektif.
Melatih keseimbangan tubuh
Gerakan tinju yang dilakakukan secara spontan dan cepat ternyata dapat menambah kemampuan tubuh untuk menyeimbangkan diri agar tidak jatuh dengan mudah. Maka dari itu tinju dikatakan memiliki manfaat untuk melatih keseimbangan tubuh.
Meredakan stress
Sebetulnya semua jenis olahraga mampu meredakan stress. Sala satunya yaitu olahraga tinju itu sendiri. Latihan tinju membuat anda harus mempertahankan diri dan menyerang objek dengan tepat. Hal inilah yang membantu seseorang mampu mengurangi stress dan meningkatkan rasa senang, puas dan semangat.
Nah, demikianlah artikel yang bisa kami kemukakan pada segenap pembaca berkenaan dengan tujuan dan manfaat bermain tinju bagi tubuh yang ada di dalam kehidupan sehari-hari. Semoga memberikan edukasi bagi kalian yang membutuhkannya.
Rate this post
Sebarkan ini:
Facebook
Twit
WhatsApp
Posting terkait:
Tujuan Melakukan Lompat Kangkang
Manfaat Lompat Kangkang bagi Kebugaran Jasmani
Contoh Aplikasi Ilmu Biomekanika dalam Olahraga
Posting pada Manfaat, Olahraga, TujuanDitag bermain tinju, manfaat tinju, olahraga tinju, permainan tinju, tinju, tinju adalah, tinju bagi kesehatan, tinju bagi tubuh, tujuan tinju
Navigasi pos
Pos sebelumnya Tujuan dan Manfaat Permainan Bowling
Pos berikutnya Tujuan dan Manfaat Renang
Sarotun Romlah - https://dosenpenjas.com/
Salah seorang yang menyukai olaharaga dan menulis terkait dengan bidang olahraga. Semoga tulisan saya di dosenpenjas.com ini membantu kalian semuanya ya.


content:
Contoh Surat Pengunduran Diri Dalam Organisasi – Bagi kamu yang ingin mengundurkan diri dari sebuah posisi di institusi perusahaan atau lembaga organisasi langkah yang umum dilakukan adalah mengajukan sebuah surat pengunduran diri resign letter. Dan semuanya itu tentu bukanlah hal yang mudah bagi sebagian orang. Contoh surat pengunduran diri dari organisasi keputusan untuk mengundurkan diri dari suatu perkumpulan atau kelompok tentu merupakan keputusan yang besar dan bisa memberikan dampak tertentu terhadap diri anda sendiri. Contoh surat pengunduran diri dari organisasi banyak alasan yang melatar belakangi seseorang untuk keluar dari sebuah organisasi. Contoh surat pengunduran diri dari sekolah. Contoh di atas adalah contoh surat pengunduran diri dari organisasi mahasiswa..
4 Contoh Surat Pengunduran Diri Dari Organisasi Kepala Sekolah Surat Sekolah
Contoh surat pengunduran diri organisasi serikat pekerja.
Contoh surat pengunduran diri dalam organisasi. Format yang digunakan adalah sebagaimana contoh di atas. Contoh surat pengunduran diri dari organisasi bergabung dengan sebuah organisasi maka tentu seseorang harus siap mengorbankan waktu dan tenaga. Berikut akan saya berikan berbagai contoh surat pengunduran diri sesuai dengan jenis organisasinya masing masing.
Adapun untuk organisasi lainnya kamu cukup mengganti dan menyalin data datanya. Contoh surat mengundurkan diri dari organisasi osis bericontoh mei 12 2020 surat tidak ada komentar contoh surat mengundurkan diri dari organisasi ketika anda memasuki sebuah organisasi atau perusahaan tentunya anda menggunakan surat lamaran. Hal ini merupakan etika yang baik sopan dan bertanggung jawab yang harus dilakukan dibandingkan dengan.
Contoh surat pengunduran diri dari organisasi kampus bem surat pengunduran diri saya benny dharmawan selaku anggota badan eksekutif mahasiswa ugm mengajukan pengunduran diri dari organisasi bem kampus. Entah itu alasan pribadi atau karena ada satu dua hal yang membuat orang itu tidak bisa lagi menjadi anggota organisasi dan ikut serta dalam kegiatannya. Softgaleri adalah blog yang berbagi informasi kode administrasi dalam surat menyurat administrasi aplikasi dan administrasi guru yang mana file berikut ini adalah kumpulan dari berbagi sumber tentang contoh surat pengunduran diri organisasi serikat pekerja yang bisa bapak ibu gunakan dan diunduh secara gratis dengan.
Begitulah contoh surat pengunduran diri dari organisasi biasanya lebih panjang dari pada surat resign kerja. Namun terkadang dikarenakan berbagai alasan seseoran harus dan terpaksa untuk mengundurkan diri dari suatu kelompok. Ada banyak macam macam surat pengunduran diri untuk keluar dari sebuah organisasi karena organisasi itu sendiri banyak macamnya seperti osis himpunan jurusan badan eksektif mahasiswa partai politik dll.
Pertama kamu harus mengajukan surat pengunduran diri dari sekolah yang lama. Bagi kamu yang akan pindah sekolah karena orang tua pindah domisili maka tidak serta merta langsung bisa pindah.
Contoh Surat Pengunduran Diri Organisasi Osis Dan Badan Eksekutif Mahasiswa Bem Surat Sekolah Guru
10 Contoh Surat Pengunduran Diri Dari Organisasi Paling Lengkap Organisasi Surat Tulisan
13 Contoh Surat Pengunduran Diri Resign Resmi Alasan Yang Baik Dan Sopan Surat Tanggal The Rules
10 Contoh Surat Pengunduran Diri Dari Organisasi Paling Lengkap Surat Organisasi
10 Contoh Surat Pengunduran Diri Dari Organisasi Paling Lengkap Surat Organisasi Tanggal
10 Contoh Surat Pengunduran Diri Dari Organisasi Paling Lengkap Surat Organisasi
10 Contoh Surat Pengunduran Diri Dari Organisasi Paling Lengkap Surat Organisasi Tanda
Pengunduran Diri Kerja Yang Baik Dan Sopan Surat Tanda Kebidanan
10 Contoh Surat Pengunduran Diri Dari Organisasi Paling Lengkap Surat Organisasi Ipa
Contoh Surat Pengunduran Diri Dalam Organisasi – Bagi kamu yang akan pindah sekolah karena orang tua pindah domisili maka tidak serta merta langsung bisa pindah. Pertama kamu harus mengajukan surat pengunduran diri dari sekolah yang lama. Ada banyak macam macam surat pengunduran diri untuk keluar dari sebuah organisasi karena organisasi itu sendiri banyak macamnya seperti osis himpunan jurusan badan eksektif mahasiswa partai politik dll. Namun terkadang dikarenakan berbagai alasan seseoran harus dan terpaksa untuk mengundurkan diri dari suatu kelompok. Begitulah contoh surat pengunduran diri dari organisasi biasanya lebih panjang dari pada surat resign kerja. Softgaleri adalah blog yang berbagi informasi kode administrasi dalam surat menyurat administrasi aplikasi dan administrasi guru yang mana file berikut ini adalah kumpulan dari berbagi sumber tentang contoh surat pengunduran diri organisasi serikat pekerja yang bisa bapak ibu gunakan dan diunduh secara gratis dengan..


content:
Pada grafik Weekly, kondisi bearish masih dominan; ditunjukkan oleh gelombang Downtrend yang membentuk Bottom baru lebih rendah gambar strategi biner opsi lindung nilai strategi dari Bottom sebelumnya. Doa di atas sangat baik untuk dibaca setiap muslim pada pagi dan sore hari. Di cara menang main Binomo sini, Anda akan punya dua candle yakni candle 1 dan candle 2. Untuk pengalaman pengguna terbaik, layanan prima tidak hanya tergantung pada staf broker.
Meski demikian, ada beberapa kondisi yang harus diperhatikan saat ingin trading forex deposit 100rb. Terlebih jika dikaitkan dengan komisi yang ditagihkan broker dan biaya lain yang menyertai. Sekitar tahun 2008, Satoshi Nakamoto menciptakan mata uang kripto yang pertama di dunia, Bitcoin. Suatu makalah yang menjelaskan mekanika dan ideologi yang menjadi latar belakangnya diterbitkan melalui Milis Kriptografi. Anda harus mendaftar di situs HotOption dan menyetorkan jumlah yang mulai dari $ 1. Selanjutnya, anda perlu memilih aset, pilihan jenis dan pilihan waktu berakhirnya dalam platform trading. Potensi laba / rugi ditentukan secara otomatis. Anda dapat memulai trading! Ingin berlatih bebas risiko perdagangan turbo options? Buka Akun Demo!
Jika anda memilih untuk mengabaikan sentimen pasar, itu adalah pilihan anda. Tapi, kami beri tahu anda sekarang, itu adalah kerugian anda! Memenangkan permainan poker adalah produk dari pergerakan dan strategi yang berbeda. Anda cara deposit Olymp Trade lewat bank bri sebagai calon karyawan harus menjelaskan sesuai dengan data diri Anda, karena pertanyaan ini biasanya akan memancing pertanyaan pertanyaan selanjutnya.
Triple top adalah pola pembalikan bearish, itulah sebabnya, mirip dengan pola double top, pola ini muncul di bagian atas tren naik dan memberi sinyal perubahan arah harga. Namun dapat lebih diandalkan daripada double top karena berkembang selama periode yang lebih lama.
Sesuai konsep syariah, kamu bisa membelinya secara tunai atau mengambil KPR berbasis syariah. Metode KPR ini memakai sistem margin, bukan bunga kredit. Artinya pada saat pengajuan KPR, pihak bank akan menetapkan margin yang harus dibayarkan dan sifatnya tetap sampai cicilan terakhir. Prestasi dan daya tangkap anak pada suatu mata pelajaran memang berbeda-beda. Hal inilah yang harus diperhatikan oleh para orang gambar strategi biner opsi lindung nilai strategi tua. Orang tua harus mengarahkan anaknya jika si anak tersebut mendapati kesulitan terhadap suatu mata pelajaran. Salah satunya adalah dengan mengikuti bimbingan belajar baik itu di sekolah maupun di luar sekolah. Siswa yang dipilih dalam materi petunjuk penggunaan alat adalah siswa kelas IV. Hal ini karena masih banyak siswa yang belum memahami tentang materi tersebut. Selama pembelajaran sebelumnya siswa kurang bersemangat, membosankan, dan pemebelajaran terpaku pada buku teks saja.
Amati lebih detail hingga pada rentang waktu harian dan tarik garis Fibonacci Retracement dari titik tertinggi ke titik terendah saat itu.
Apa itu adx (average directional movement index)
Cara trading option di broker
Saya juga bingung nih mau menjawabnya, Beta saham pastinya dipengaruhi oleh fundamental perusahaan bukan secara langsung oleh fundamental pasar (kalau menurut CAPM). Fundamental pasar tentunya berhubungan dengan risiko pasar (risiko sistematis). opsi biner trading bahasa Indonesia.
Jika hanya membayangkan saja sandi koordinat akan sulit terbaca. Tips menghafalnya adalah: baca – mempelajari – mengetahui model dan cara mainnya – mempraktikkannya dengan berulang-ulang. "Seseorang adalah sebuah 'kartu kredit' kepada nilai bank digital mereka sendiri," kata perusahaan tersebut.
Gambar strategi biner opsi lindung nilai strategi: Day trade options Indonesia
Apakah ada broker dengan nilai nol untuk sejarah harga? Dengan menggunakan portal situs manajemen akun, seseorang dapat membuat nama pengguna sekunder yang terkait dengan akun yang sama. Dan Anda mendapat konfirmasi dengan fungsi callback sederhana agar pesanan itu terisi atau tidak. Kami mencari komunitas perdagangan algo untuk bekerja sama. Jika berhasil, Anda memiliki perdagangan yatim piatu. Memasang gambar strategi biner opsi lindung nilai strategi dan memulai broker API bisa sangat sederhana. Broker forex dan saham Untuk mendapatkan penawaran harga Anda harus terlebih dahulu berlangganan aset tersebut. API tidak mengizinkan untuk mengambil komisi.
Download Free Binary Options Strategies. Strategie forex mprc Teknik forex indikator terbaik dari opsi biner, forex scalping strategy However.
Komputer ini digunakan oleh Biro Sensus untuk memprediksi hasil pemilihan presiden tahun 1952. Selama dua puluh lima tahun ke depan, Komputer mainframe digunakan di perusahaan besar untuk melakukan perhitungan dan memanipulasi sejumlah besar Informasi yang disimpan dalam database. Teknik obos adalah gambar strategi biner opsi lindung nilai strategi teknik trading yang sangat cocok untuk investor jangka panjang.cukup sekali open posisi dan menunggu beberapa minggu atau beberapa bulan tergantung tempat meletakkan titik take profit. Analisa software forex auto trader erfahrungen pertanyaan opsi biner jasa perdagangan pemula sederhana. Apa itu review pasar saham software manajemen uang biner yang menguntungkan Beli saham blog dengan persentase perdagangan yang efisien.
Beberapa perusahaan memang telah mempunyai reputasi di kalangan kaskuser sebagai broker forex terbaik kaskus. Dengan demikian ada aliran uang masuk dari luar ke dalam negeri sebesar pinjaman otonom ditambah pinjaman akomodasi yaitu.
Semua diawali dari sini, pengetahuan yang terus diupgrade sesuai dengan berkembangnya peradaban. Meski kalian merasa yang terbaik di bidang masing-masing, ketika berhenti untuk investasi di area ini, maka tinggal menunggu saja kehancuran bisnisnya. Awalnya, ide-ide tersebut mungkin brilian. Mereka tidak lagi menggunakan daftar broker biner pilihan AS saat mereka berhenti mengambil pedagang AS pada bulan Januari Studs Hood bermerek stud. Anda mungkin merasa sudah terbiasa dengan menggunakan chart 15 menit atau bahkan 5 menit, sehingga untuk beralih ke Daily diperlukan Balance lebih besar karena harus memasang Stop Loss yang lebih lebar. Ya, benar, dan hal itu bisa diatasi dengan mengatur position size-nya. Dengan position sizing management yang proporsional dengan balance Anda, maka Stop Loss diperbesar sementara position size diperkecil. Dengan demikian, balance tetap sama dan persentase risiko bisa Anda tetapkan sendiri. Yang mesti dihindari adalah keinginan mencetak gambar strategi biner opsi lindung nilai strategi profit dalam waktu singkat seperti saat Anda trading dengan chart 5 atau 15 menit.


content:
2). Tempatkan keset atau tikar matts pada bagian depan pintu atau jeda antar ruang jendela, manfaatnya untuk meminimalisir pasir dan butiran debu.
3). Bersihkan dan di pel seluruh ruangan yang dilantai granit setiap hari dengan kain yang lembut.
4). Material utama yang merusak lantai granit adalah kotoran yang ada disepatu seperti pasir-pasir halus atau batu-batu kecil yang dapat menggoreskan lantai granit.
5). Pilih lah cairan pembersih lantai granik dengan cairan polish khusus granit yang banyak dijual di toko-toko.
6). Hindari pembersihan yang mengandung asam atau cuka, kedua hal tersebut sangat sensitive untuk lantai granit.
7). Setidaknya setiap 1 bulan sekali bersih kan dengan cairan polish yang khusus granit agar lantai granit selalu mengkilap.


content:
Bisnis Online Gratis Terpercaya – Bisnis online adalah salah satu cara untuk mendapatkan kebebasan finansial, saat ini ada banyak sekali orang berusaha menguasai ilmu cara mendapatkan pendapatan di internet, beberapa memang sangat direkomendasikan, namun tidak jarang kita menemukan bisnis internet yang pada ujungnya sebenarnya investasi penipuan yang hanya akan merugikan diri kita. Beberapa mungkin kita pernah mendengar namanya, atau bahkan kita pernah mendengar cerita pahit dari bisnis penipuan yang telah banyak bertebaran di intenet. Sehingga mungkin inilah yang menjadikan Anda menjadi sangat hati-hati untuk memulai bisnis internet, dan ingin mengetahui apa saja bisnis internet yang benar-benar menghasilkan. Berikut kami bahas beberapa model bisnis online gratis terpercaya.
Google Adsense
Google adsense adalah salah satu bisnis online gartis dan terpercaya sejak lama, bisnis ini di kelola oleh google, yaitu dengan menampilkan iklan dari pengiklan di website yang kita buat. Untuk itu kita membutuhkan sebuah blog yang berkualitas, dan mengajukan diri sebagai publisher di Google Adsense, google membutuhkan review manual ke blog Anda sebelum akhirnya Anda akan di terima sebagai publisher, review manual ini untuk melakukan pengecekan terhadap kualitas artikel dan blog Anda. Beberapa kali mungkin Anda akan ditolak namun jangan berhenti dan putus asa, terus perbaiki kualitas website dan kembali mengajukan untuk menjadi publisher di Google Adsense, karena jika Anda telah diterima sebagai publisher Anda memiliki kesempatan besar untuk mendapatkan uang dari google Adsense, hanya dengan menulis artikel bermanfaat di website atau blog Anda. Akan sangat menguntungkan bisa Anda memang memiliki hobi menulis.
Youtube Adsense
Salah satu bisnis online gratis terpercaya adalah dengan menjadi YouTuber, YouTuber adalah sebuah istilah yang dialamatkan kepada orang yang membuat chanel bermanfaat di youtube dan mendapatkan pembayaran dari youtube, yang juga masih milik google sehingga ini akan sangat terpercaya dan juga gratis. Yang perlu Anda lakukan adalah membuat video yang bermanfaat tentang hal-hal unik, bisa dari pengalaman ataupun memang tutorial tertentu. Menjadi YouTuber dibutuhkan kerja keras dan juga kekreatifitas yang tinggi, karena menciptakan video yang berkualitas adalah hal yang tidak mudah, namun ketika video Anda telah memiliki banyak viewers, atau Anda telah mempunyai ratusan ribu subscriber chanel, maka akan sangat mudah Anda untuk mendapatkan uang dari mulai $2 per hari sampai di atas $100 perhari.
Menjual jasa di fiverr
Fiverr adalah sebuah marketplace jasa yang besar di dunia, Anda bisa melihat sangat banyak sekali orang membuka jasa mereka disana. Kebanyakan jasa adalah jasa yang masih berhubungan di internet marketing, seperti jasa pembuatan website, jasa optimasi dan jasa desain grafis. Bagi Anda yang memiliki keahlian khusus akan hal ini, maka Anda memiliki peluang besar untuk memulai bisnis online gratis terpercaya dengan memanfaatka fiverr.com
Mencari pekerjaan di upwork
Upwork berbeda dengan fiverr, jika di fiver kita membuka jasa yang kita spesialisasikan, di upwork kita mencari pekerjaan, atau mencari perusahaan yang membutuhkan keahlian kita. Beberapa orang akan bersedia membayar kita dengan bayaran per jam, sampai di atas $50 per jam bagi Anda yang memang memiliki keahlian yang mumpuni. Misalnya saja Anda menguasai bahasa pemrograman tertentu, Anda akan mendapatkan bayaran yang tidak sedikit ketika mendapatkan pekerjaan di upwork.com
Demikian beberapa cara bisnis online terpercaya yang bisa Anda ikuti, sekali lagi untuk tetap berhati-hati dengan tawaran cepat kaya tanpa kerja sama sekali. Bisnis online sama halnya dengan bisnis offline, membutuhkan komitmen dan usaha yang tinggi.
Categories: Bisnis Online
Tagged: bisnis online gratis, bisnis online terbukti, bisnis online terpercaya
Related Articles
Panduan Lengkap : Memulai Bisnis MLM Online Gratis!
Memulai Bisnis mlm Online – Apakah Anda sedang mencari Bisnis MLM yang bisa dikerjakan secara Online? Maka Anda tepat sekali berkunjung kedalam website ini. Saya akan…
Niko
Menambah Followers Instagram di 2020: Serba Organik ala Vegetarian
Statista di bulan Juli 2020 menyatakan, ada sekitar 73 juta pengguna. Pasar yang menggiurkan, kan? Instagram adalah tempat yang positif untuk mendapat exposure pasar. Exposure,…
Danoe
Dari Brand Hingga Rebranding: Serba-Serbi Dasar yang Sering Dilewatkan
Brand merupakan persepsi orang lain tentang produk/jasa/organisasi yang kamu punya. Dengan kata lain, brand kamu adalah reputasi kamu dalam berbisnis.
Danoe
Cara Jualan di Instagram yang Terbukti Menghasilkan
Inilah cara jualan di Instagram yang Terbukti menghasilkan untuk Anda ikuti.. Tapi terlebih dahulu kita perlu melihat beberapa hal… Sejauh ini, perkembangan teknologi mampu memberikan…
Niko
5 Cara Menghasilkan Uang dari Internet – Terbukti!
5 Cara Menghasilkan Uang dari Internet Cara Menghasilkan Uang dari Internet sebenarnya ada buanyakkk cara… Seperti yang saya juga sudah yakin bahwa Anda sudah pernah banyak…
Niko
Kategori :
Kategori : Select Category Affiliate Marketing Bisnis Bisnis Konvensional Bisnis Online Bisnis Properti Bisnis Rumahan Blog Blogging Cari Uang Dropship Facebook Fashion Google Adsense Hidup Sehat Insight Internet Marketing Lifestyle Marketing Produk Rekomendasi Properti Social Media Tips Travel Tutorial Youtube


content: Tak hanya wanita, pria juga bisa gugup dan khawatir dengan perselingkuhan di ranjang. Meski pria sepertinya [...]


content: Tips Merawat Komputer Agar Awet – Untuk saat ini komputer sudah menjadi barang kebutuhan sehari-hari dan merupakan barang yang sangat familiar […]