C++ ภาษานี้ก็ยัง Powerful อยู่เช่นเดิม

c_0

ถ้ามีคนมาถามผมว่าอยากเริ่มเขียนโปรแกรมจะเริ่มจากอะไร ผมก็จะตอบว่า ลองเขียน Java, C# ดูซึ่งเป็น OOP เต็มรูปแบบ มีเครื่องมือครบ และมี Syntax ที่ดีมาก หรือว่าพวกภาษา Script เช่น JavaScript, Python ก็ได้ เพราะจะได้เป็นการหัดคิดแบบเป็น Logic และฝึกแก้ปัญหา

แต่ถ้า ถามว่าอยากเขียนโปรแกรมให้เก่งแบบมองภาพรวมของ Software Architecture ออกจะต้องยังไง
ผมก็จะตอบว่าเขียน C++ ดู

ถึงแม้ว่าภาษา C จะเกิดมาตั้งแต่ปี ค.ศ. 1972 และ C++ มาตอน 1983 แต่ภาษานี้ก็ยังคงความนิยมและคุ้มค่าต่อการศึกษาครับ

เพราะ…C++

  1. เป็นภาษาที่อยู่ระดับเกือบระดับต่ำสุดเป็นรองแค่ Machine Code กับ Assembly ทำให้เราต้องรู้ว่า CPU มันทำงานยังไง
  2. เป็นภาษาที่ใกล้ชิดกับ OS ทำให้เราต้องรู้ว่า OS แต่ละแบบทำงานยังไงมีส่วนประกอบอะไรบ้างสำหรับโปรแกรมหรือ App ของเรา เช่นการจัดการ Process, Thread, File System, Memory, การทำงานระหว่าง Process (IPC)
  3. ไม่ค่อยมี Tool หรือ Function สำเร็จรูปมาให้แบบ Built-In ทำให้การที่เราจะเขียนอะไรง่ายๆ เช่นจะเขียนแปลง String ก็ต้องเขียนเองเยอะ ซึ่งข้อดีคือทำให้เข้าใน Logic/Algorithm ได้ดีขึ้น และมีนิสัยไม่ขี้เกียจที่จะลงแรงเองถึงแม้งานที่ดูเหมือนง่ายอาจจะต้องเขียนกัน 20-30 บรรทัด
  4. ไม่มี Memory Management ที่ฉลาดๆ เราที่จะเขียนก็ต้องฉลาดที่จะใช้เอง ต้องรู้ว่า Memory เก็บยังไงหลังจากที่ทำการ Allocate แล้ว และต้องรู้ว่าจะคืน Memory ให้ระบบตอนไหน
  5. เป็นภาษาที่ถูกต่อยอดไปเป็นภาษาสมัยใหม่หลายๆภาษา เช่น Java, C#, Objective-C, Swift, PHP, Python, Perl, Ruby, JavaScript และอื่นๆอีกมาก ทำให้เราสามารถไปศึกษาภาษาพวกนี้ได้เร็วขึ้น(จริงๆนะ)
    เปรียบเทียบกับทำให้เหมือนเรารู้ภาษาละตินซึ่งเป็นรากฐานของภาษาในยุโรปเกือบทั้งหมด!
  6. ทำให้รู้กระบวนการของการ Compile โปรแกรมตั้งแต่ เขียน Code ไปจนได้ไฟล์ Executable ออกมา
  7. เข้าใจการทำงานของ Framework หลายๆอย่างในปัจจุบัน เช่น OS, Web Browser, .NET Framework หรือ JVM รวมทั้ง Game Engine ต่างๆ และยังใช้เขียนต่อกับ Hardware ด้วย
  8. ส่วนมากจะเป็นสะพานเชื่อมการทำงานระหว่าง Technology เช่นเขียน .NET app ให้คุยกับ Web
  9. Performance ถึงแม้ว่าทุกวันนี้ CPU เราจะแรง แต่ถ้าต้องการรีด CPU ทุก clock cycle การใช้ C++ ก็ช่วยได้นะครับ
  10. Debug ได้ถึง Memory รวมทั้งสามารถ Deassembly Code มาดูเพื่อทำ Reverse Engineer ได้ ถ้าเราเก่งพอ :p
  11. เขียนได้หลาย Paradiam เช่น Imperative, Object-Oriented, Generic Programming (และทำให้ Code มั่วดีด้วยครับถ้าเขียนบนกันทุก Paradiam 555)
  12. ที่สำคัญ ภาษา C++ นั้นยังมีการพัฒนาอยู่เสมอซึ่ง version หลังๆก็คือ C++11/C++14 และที่กำลังจะมาคือ C++17 (เลขข้างหลังคือเลขปี ค.ศ.ที่จะออก) ซึ่งสิ่งที่เพิ่มเข้ามาทำให้เขียน Code ได้ง่ายขึ้น เช่นเดียวกับภาษายุคใหม่แหละครับ

 

C++ is still ROCK (as always)!

ปล.

  • บทความนี้ความเห็นส่วนตัวนะครับ 🙂
  • C++ เป็นภาษาแรกที่ผมอยากเขียนหลังจากที่ผมรู้จักคอมพิวเตอร์ ตอน ม.ปลาย (เพราะอยากเขียนเกม) แต่ไม่สำเร็จเพราะเข้าไม่ถึงผมเลยหนีไปเขียนเวป PHP, C#, Java ตอนเรียนมหาวิทยาลัย
  • C++ เป็นภาษาที่ใช้ในโปรเจคแรกของชีวิตการทำงาน Developer ของผม

Node.js ด้วยขุมพลัง Chakra ของ Microsoft

ตามคาดครับเจ้าใหญ่อย่าง Microsoft ก็เข้ามามีบทบาทในโลก Node.js หลังจากประกาศเป็นมิตรกับ Open Source วันนี้เรามาลองเล่น Node.js โดยที่รันด้วย ChakraCore ซึ่งเป็น Engine ที่รัน JavaScript ที่อยู่เบื้องหลัง Microsoft Edge (ผมชอบนะเปิด app เร็วดี :p ) แทนที่จะเป็น V8 ตาม version ปกติ

เริ่มจากไปดูใน node-chakracore เราก็พอจะได้ความว่า โปรเจคนี้เปิดตัวมา 6 เดือนแล้ว และมาถึงวันนี้ก็ยังอยู่ใน version ทดสอบอยู่นะครับ ซึ่ง Features หลักๆก็น่าจะพร้อมใช้งานระดับหนึ่ง

เนื่องจากผมขี้เกียจจะมา Build เองก็ไปโหลดตัว Prebuilt มาได้เลยจาก node-chakracore/releases เท่าๆที่ดูก็สามารถใช้งานได้บน Windows, ARM และ Linux (Mac หายไปไหน???)

ผมขอลอง Windows x64 ละกันครับ

หลังจาก Install แล้วตัว Node.js ก็น่าอยู่ที่ “C:\Program Files\nodejs (chakracore)” ซึ่งเป็น Path ปกติก็จะเห็นว่ามีไฟล์ ‘chakracore.dll’ เพิ่มเข้ามา

node_e_files.png
nodejs (chakracore) folder

ซึ่งถ้าเทียบกับ Node.js ปกติ จะเห็นว่า node.exe นั้นไฟล์ขนาด 16MB เพราะรวม V8 engine ไปด้วยในไฟล์เดียวกัน

node_v8_files.png
nodejs ปกติ

ลองเทส http server ง่ายๆก่อน

Code ข้างล่างเป็นการสร้าง Web Sever แบบพื้นฐานที่สามารถส่ง Hello.. กลับไปหน้าเวปได้

// app.js
let http = require(‘http’);

let server = http.createServer( (request, response)=> {
response.write(‘Hello…!’);
response.end();
});

server.listen(80);
console.log(“Server is listening”);

ก็รันได้ดีปกติครับ

node_e_run

 

Performance

ไหนๆก็ไหนๆมาลองดู Performance ดีกว่า เรามาวนลูปเล่นๆกัน “ล้าน” รอบ

console.time(‘test:’);
for(let i = 0; i < 1000000 ; ++i){
let x = Math.random();
}
console.timeEnd(‘test:’);

ลองรันไป 3 รอบ ก็ได้ค่าเฉลี่ยประมาณ 5ms!!

node_e_loop.pngลองรันกับ Node.js (V8) ปกติก็พบว่า…. 15ms ช้ากว่า Chakra เกือบ 3 เท่า…

node_v8_loop.png

ที่นี้เราลองเรียก fucntion หลายๆชั้นดีกว่า เพื่อดูว่าถ้ามี Function ใน Call Stack สัก 3 ชั้นผลจะเป็นยังไง

console.time(‘test:’);
for(let i = 0; i < 1000000 ; ++i){
let x = Math.random();
do1();
}
console.timeEnd(‘test:’);

function do1(){
do2();
}

function do2(){
do3();
}

function do3(){

}

Chakra จัดไป ~9.5ms

node_e_fn_loop.png

ส่วน V8 ก็ยังแถวๆ ~15.7ms

node_v8_fn.png

สรุปสำหรับ Performance ส่วนของ Chakra ก็ยังทำได้ดีกว่าระดับหนึ่ง ซึ่งก็สอดคล้องกับ Official Blog ใน https://blogs.windows.com/msedgedev/2016/06/22/javascript-performance-updates-anniversary-update/

 

HTTP แบบพื้นฐานสุดๆ

http_basic

เป็นเรื่องที่หลีกเลี่ยงไม่ได้สำหรับ  Developer ที่จะเจอคำว่า HTTP เพราะมันเป็นส่วนหนึ่งของชีวิตประจำวันไปแล้วเพราะแทบทุกอย่างในโทรศัพท์มือถือ รวมถึง Web และเกมออนไลน์ นั้นเชื่อมต่อกันด้วย HTTP ทั้งสิ้น

HTTP คืออะไรล่ะถ้าอยากรู้รายละเอียดก็จริงจังก็ไปอ่านใน Wiki ได้เลย

สิ่งที่ผมอยากจะพูดถึงขอเป็นในมุมของ Developer แบบสั้นๆละกัน

HTTP นั้นเป็น Protocol(ข้อตกลง) ที่ใช้ในการติดต่อกันระหว่างอุปกรณ์ที่รองรับการเชื่อมต่อไม่ว่าจะแบบต่อสายหรือ wireless ซึ่งจะมีส่วนประกอบหลักๆคือ Client(เครื่องต้นทาง) กับ Server(เครื่องปลายทาง) และทำการสื่อสารโดยสิ่งที่เรียกว่า HTTP Request/Response

HTTP Request

คือการส่งคำสั่งเพื่อขอข้อมูลโดย Client ไปยัง Server เพื่อให้ส่งข้อมูลตอบกลับมา

Client === ร้องขอ ==> Server

ส่วนประกอบสำคัญของ HTTP Request

  1. URL ซึ่งเป็นเหมือนที่อยู่ของ Server ที่จะไปขอข้อมูล
    โดยที่ URL นั้นก็มีส่วนประกอบหลักๆประมาณนี้ครับ
    Scheme เป็นตัวที่ระบุ Protocol ซึ่งโดยปกติจะเป็น http หรือ https (มี s คือ secure หรือมีระบบความปลอดภัยกว่า)
    Host Name เป็นชื่อของ Server ที่ทำการลงทะเบียนไว้
    Port เป็นหมายเลขสำหรับระบุช่องการติดต่อ (เหมือนกับเราไปธนาคารแล้วมีหลายช่องที่เคาเตอร์ให้บริการ แต่ละช่องก็ให้บริการแตกต่างกันในกรณีปกติ) ซึ่งปกติไม่ต้องระบุก็ได้เพราะมี Default คือ 80 สำหรับ http และ 443 สำหรับ https
    Path เช่นที่อยู่ของข้อมูล ไฟล์ รูป
    Query String เป็นข้อมูลเพิ่มเติมที่ใช้ระบุว่า Client ต้องการข้อมูลมีรายละเอียดปลีกย่อยยังไง

    ตัวอย่างเช่น
    https://www.youtube.com/watch?v=ZV-6SJmSw7
    Scheme คือ https
    Host Name คือ www. youtube.com
    Port ไม่ได้ระบุ ซึ่งค่าปกติเป็น 443 เพราะเป็น https
    Path ก็คือ watch
    Query String คือ v=ZV-6SJmSw7

  2. HTTP Headers ซึ่งเป็นเหมือนกับข้อมูลเพิ่มเติมที่แนบไปให้ Server รับรู้ว่า เช่น มาจากอุปกรณ์แบบไหน Version อะไร ต้องการข้อมูลแบบไหน
  3. Cookies เป็นข้อมูลไม่ใหญ่มากที่ทาง Server สามารถฝากไว้ที่ Client ได้
  4. Method หรือ Verb เป็นข้อมูลที่บอกว่า Client ต้องการทำอะไรกับข้อมูล เพื่อที่ Server จะได้ทำงานได้ตรงตามที่ต้องการ ปกติที่จะเจอกันก็ GET, POST, PUT ตามแต่ประเภทของการขอข้อมูลครับ ซึ่งตอนออกแบบ Server ต้องออกแบบว่าการเข้าถึงข้อมูลแต่ละแบบจะให้ใช้ Method แบบไหน
  5. Request Body หรือ Payload เป็นข้อมูลที่เอาไว้ระบุว่าคำสั่งขอข้อมูลนั้นๆมีรายละเอียดอะไรบ้าง อ่านดูแล้วเหมือน Query String ซึ่งปกติจะใช้กับแบบ GET
    ดังนั้นตัว Request Body เนี่ยจะได้ใช้ในการ Request แบบ POST/PUT

ตัวอย่าง…HTTP Request แบบดิบๆ

POST h ttps://play.google.com/log?format=json HTTP/1.1
Host: play.google.com
Connection: keep-alive
Content-Length: 417
accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
content-type: application/x-www-form-urlencoded;charset=UTF-8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: HSID=AiNeRb8SXTipvwqNT; SSID=AUnId0mBjkh8FuXrP;

[[1,null,null,null,null,null,null,null,[“en-US”,”chrome”,”51.0.2704.103″,”22.0.0″],null,[null,”10.0″,3,null,”en-TH”,2]],78,[[“1469717946642″,null,[],null,null,null,null,”[null,null,null,null,null,null,null,null,null,null,null,[[null,1,null,null,null,null,243,2051499711]],null,null,[1600,900],null,null,null,null,null,null,null,null,[]]”,null,null,null,null,null,null,null,null,null,null,null,[]]],”1469717946643″,[]]

สีแดง คือ Method/Verb
สีส้ม คือ URL
สีเขียว คือ Version ของ HTTP ที่ใช้ในการ request
สีม่วง คือ Headers
สีน้ำเงิน คือ Cookie
สีชมพู คือ Request Body

HTTP Response

คือการส่งข้อมูลที่ทาง Server นั้นตอบรับกลับไปยัง Client ตามที่ได้ขอมา

Client <== ตอบรับ === Server

ส่วนประกอบสำคัญของ HTTP Response

  1. HTTP Status Code ซึ่งเป็นรหัสบอกสถานะว่า การ Request ครั้งนั้นได้รับการตอบรับเป็นอย่างไร
  2. HTTP Response Headers เป็นข้อมูลเพิ่มเติมที่แนบมาโดย Server เช่น ข้อมูลมีขนาดเท่าไหร่ เป็นข้อมูลประเภทไหน
  3. Response Body เป็นตัวเนื้อความของข้อมูลจริงๆที่ Server นั้นตอบกลับมาที่ Client

ตัวอย่าง… HTTP Response แบบดิบๆ

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.google.co.th
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Playlog-Web
Content-Type: text/plain; charset=UTF-8
Date: Thu, 28 Jul 2016 14:59:04 GMT
Server: Playlog
Cache-Control: private
Expires: Thu, 28 Jul 2016 14:59:04 GMT
Content-Length: 47

[“900000″,null,[null,”2570847921467975139”],[]]

สีเขียว คือ Version ของ HTTP ที่ใช้ในการ request
สีส้ม คือ Status Code ซึ่ง 200 คือสำเร็จ (OK)

สีม่วง คือ Response Headers
สีชมพู คือ Response Body

มาถึงตรงนี้แล้วทุกคนก็คงเข้าใจพื้นฐานหลักๆของ HTTP แล้วนะครับ (y)
แล้วพอทราบมั้ยครับว่าการกด Link บนเวปหรือการพิมพ์ URL เป็นการ Request แบบไหน 🙂

 

Debug – รู้ว่า code เรามาถึงจุดนี้ได้ยังไงกับ Call Stack

สำหรับ Computer Science แล้วคำว่า Stack นั้นหมายถึงโครงสร้างของข้อมูลชนิดหนึ่งที่มีลักษณะคือ

  • เก็บข้อมูลได้เป็นชั้นๆ (เหมือนกับการวางมันฝรั่งแผ่นซ้อนๆกันไปเรื่อยๆ)
  • การที่ข้อมูลเข้า Stack เรียกว่า Push และการเอาข้อมูลออกเรีนกว่า Pop
  • ข้อมูลที่เก็บไว้นั้นเป็นแบบที่หลังได้ออกก่อน (เช่น เวลาเราจะต่อชั้นของมันฝรั่งเราจะทับแผ่นบนสุดของก่อนหน้านั้น จากนั้นมันฝรั่งแผ่นบนสุดจะถูกเอาไปกินก่อนเสมอ)

ส่วน Call Stack นั้นคือ ลำดับการเรียกของ Function/Method ของ Code โดยที่เก็บข้อมูลในแบบ Stack

Call Stack นี้สำคัญมากในการวิเคราะห์หรือการไล่ workflow เพื่อทางการแก้ไขข้อผิดพลาดของโปรแกรม เพราะจะช่วยให้เราเห็นว่า Function หรือว่า Code จุดที่เราสนใจนั้นมีลำดับการเรียกมาได้ยังไงกัน

มาดูกันเลยดีกว่า

ผมมี Code ตัวอย่างหน้าตาแบบนี้ครับ

debug_callstack1.png

Code นี้ไม่มีอะไรมาก คือมี Class Logger เพื่อทำหน้าที่เขียนข้อความลงบน Console

คำถามคือเวลาโปรแกรมนี้ทำงานมีนั้น มันมีลำดับการทำงานยังไงบ้างจนกระทั่งมาถึงการเขียนหน้าจอลง Console ในบรรทัดที่ 24

ซึ่งนี่แหละครับ Call Stack จะช่วยเราได้
1. ผมทำการตั้ง Break Point ไว้หลังจากที่มันเขียนข้อความเสร็จนะครับ
2. ลอง Debug กันเลยครับ F5 จัดไป

จะทำให้ Code เราหยุดที่บรรทัดที่ 24 ตามที่คิดไว้ แต่ตอนนี้เราจะไม่รู้เลยว่า Code มาถึงจุดนี้ได้ยังไง

debug_callstack2.png

ไปที่ Debug เมนูข้างบน Windows > Call Stack

debug_callstack3.png

เราก็จะเป็นหน้าต่าง Call Stack พร้อมกับลำดับชื่อ Functions ที่มีการเรียกจากล่างขึ้นบน

debug_callstack4.png

จากตัวอย่างนี้ตำแหน่งปัจจุบันคือสีเหลืองซึ่งก็คือ Logger.doLog()
และเราจะรู้ลำดับการเรียกของ Code จาก Call Stack (ดูจากล่างขึ้นบน) คือ Program.Main() ซึ่งเป็น Entry Point หลัก -> Logger.StartLog() -> Logger.doLog()

นี่แหละครับขุมพลังของ Call Stack

แต่ช้าก่อนเรายังสามารถเลือกดู Code ใน function ต่างๆใน Stack ได้จากการ Double Click นะครับ
ซึ่งจะทำให้มีลูกศรเขียวๆขึ้นมา

debug_callstack5

และทำให้เราเห็น Code ของ จุดที่เรียก Function นั้นๆ ด้วยครับ

debug_callstack6

สุดท้ายเราก็รู้ว่า Code เรามาถึงจุด Break Point นี้ได้ยังไง กันแล้วนะครับ 🙂

Debugging Series:

Debug – สกัดจุดหยุด Code ด้วย Break Point

ถ้าถามว่าจะเริ่ม Debug โปรแกรมต้องทำอะไรบ้าง ทุกๆคนจะตอบเป็นเสียงเดียวกันว่าไปใส่ Break Point ไว้ใน Code ตรงบรรทัดที่เราต้องการให้ Code หยุดการทำงาน

การใส่ Break Point ก็ทำได้ตามนี้ครับ คือ

  1. คลิ๊กที่พื้นที่หน้า Code บริเวณที่ล้อมกรอบสีแดง ถ้าสำเร็จแล้วจะมี จุดสีแดงขึ้น (คลิ๊กอีกทีเพื่อเอา Break Point ออก)

breakpoint1.png

2. หรือจะใช้ Hot Key ก็ได้ (ปกติของ Visual Studio คือ F9)

breakpoint2.png

เริ่มได้
จากนั้นลอง Run โปรแกรมแบบ Debug เช่นกด F5 ครับ เราจะเห็นว่าเมื่อ Code ทำงานมาถึงบรรดัดที่เราตั้ง Break Point ไว้มันก็จะหยุดเป็นลูกศรสีเหลืองๆ ซึ่งหมายถึงตอนนี้ Code กำลังทำงานอยู่ที่บรรทัดที่ 9

breakpoint3

ถ้าเรามีหลาย Break Point ทำการกด F5 นั้นจะเป็นการสั่งให้ Code ทำงานต่อจนไปถึง Break Point จุดถัดไปนะครับ

แล้วจะ Break ไปทำไมกัน มันมีประโยชน์แน่นอนครับ ถ้า Code ของเรามีตัวแปรเราสามารถเอา Mouse ไปจิ้มดูได้ครับแล้ว Debugger ก็จะโชว์ค่าของตัวแปร

ตัวอย่างเช่น

breakpoint4

Console.ReadLine() ทำการรับข้อมูลจาก User ซึ่งผมพิมพ์ “hey anurocha” ไป แล้วเก็บค่าใส่ตัวแปรชื่อ input ผมสามารถเอา Mouse ไปจิ้มตรง input แล้วจะเห็นว่าตัวแปรนี้เป็นค่า “hey anurocha” อยู่

ที่นี้ถ้าโปรเจคเราใหญ่มากแล้วเราทำการตั้ง Break Point ไว้หลายที่ หลายไฟล์เราจะจำได้มั้ย ซึ่งก็จะมี Break Point Window อยู่ครับ

breakpoint5.png

ซึ่งจะเห็นหน้าต่างสำหรับจัดการ Break Point ทั้งหมดของโปรเจคนี้ครับ เช่น
– เปิด/ปิด
– เซฟ หรือ Export/Import

breakpoint6.png

ซึ่งเราสามารถที่จะปิด Break Point ได้โดยที่เรายัง Mark ตำแหน่งไว้จาก Check Box ทำให้เวลา Code ที่ทำงานจะไม่หยุดตรงจุดนั้นๆ

breakpoint7.png

จบ…(เรื่องพื้นฐาน)

มาต่อกันที่ระดับ Advanced ขึ้นนิดนึงครับ 
ปกติแล้ว Break Point ที่เราตั้งเนี่ยจะทำให้ Code หยุดทุกครั้งที่บรรทัดนั้นเรียก แล้วถ้าเราอยากให้มันหยุดเฉพาะบางกรณีล่ะ

ทำได้ครับ มีทางเลือกง่ายๆ คือทำการ Right Click ที่ Break Point นั้นๆ จะมี Conditions..เมนูให้เลือก

breakpoint8.png

ปกติผมใช้ Condition Expression กับ Hit Count ครับ

breakpoint9.png

  1. Condition Expression – เราสามารถกำหนดได้ว่าจะให้ Code มันหยุดตอนไหนบ้างโดนใส่ expression เหมือนใน if() เช่น ถ้าเรามี loop ที่ทำงาน 100 รอบ แล้วเราต้องการให้หยุดตอน i==10 ก็ใส่ไปแบบนี้
    breakpoint10.png
  2. Hit Count – กรณีเช่นเรามีปัญหาว่า Code จุดนี้รัน 30 ครั้งแล้วมันถึงมีปัญหา ถ้าเรา Break แบบปกติมันจะหยุดทุกครั้งซึ่งจะทำให้เราทำงานช้า เราก็สามารถกำหนดไปเลยว่า ขอหยุดเมื่อมันมารันครั้งที่ 30breakpoint11.png

เมื่อ Break Point มีการตั้งเงื่อนไขขึ้นสัญลักษณ์ก็จะเปลี่ยนไปเป็น

breakpoint12.png

ใช้กับ Google Chrome ก็ได้นะ

breakpointchrome.png

แล้ว Break Point เก็บไว้ที่ไหน????
หลายๆท่านอาจจะงงว่า เราตั้ง Break Point ไว้แล้วปิด Visual Studio ไปแล้วพอเปิดใหม่ Break Point ที่เคยตั้งไว้ก็กลับมาด้วย แต่พอไปเปิดเครื่องอื่นกลับไม่มา

สำหรับ Visual Studio นั้น โดยทั่วไป Break Point นั้นไม่ได้เป็นส่วนหนึ่งของไฟล์ในโปรเจค ทำให้เวลาที่เราแก้ไขมันแล้วเราเอาไฟล์ขึ้น Repository ต่างๆเช่น Git/SVN) คนอื่นจะไม่เห็น

ซึ่งไฟล์ของมันเก็บไว้ที่นี่ “.vs”
breakpoint13.png

ลองเข้าไปดู เจอไฟล์ .suo แต่เปิดไม่ได้…

breakpoint14.png

ลองใช้ 7z เปิดดูก็พอเดาได้ว่าข้อมูลการตั้ง Break Point อยู่ในนี้แหละครับ

breakpoint15.png

เป็นอันจบหลักสูตรพื้นฐานวิชาสกัดจุดครับ HAPPY DEBUGGING

Debugging Series:

Debug – การ Run กับ Debug สิ่งนี้คืออะไร

โดยปกติแล้วพวกเราเหล่า Developer ที่ใช้  Visual Studio หลังจากเขียน Code เสร็จแล้วอยากจะดูผลของการทำงาน เราก็จะใช้ปุ่มสุดฮิต นั่นก็คือ กด F5…สิ่งนี้แหละคือการ Debug!..จบ

อ้าวยังครับ! มาดูกันต่อ
ตัวอย่างเช่นการเลือกเมนูข้างล่างหรือ F5 เนี่ยคือการ Start การ Debug แล้วจริงๆ

2016-07-21 00_28_01-ConsoleApplication1 - Microsoft Visual Studio

หรือแม้กระทั่งการปกปุ่มเขียวๆตรงนี้ก็คืการเริ่มต้นการ Debug

2016-07-21 00_28_01-debug-button

อ้าวแล้วการ Run ล่ะคืออะไร
คำตอบง่ายๆก็คือการ double click ไฟล์ Executable (หรือไฟล์ .exe) ตรงๆไงล่ะครับ
หรือถ้าจาก Visual Studio ก็ใช้ เมนู Start Without Debugging ซึ่งก็คือ Ctrl+F5

2016-07-21 00_28_01-debug-run_btn.png

แล้ว 2 อย่างนี้มันต่างกันยังไง????

(Run with) Debug – จะเป็นการ Run โปรแกรมโดยที่ทาง Debugger จะโหลดไฟล์หรือโมดูลเพื่อเตรียมพร้อมให้เราใช้สำหรับการ Debug โปรแกรมของเราได้ ซึ่งบางครั้งอาจจะทำให้รู้สึกว่าโปรแกรมมันทำงานช้าลงไปบ้าง..
แต่สิ่งที่เราจะได้มาคือ
– หยุดการทำงานของโปรแกรมตาม Code ในบรรทัดที่เราต้องการ
– ดูค่าตัวแปรต่างๆเวลาที่โปรแกรมทำงาน
– แก้ไขค่าได้แม้กระทั่งโปรแกรมทำงานอยู่
– และอีกมากมาย

ถ้าเราใช้ Process Explorer ดูจะเห็นว่าโปรแกรมที่เราทำการ Debug อยู่เนี่ยมันเป็น Process ลูกของ devenv.exe(ชื่อ Process ของ Visual Studio) ตรงๆเลยครับ (สำหรับ .NET ตัว Process จะมีเป็นชื่อ .vshost.exe แทน)

2016-07-21 00_28_01-debug-debug_tree

Run – จะเหมือนกับการใช้งานทั่วไปของ Users ซึ่งจะมี Performance ของโปรแกรมเราตามปกติ
ซึ่งจะเห็นได้ว่า deven.exe นั้นจะสร้าง cmd.exe( Commandline Application ) แล้วจึงทำการรัน ConsoleApplication1.exe ซึ่งเป็นโปรแกรมของเราอีกหนึ่งต่อ

2016-07-21 00_28_01-debug-run_tree

และตามปกตินั้นเวลาที่เรา Debug นั้นหน้าตาของ IDE จะเปลี่ยนไป เช่น

2016-07-21 00_28_01-debug-codeview.png
หน้าจอเขียน Code

ไปเป็น

2016-07-21 00_28_01-debug-debugview.png
หน้าจอตอน Run โปรแกรมแบบ Debug

ซึ่งไม่ต้องตกใจนะครับว่าอุตส่าห์จัดหน้าจอสวยๆแล้ว เพราะหน้าจอแบบนี้แหละจะช่วยให้เราทำการ Debug ได้ง่ายขึ้นแล้วมันก็จะเปลี่ยนกลับถ้าออกจากโหมด Debug ไปเป็นโหมด Editor 🙂

จบตรงนี้หวังว่าทุกท่านจะเข้าใจการรันโปรแกรมแบบ Debug ได้ดีขึ้นนะครับ…

Debugging Series:
Debug – Debugger สิ่งนี้คืออะไร

Debug – Debugger สิ่งนี้คืออะไร

จากที่ผมเขียนเกี่ยวกับ IDE (Integrated Development Enviroment) ไปแล้วนั้น ผมได้เน้นว่าอยากให้ศึกษาเรื่อง  Debugger เพิ่มขึ้น มาคราวนี้เลยขอลงรายละเอียดเลยนะครับ

debug.png

เคยมีโค๊ชที่ผมรู้จักท่านนึงกล่าวไว้ว่าการ Debug นั้นคือศาสตร์มืด เพราะมันเป็นการโกงและไม่ทำให้ Code มีการพัฒนาไปในทางที่เหมาะสม เพราะพอโกงชนะก็มักจะขี้เกียจแก้ Code ให้มันเขียน Unit Test ดีๆได้

แต่ผมคิดว่ามันคือเครื่องมือที่ช่วยเรามากกว่าครับ 🙂

การ Debug ก็คือการวิเคราะห์หาข้อผิดพลาดของ Code ของเราที่มันทำงานไม่ถูกต้องอย่างที่เราคิด ยกตัวอย่างเช่น เราคาดหวังว่า Function จะคำนวณผลมาแบบนึง แต่เราได้ค่าที่ไม่ตรง..หรือว่าเรากดปุ่มนึง แต่ข้อมูลดันออกอีกแบบนึง รวมถึงเวลาต้องการทำความเข้าใจ Workflow ของ Code ที่เราไม่คุ้นเคย ซึ่งปัญหาเหล่านี้ถ้ารู้จักวิธีการ Debug ก็จะทำให้ชีวิตเราง่ายขึ้น

แล้ว Debug กันยังไง? วิธีการ Debug นั้นมีหลายวิธีครับ ขอพูดถึงเฉพาะวิธีที่น่าจะใช้กันบ่อยๆกัน

  1. ไล่ Code ดิบๆ – วีธีสุด Classic คือนั่งเปิด Code ดูแล้วก็รีวิวแบบคิดทุกอย่างในหัว ถ้า Code จุดนั้นไม่ซับซ้อนก็ใช้ได้เหมือนกันครับ
  2. Log – อีกหนึ่งวิธีสุด Classic ที่ใช้การเขียนตัวแปรลงไฟล์ หรือ Console ใช้ได้ดีมากครับ โดยเฉพาะถ้าเราต้องทำที่ระบบปิด เช่น เครื่องของ users หรือบน Production
  3. เช็ค Unit Test – วิธีที่ดีที่สุดและท้าทายที่สุด ซึ่งก็คือถ้าเจอ Bug ก็เพิ่ม Test Case ให้สามารถฟ้องว่าเจอ Bug ได้แล้วก็ทำการแก้ Code ให้ Test ผ่าน จากนั้นเราก็จะได้ Test ที่มันครอบคลุมมากขึ้น
  4. ใช้ Debugger – ซึ่งเป็นสิ่งที่จะพูดถึงต่อไปครับ

Debugger คืออะไร? มันก็คือเครื่องมือช่วยเหลือในการแก้ Bug หรือไล่ Workflow ต่างๆ ซึ่งโดยปกติแล้ว IDE นั้นจะมี Debugger ติดมาให้ด้วยอยู่แล้วสังเกตดูจากเมนูของ IDE ต่างๆครับ จะมีเมนูชื่อ Debug อยู่

เช่น…

Screen Shot 2559-07-19 at 11.58.29 AM.png
Debug ใน XCode
vsdebug
Debug ใน Visual Studio
chromedebug.png
Debug ใน Google Chrome (Developer Tools)

แต่สำหรับ Windows ถ้าไม่อยากลงโปรแกรมแบบหนักๆแบบ Visual Studio เช่นต้องไป Debug  ที่เครื่องของ User ก็มี WinDbg ที่เป็น Debugger แบบ Stand Alone แต่มันค่อนข้าง Advanced มากและเป็น Command Line ผมขอยังไม่พูดถึงนะครับ

ขอทิ้งท้ายไว้กับสิ่งที่ต้องรู้สำหรับการเป็นนัก Debug ละกัน ใครยังไม่รู้จักตัวไหนเจอกันครั้งหน้าครับ

  1. Debug กับ Run
  2. Break Point สกัดจุดหยุดทุกสิ่ง
  3. Call Stack
  4. 3 Steps – Step Over, Step Into, Step Out
  5. หน้าต่าง Watch, Autos, Locals

“If debugging is the process of removing bugs, then programming must be the process of putting them in.” – Edsger W. Dijkstra

ถ้าการ Debug เป็นการจัดการ Bug ให้หมดไป ถ้างั้นการเขียนโปรแกรมก็เป็นการเพิ่ม Bug เข้าไป!

สร้าง Node.js module แบบ Native ด้วย C++

node_cpp

เป็นที่รู้กันว่าสำหรับทุกคนว่า Node.js นั้น Powerful ก็เพราะว่ามี Modules ให้เราใช้ไปแทบทุกอย่าง รวมถึงหลายๆคนอาจจะเคยเขียน Module ด้วย JavaScript ทั้งใช้เองและให้คนอื่นใช้

แต่วันนี้ผมจะมาแนะนำวิธีการเขียน Node.js module ด้วย C++ กัน

ก่อนอื่นในเมื่อเราเขียน Module ด้วย JavaScript ได้ทำไมต้องใช้ C++ มาดูข้อดีกันก่อนเลย

  1. System Access – ด้วย Native enviroment ทำให้ Module ที่เขียนด้วย C++ สามารถเข้าถึง API ของ System/OS ได้
  2. Performance – JavaScript นั้นทำงานด้วย Single Thread แต่ว่า Native นั้นสามารทำงานแบบ Multi Thread ได้
  3. Compiled Binary – JavaSciprt ถึงแม้จะมี Minify/Uglify แต่ก็พอจะ reverse engineer ได้แต่สำหรับ Native นั้นถึงแม้จะทำได้เหมือนกันแต่ก็ต้องมานั่ง Deassembly

เริ่มกันเลยครับ จริงๆแล้วผมก็ทำตาม https://nodejs.org/api/addons.html  แต่!…ผมทำตามแล้วมันมีขั้นตอนเยอะและต้องใช้ Python ในการ Build อีก ผมเลยขอสรุปเองจากการลองแงะ Python scipt เพื่อลดความงงลง(หรือว่ายากขึ้น?)

  1. สร้าง Project C++ ใหม่จาก Visual Studio 2015
    newproj
  2. เป็น DLL นะ
    dllproj
  3. ไปโหลด Node.js ไฟล์ headers และ node.lib มาครับที่
    https://nodejs.org/download/release เลือกตาม version ของ Node ที่เราจะใช้ได้เลย เช่น v6.3.0
    download
  4. Extract .gz แล้วก้ copy ไฟล์มาที่ Folder C++ Project ของเรา
    ผมตั้งชื่อ folder เป็น
    – include สำหรับ headers ไฟล์ที่เรา Extracted มา
    – lib สำหรับเก็บ node.lib
    copy_dep
  5. ที่นี้ก็ copy Source code นี้ไปที่ .cpp หลักครับ
    // anurocha_node.cpp : Defines the exported functions for the DLL application.
    //
    
    #include "stdafx.h"
    #include "include/node/node.h"
    
    namespace demo {
    
     using v8::FunctionCallbackInfo;
     using v8::Isolate;
     using v8::Local;
     using v8::Object;
     using v8::String;
     using v8::Value;
    
     void SayHi(const FunctionCallbackInfo<Value>& args) {
     Isolate* isolate = args.GetIsolate();
     args.GetReturnValue().Set(String::NewFromUtf8(isolate, "Hi - How are you doing?"));
     }
    
     void init(Local<Object> exports) {
     NODE_SET_METHOD(exports, "hello", SayHi);
     }
    
     NODE_MODULE(addon, init)
    
    } // namespace demo
  6. ลอง Build Project ดูครับ…เจ๊ง!
    link_err
    อ๊ะ!.. เราลืม Link ครับ
  7. ไปเพิ่ม lib/node.lib ใน Linker ซะ
    linker
  8.  Build อีกรอบ….เจ๊งเหมือนเดิม!!@#ไม่ต้องตกใจครับ….เป็นมุข..เรามี Lib ของ node.dll เป็น x64 ตามที่โหลดมา แต่เรากำลัง Compile แบบ x86 อยู่(ซึ่งเป็น Default Configuration ตอนสร้าง Project) ดังนั้นไปแก้ Project – Linker อีกรอบนึงครับ มั่นใจว่าแก้สำหรับ Platform x64 ด้วยนะครับ
    linker64
  9.  Build อีกทีจริงๆ ด้วย Target x64 นะครับbuildx64
  10. ถ้า Build ผ่านจะได้ไฟล์ .dll มาครับ
    out
    ให้เปลี่ยนชื่อเป็น anurocha.node แทน
  11. สร้างไฟล์ app.js ง่ายๆมา มี Code แค่ 2 บรรทัด ที่ Folder เดียวกับ anurocha.node
    const addon = require('./anurocha');
    console.log(addon.hello());
  12. รัน “node app.js” ดูครับ…..แล้วความตื่นเต้นก็เกิดขึ้น!!!
    node_out

สำเร็จแล้วกับ 12 ขั้นตอนที่ยาวนาน !!!!!

ลองมาดูรายละเอียดกันครับเกี่ยวกับขั้นตอนการทำงานของ JavsScript <–> C++
ซึ่งหัวใจสำคัญที่ทำให้ทั้ง 2 ภาษาคุยกันได้คือ V8 ที่เป็น JavaScript Engine เขียนด้วย C++ จาก Google นั่นเอง

  1. เวลาที่ dll ถูกโหลดด้วย JavaScript จาก require(); ตัว dll จะถูกเรียกครั้งแรกเพื่อทำการ Init ค่าต่างๆ
    ในที่นี้เราทำการ export Fuction ที่ชื่อว่า hello ออกไป ซึ่ง function hello นั้นทำการ Map กับ Method ที่ชื่อว่า SayHi

    void init(Local<Object> exports) {
     NODE_SET_METHOD(exports, "hello", SayHi);
     }
    
     NODE_MODULE(addon, init)
  2. เวลาที่ JavaScript เรียก addon.hello();
    Code ฝั่ง C++ จะถูกเรียก Method ที่ชื่อว่า SayHi(); ทำให้มีการ return String object ที่มีค่า “Hi – How are you doing?” ออกมาให้ฝั่ง JavaScript

    void SayHi(const FunctionCallbackInfo<Value>& args) {
     Isolate* isolate = args.GetIsolate();
     args.GetReturnValue().Set(String::NewFromUtf8(isolate, "Hi - How are you doing?"));
     }

จากตัวอย่างนี้จะเห็นได้ว่าการเขียน Node.js Module ด้วย C++ นั้นอาจจะดูยุ่งยากซักนิดนึง แต่มันทำให้เราเขียน Logic ต่างๆด้วย C++ ได้ นั่นหมายความว่าถ้าเรารัน Node บน Windows เราก็สามารถเรียกใช้งาน Win32 API ต่างๆได้เช่น การเรียก Registry Key, ต่อ Socket, อ่านไฟล์บน HDD รวมถึงการทำงานร่วมกับสารพัด Library ของ C++ อย่างที่ทำได้เหมือนการเขียนโปรแกรมบน OS นั้นๆ….

LONG LIVE C++

ปล. Code ทั้ง Solution ดูได้จาก https://github.com/anurocha/node_cpp_addon ครับ

IDE หนึ่งในสิ่งพื้นฐานควรรู้ของ Developer

Developer คนไหนไม่รู้จัก IDE บ้าง? ถ้าคนๆนั้นเป็นคุณก็…..อ่านต่อเถอะครับ 🙂
ส่วนถ้ารู้แล้วก็ลองอ่านเล่นๆดูได้ครับ

IDE ย่อมากจาก Integrated Development Enviroment ซึ่งก็คือเครื่องมือที่ Developer ใช้ในการพัฒนา Software แบบครบวงจร เช่น Visual Studio, XCode, Netbean, Eclips, Xamarin และอื่นๆ

โดยความสามารถหลักๆ ของ IDE ผมขอแบ่งเป็น 4 อย่างใหญ่ๆละกัน

  1. Editor – เอาไว้เขียน Source Code รวมถึงพวก Syntax Hilight, Auto-Complete
  2. Compiler – เอาไว้ Build โปรแกรมจาก Code ไปเป็น Binary
  3. Debugger – เอาไว้ใช้ในการแก้หาวิธีในการแก้ Bug
  4. Tools – เครื่องมือช่วยต่างๆ เช่น Refactoring, จัดหน้าจอหรือ Visual Design, การทำ UML, ดู Database รวมถึงพวกทำ Static Code Analysis และการสร้าง Document จาก Code

มาถึงตรงนี้แล้วมีใครใช้ IDE ครบ 4 อย่างมั้ยครับ….จากประสบการณ์ของผมแล้วน้องๆ Developer  ส่วนใหญ่จะรู้จักมันในฐานะข้อ 1 และ 2 เท่านั้น

ซึ่งผมอยากแนะนำสำหรับคนที่ยังไม่ได้ลองใช้ความสามารถของ IDE ในการเป็น Debugger ควรจะหาเวลาไปเรียนรู้ไว้ครับ เพราะมันจะช่วยทำให้คุณแก้ Bug รวมถึงพัฒนา Feature ที่ซับซ้อนได้เร็วขึ้นจริงๆ

แต่ช้าก่อน…..ถ้าท่านที่สามารถทำงานกับโปรเจคขนาดใหญ่โดยไม่ต้องใช้ Debugger ได้ผมนับถือมากครับ แสดงว่า  Source Code น่าจะมี Unit Test ครบ 100% ซึ่งทำให้เจอBug ได้จาก Unit Test และไม่ต้องพึ่งการ Debug

นี่คือ Utopia of Software – Software ในอุดมคติเลย!

Canary Testing นกขมิ้นน้อยในเหมืองใหญ่

4_1278772155

เหล่าท่านๆ Engineer ทั้ง Developer และ QA อาจจะรู้ว่าการปล่อย Software ขึ้น Production ให้คุณลูกค้านั้นมีความตื่นเต้นเพียงใด ถึงแม้ว่าเราจะมีการหลายๆ Enviroment ในการพัฒนาระบบเช่น Development, Pre-Production, Production เพื่อลดความเสี่ยงลงแล้ว แต่ถึงอย่างนั้นตอนเอาขึ้น Production ก็ยังต้องลุ้นทุกที

เป็นปกติที่ระบบ Production ของ Software จะมีการ Config ที่แตกต่างกันกว่า Development อยู่เสมอ (แล้วทำไมมันไม่เหมือนกันล่ะ??) แต่ถ้าเราต้องอยู่ด้วยสถานะระบบแบบนี้เรายังมีทางออกนะครับ

สิ่งนี้เรียกว่า Canary Testing ซึ่งมาจาก Canary in Coal Mine มาจาก

การที่นักขุดเหมืองสมัยก่อนนั้นจะใช้นกขมิ้นในการทดสอบว่าเหมืองนั้นปลอดภัยไม่มีก๊าซพิษก่อนที่คนละทำการลงไปขุดในระดับที่ลึกขึ้น

การนำแนวคิดนี้มาใช้กับ Sofware ก็คือ เราจะให้กลุ่ม Users บางกลุ่มนั้นได้ลองใช้ Software Version ใหม่ก่อนคนอื่นๆ เพื่อป้องกันการความเสี่ยงจากการ Release ที่เดียว Impact ทุกคน หรือเรียกว่า BIG BANG Release
จากนั้นก็ค่อยๆรับ Feedback จาก Users กลุ่มๆนี้ ถ้ามี Critical Bug ก็ทำการแก้ไขก่อนที่จะเริ่ม Release ให้กับ Users ในกลุ่มที่ใหญ่ขึ้น และทำแบบนี้ไปเรื่อยๆจน Release ให้กับทุก Users

ถ้าระบบของ Software เราเป็น Web เราอาจจะทำ Canary Tetsing/Release ได้ง่ายขึ้นจากการ

  1. โดยอาจจะเริ่มจาก กลุ่มผู้โชคดี > ประเทศ > ทวีป > ทั้งโลก เป็น 4 ขึ้นตอน
    ซึ่งอาจจะทำได้โดย detect  ว่า Users มาจาก IP ช่วงไหนแล้วก็ Redirect ไปยัง URL ของ Version ใหม่
  2. ถ้ามีระบบ User อาจจะมี Option ว่าเป็น Early Accessได้ แล้วระบบเราเช็ค Flag นี้ในการตัดสินใจ Version
  3. สร้าง URL ใหม่เลยแล้ว Promote ที่ Banner ว่า Try Latest Version!

ซึ่งแน่นอนว่าการที่ระบบจะทำ Canary Testing ได้ก็ต้องลงทุนและต้องมีสถาปัตยกรรมที่รองรับ และยิ่งถ้าระบบใหญ่ๆและการ Release ทีนึงมี Impact กับ Users เยอะๆนี่ ผมว่าคุ้มนะ 🙂