Each program limitation.
MyMusicCloud -> limit playing only 250 songs.
Beat - cloud & music -> no song downloading in advance to play offline later. But you can play from cache.
Cloudaround
- limit only 1 cloud account.
- can't move downloaded songs to SD card (only Android6).
- Onedrive can't be downloaded (mean no offline play).
CloudBeats -> download function need to be upgraded.
CloudPlayer -> only premium account can play cloud music files.
AirBeats -> support only Dropbox.
Angular module include module
module ใน Angular เราสามารถไปเรียก module อื่นๆ ได้
ตัวอย่าง
HomeModule.js
จากนั้นเขียน module ที่ต้องการจะเรียก module
app.js
จากนั้นก็เขียน html ในการเรียก angular ปกติ แต่จะต้องใส่ script ทุกไฟล์ที่ module เรียกไว้ให้ครบด้วยนะค่ะ
02.html
แค่นี้ก็สามารถเรียกใช้เป็น module ได้
จบ.
ตัวอย่าง
HomeModule.js
1 2 3 4 5 | var app = angular.module('HomeModule', []); app.controller('HomeController', function($scope) { $scope.name = 'AngularJS'; }); |
จากนั้นเขียน module ที่ต้องการจะเรียก module
app.js
1 | var app = angular.module('A02', ['HomeModule']); |
จากนั้นก็เขียน html ในการเรียก angular ปกติ แต่จะต้องใส่ script ทุกไฟล์ที่ module เรียกไว้ให้ครบด้วยนะค่ะ
02.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html ng-app="A02"> <head> <title>02</title> <script src="js/angular.min.js" type="text/javascript" charset="utf-8"></script> <script src="app/02/app.js" type="text/javascript" charset="utf-8"></script> <script src="app/02/HomeModule.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div ng-controller="HomeController"> <p>{{ name }}</p> </div> </body> </html> |
แค่นี้ก็สามารถเรียกใช้เป็น module ได้
จบ.
Angular factory
คราวที่แล้วเราสร้าง service ไปแล้ว คราวนี้จะมาดูกันว่านอกจาก service แล้ว เราสามารถเขียนเป็น factory ก็ได้เหมือนกัน
app.js
คราวที่แล้วเราเขียน function เดียวกันแต่ใช้ผ่าน service ซึ่งไม่มีการ return อะไร แต่ว่าผูกค่าหรือ function ไว้กับ this แต่ถ้าเป็น factory จะมีการ return ค่า
file.html
แต่ตอนที่เรียกใช้ ไม่ว่าจะเป็น service หรือ controller จะเรียกไม่ต่างกัน
จบ.
Reference:
AngularJS: Service vs provider vs factory
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var app = angular.module('A05', []); app.factory('CalculatorFactory', function() { var currency = 'US$'; function resultWithCurrency(value) { return currency + ' ' + value; } return { name: 'Calculator Factory', calculate: function(value) { return resultWithCurrency(value * value); } } }); app.controller('FactoryController', function($scope, CalculatorFactory) { $scope.name = CalculatorFactory.name; $scope.calculate = function() { console.log(CalculatorFactory.calculate(10)); } }); |
คราวที่แล้วเราเขียน function เดียวกันแต่ใช้ผ่าน service ซึ่งไม่มีการ return อะไร แต่ว่าผูกค่าหรือ function ไว้กับ this แต่ถ้าเป็น factory จะมีการ return ค่า
file.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!DOCTYPE html> <html ng-app="A05"> <head> <title>05</title> <script src="js/angular.min.js" type="text/javascript" charset="utf-8" ></script> <script src="app/05/app.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div ng-controller="ConstantController"> <p><b>Constant</b>: {{ viewPath }}</p> </div> <hr> <div ng-controller="FactoryController"> <p><b>Factory</b>: {{ name }}</p> <p><button ng-click="calculate()">{{ name }}</button></p> </div> </body> </html> |
แต่ตอนที่เรียกใช้ ไม่ว่าจะเป็น service หรือ controller จะเรียกไม่ต่างกัน
จบ.
Reference:
AngularJS: Service vs provider vs factory
Angular service
คราวที่แล้วเราเริ่มต้นด้วย module กับ controller ไปแล้ว ถ้าเราจะเขียนให้สวยก็เขียนใส่ service หรือ factory สำหรับการเรียกใช้ในหลายๆ controller (คิดว่าน่าจะเหมือนกับ MVC)
ตัวอย่างการเขียน service และการเรียกใช้ผ่าน controller
app.js
ใน service เราผูกค่า หรือ function ที่เราต้องใช้ไปกับตัว service เอง (this) แล้วค่อยให้ controller มาเรียกใช้ service ไปอีกที โดยจะต้องผ่านตัวแปร $scope เพื่อให้หน้า client สามารถเห็นค่าเหล่านี้
file.html
ในหน้าเวป เราก็เรียกใช้ controller เหมือนปกติ
จบ.
ตัวอย่างการเขียน service และการเรียกใช้ผ่าน controller
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var app = angular.module('A05', []); app.service('CalculatorService', function() { var currency = 'US$'; function resultWithCurrency(value) { return currency + ' ' + value; } this.name = 'Calculator Factory'; this.calculate = function(value) { return resultWithCurrency(value * value); }; }); app.controller('ServiceController', function($scope, CalculatorService) { $scope.name = CalculatorService.name; $scope.calculate = function() { console.log(CalculatorService.calculate(10)); } }); |
ใน service เราผูกค่า หรือ function ที่เราต้องใช้ไปกับตัว service เอง (this) แล้วค่อยให้ controller มาเรียกใช้ service ไปอีกที โดยจะต้องผ่านตัวแปร $scope เพื่อให้หน้า client สามารถเห็นค่าเหล่านี้
file.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html ng-app="A05"> <head> <title>05</title> <script src="js/angular.min.js" type="text/javascript" charset="utf-8" ></script> <script src="app/05/app.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div ng-controller="ServiceController"> <p><b>Service</b>: {{ name }}</p> <p><button ng-click="calculate()">{{ name }}</button></p> </div> </body> </html> |
ในหน้าเวป เราก็เรียกใช้ controller เหมือนปกติ
จบ.
Angular module and controller
function หรือ global API คือคำสั่งที่เรียกผ่าน object angular ทั้งหมด ซึ่งมีด้วยกันหลายคำสั่ง ซึ่งตามหลักที่ดี ก็คือเขียนเป็น module และใน module แยกเป็นแต่ละ controller เพื่อใช้เรียก service หรือ factory อีกที (ส่วนตัวเข้าใจว่า service จะเป็นการสร้าง object service ใหม่ แต่ factory เป็นการเรียก service นั้นๆ โดยไม่สร้างใหม่)
ซึ่งเราจะแยกไฟล์ AngularJS แยกไว้ต่างหาก และในไฟล์ HTML ก็จะ include script เข้ามาโดยผ่าน directive ng-app และ ng-controller
ตัวอย่างไฟล์ AngularJS ที่เขียนเป็น module และการเรียนใช้ controller ภายใน module
app.js
02.html
อันนี้ถือเป็นการเริ่มทำความคุ้นเคยกับการเขียน Angular ซึ่งจะเห็นว่า เราก็จะเขียน Angular function ต่างๆ ไว้ในไฟล์แยกเหมือน javascript ตัวหนึ่ง แล้วเรียกใช้ เพียงแต่การเรียกใช้เราจะเรียกผ่าน Angular directive ต่างๆ
จบ.
ซึ่งเราจะแยกไฟล์ AngularJS แยกไว้ต่างหาก และในไฟล์ HTML ก็จะ include script เข้ามาโดยผ่าน directive ng-app และ ng-controller
ตัวอย่างไฟล์ AngularJS ที่เขียนเป็น module และการเรียนใช้ controller ภายใน module
app.js
1 2 3 4 5 6 | // create angular model A02 var app = angular.module('A02', []); app.controller('HomeController', function($scope) { $scope.name = 'AngularJS'; }); |
02.html
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html> <html ng-app="A02"> <head> <title>02</title> <script src="js/angular.min.js" type="text/javascript" charset="utf-8"></script> <script src="app/02/app.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div ng-controller="HomeController"> <p>{{ name }}</p> </div> </body> </html> |
อันนี้ถือเป็นการเริ่มทำความคุ้นเคยกับการเขียน Angular ซึ่งจะเห็นว่า เราก็จะเขียน Angular function ต่างๆ ไว้ในไฟล์แยกเหมือน javascript ตัวหนึ่ง แล้วเรียกใช้ เพียงแต่การเรียกใช้เราจะเรียกผ่าน Angular directive ต่างๆ
จบ.
Basic Angular Directive
นอกจาก Angular Expression แล้ว เรายังสามารถใช้ Angular Directive สำหรับการผูกข้อมูล (binding) โดย directive ที่ใช้ทั่วไป มีดังนี้
ตัวอย่างจะเป็นการกำหนดค่าตัวแปร price กับ qty
ในตัวอย่างเป็นการผูก input text กับตัวแปรชื่อ name ซึ่งในการผูกค่า อาจจะใช้เป็นตัวแปรแบบ primitive หรือว่า object ก็ได้
หรืออีกตัวอย่างหนึ่ง เป็นการผูกค่าตัวแปร like กับ input radio
หรือ ผูกค่ากับ select tag
ตัวอย่างกำหนดการคำนวณให้กับปุ่ม
ตัวอย่างกำหนดให้แสดงหรือไม่แสดงข้อความ (รวมถึงสีพื้น)
นอกจากนี้ยังมี
พื้นฐานของ Angular Directive ก็จะมีประมาณนี้ เอาไว้ค่อยมาต่อกันนะค่ะ
Reference:
ng Directive
ng-init
สำหรับการกำหนดค่าเริ่มต้นให้กับตัวแปร1 2 3 4 5 6 7 | <div ng-init="price=50;qty=25"> <p>Amount: {{ price * qty }}</p> <p>Amount: {{ price * qty | currency }}</p> <p>Amount: {{ price * qty | currency:'THB' }}</p> </div> |
ตัวอย่างจะเป็นการกำหนดค่าตัวแปร price กับ qty
ng-model
เป็นการผูกค่าตัวแปรกับ input tag ใน HTML
1 2 | <input type="text" ng-model="name"> <p>Name: {{ name }}</p> |
ในตัวอย่างเป็นการผูก input text กับตัวแปรชื่อ name ซึ่งในการผูกค่า อาจจะใช้เป็นตัวแปรแบบ primitive หรือว่า object ก็ได้
หรืออีกตัวอย่างหนึ่ง เป็นการผูกค่าตัวแปร like กับ input radio
1 2 3 4 5 | <div ng-init="like='Yes'"> <input type="radio" value="Yes" ng-model="like">I like <input type="radio" value="No" ng-model="like">I don't like <p>Answer: {{ like }}</p> </div> |
หรือ ผูกค่ากับ select tag
1 2 3 4 5 6 7 | <select ng-model="food"> <option value="Rice">Rice</option> <option value="Noodle">Noodle</option> <option value="Soup">Soup</option> </select> Your Order: {{ food }} |
ng-click
เนื่องจากใน javascript ตัวแปรนอกจากจะเก็บค่าต่างๆ หรือว่าใช้เก็บเป็น object ของ property (ซึ่งก็เป็นการเก็บค่าอยู่ดี) ได้แล้ว ยังสามารถกำหนดให้ตัวแปรมีค่าเก็บ function ได้ด้วย เสมือนกับ function เป็นค่าๆ หนึ่ง ดังนั้นเราจึงใช้คุณสมบัตินี้มากำหนดพฤติกรรมของการทำงานในเอกสาร HTML ได้ตัวอย่างกำหนดการคำนวณให้กับปุ่ม
1 2 | <button ng-click="counter=counter+1">Count</button> <p>Counter: {{ counter }}</p> |
ng-if
เป็น directive ที่ใช้กำหนดเงื่อนใขให้กับ HTMLตัวอย่างกำหนดให้แสดงหรือไม่แสดงข้อความ (รวมถึงสีพื้น)
1 2 3 4 5 6 | <div ng-init="show=true"> <p ng-if="show" style="background-color: red;">Red</p> <p ng-if="!show" style="background-color: green;">Green</p> <button ng-click="show=!show">Toggle</button> </div> |
นอกจากนี้ยังมี
- ng-repeat
- ng-app
- ng-controller
พื้นฐานของ Angular Directive ก็จะมีประมาณนี้ เอาไว้ค่อยมาต่อกันนะค่ะ
Reference:
ng Directive
Angular Expression
Angular สามารถเขียน code ลงไปได้ 2 รูปแบบ คือ Angular Expression และ Angular Directive ซึ่งสำหรับ Angular Expression จะมีลักษณะคล้ายๆ การเขียน JavaScript ลงไปยัง {{ script }}
ซึ่งตัวอย่างที่สามารถเขียนลงไปได้ก็อย่างเช่น
ซึ่งตัวอย่างที่สามารถเขียนลงไปได้ก็อย่างเช่น
- {{ 'Hello World' }} - แสดงข้อความ
- {{ 1 + 2 }} - คำนวณค่าคงที่
- {{ a + b }} - คำนวณค่าจากตัวแปร
- {{ user.name }} - แสดงค่า property จาก object
- {{ items[index] }} - แสดงค่าจาก array
แต่จะแตกต่างจาก JavaScript คือ
- JavaScript อ้างอิงจาก ตัวแปร window แต่ Angular จะใช้ $scope object
- ตัวแปรไหนที่ไม่อยู่ใน scope หรือไม่เคยกำหนดค่ามาก่อน Angular จะใส่ให้เป็น null หรือเริ่มต้น เช่น ถ้าเป็นตัวเลขก็จะใส่เป็นค่า 0 เป็นต้น
- ไม่สามารถใส่ Control Flow ได้ เช่น loop, if
- ไม่สามารถสร้าง function ได้
ไว้โอกาสหน้าจะมาต่อกันเรื่อง Directive
Reference:
AngularJS 101
AngularJS เป็น lib ของ javascript ที่จะช่วยให้การเขียนได้ง่ายขึ้น (เข้าใจว่า) ดังนั้นการเขียน Angular JS จึงเหมือน javascript ทั่วๆ ไป แต่อาจจะมีการรูปแบบการเขียน (syntax) ที่แตกต่างออกไป
การจะเริ่มเขียน AngularJS สามารถเขียนได้บนไฟล์ .html ทั่วๆ ไป โดยเพิ่มการอ้างอิง AngularJS lib และใส่ module เข้าไป
ส่วนที่เพิ่มเข้าไปคือ "ng-app" ใน html tag และ script ที่อ้างไปยัง AngularJS lib เพียงเท่านี้ก็เป็นอันเสร็จ คือไฟล์ html นี้สามารถเพิ่ม code ส่วนที่เป็น Angular เข้าไปได้แล้ว ซึ่งในตัวอย่างจะเป็นการแสดงข้อความ 'Hello World' ผ่านทาง AngularJS
เอาหอมปากหอมคอแค่นี้ก่อน ไว้มาดูตอนต่อไป
การจะเริ่มเขียน AngularJS สามารถเขียนได้บนไฟล์ .html ทั่วๆ ไป โดยเพิ่มการอ้างอิง AngularJS lib และใส่ module เข้าไป
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html ng-app> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js" type="text/javascript" charset="utf-8"></script> <title>test</title> </head> <body> {{ 'Hello World '}} </body> </html> |
ส่วนที่เพิ่มเข้าไปคือ "ng-app" ใน html tag และ script ที่อ้างไปยัง AngularJS lib เพียงเท่านี้ก็เป็นอันเสร็จ คือไฟล์ html นี้สามารถเพิ่ม code ส่วนที่เป็น Angular เข้าไปได้แล้ว ซึ่งในตัวอย่างจะเป็นการแสดงข้อความ 'Hello World' ผ่านทาง AngularJS
เอาหอมปากหอมคอแค่นี้ก่อน ไว้มาดูตอนต่อไป
ติดตั้ง Sublime และ Package Control
Sublime เป็น text editor ตัวหนึ่งคล้ายๆ กับ Notepad++ แต่ว่าเป็นโปรแกรมที่มีอยู่ทั้งใน Windows, MacOS ก็เลยทำให้หลายคนใช้กัน เพราะว่าจะได้สภาพแวดล้อมที่คล้ายกันทั้งใน PC และ Mac
การติดตั้ง Sublime ก็ไม่ได้ยุ่งยากอะไร Search มาแล้วก็สามารถเลือกติดตั้งกันได้เลยทั้ง Windows, Mac แต่การจะใช้ Sublime ให้เป็นประโยชน์จะไม่ได้สิ้นสุดแค่นั้น จะต้องหา package อื่นๆ มาติดตั้งเพิ่มเติม เพื่อให้ Sublime สามารถทำงานได้มีประสิทธิภาพมากขึ้น ดังนั้นเมื่อติดตั้ง Sublime แล้ว สิ่งที่ควรติดตั้งตามมาคือ Package Control เพื่อให้สามารถติดตั้ง package อื่นๆ ต่อไปได้ ซึ่งวิธีติดตั้งสามารถเข้าไปดูจาก https://packagecontrol.io/installation ได้ค่ะ แต่สั้นๆ ก็คือไปที่เมนู View > Show Console แล้ว copy text จากในหน้าเวปนั้น ไปใส่กด enter เป็นอันเสร็จค่ะ
หลังจากนั้นสามารถกด Ctrl + Shift + p เพื่อติดตั้ง package อื่นๆ ต่อไป ซึ่ง package อื่นๆ ก็อย่างเช่น
- Emmet เป็นตัวช่วยให้การเขียนโปรแกรมง่ายขึ้น เช่น สามารถเขียน table>tr>td แล้วก็กด tab ได้เลย มันก็จะขึ้นมาเป็น tag table ทั้งหมดให้เรียบร้อย
- HTML5 เข้าใจว่าเป็นตัวที่ทำให้ Sublime รู้จัก tag HTML5 จะได้แสดงสีอย่างสวยงาม
- SublimeCodeIntel ใช้สำหรับ autocomplete code โดยเมื่อพิมพ์เข้าไปแล้วจะแสดงเป็น pop up มาให้เลือก
นอกจากนี้ยังมี package สำหรับแต่ละภาษาเช่น Python เพื่อให้แสดงสีตามแต่ละภาษาด้วย
ก็สรุปจบการแนะนำ Sublime พร้อมการติดตั้งไว้เท่านี้
การเปลี่ยนแปลงจนถึง Java8
เป็นการสรุปที่อบรมมาค่ะ เอาแบบสั้นมากๆ
Java5
- Fast Loop
for (int x : list)
- Variable Argument
public void doSomething (int... listInt)
- Format (printf)
- Enumeration ที่เป็น type safe
- Autoboxing
- Generic type
- Annotation
- Document annotation
- Static import package
import static java.lang.math.*;
Java6
- Script engine สามารถ run javascript ใน java ได้ ผ่าน class javax.script.ScriptEngine
- String pool คือมีการรวมค่าของ string ที่เป็นค่าเดียวกันไว้ด้วยกัน (แต่ไม่ใช่ค่า string ตอน runtime)
String s1 = "Hello";
String s2 = "Hello"; // s1 = s2
String s3 = new String("Hello"); // s1 <> s3
String s4 = s3.intern(); // s1 == s4
Java7
- String switcher คือใช้ string ในการเลือก case ได้
- Literal underscore สามารถเพิ่ม _ เพื่อให้อ่านง่าย
long a = 127_777;
byte x = 0b0111_1111;
- DiamondOp คือสามารถละ type ที่กำหนดใน generic class ได้
List b = new ArrayList<>();
- Null safe มี java.util.Objects ที่เป็น utility สำหรับจัดการค่าที่สามารถเป็น null ได้ เช่น equals(), toString()
- Multi-catch
try {
...
} catch (IndexOutOfBoundsException | NumberFormatException | ArithmeticException ex) {
System.out.println(ex.getClass());
}
- Try resource block
try (
/* create auto-closeable resource object (class that implements AutoCloseable interface) */
) {
...
} catch (Exception ex) {
...
}
- Walk โดยการเพิ่ม FileVisitor ใช้กับ Files.walkFileTree
- Watch โดยมี WatchService
WatchService ws = FileSystems.getDefault().newWatchService();
Path p = Paths.get("temp");
p.register(ws, StandardWatchEventKinds.ENTRY_DELETE);
Java8
- Interface สามารถสร้าง static method โดยจะต้องเป็น concrete method และเรียกผ่าน Interface ไม่ใช่เรียกที่ class
- Interface สามารถสร้าง default method ที่เป็น concrete method ได้
- Lambda ซึ่งจะถูกสร้างเป็น private method ใน class นั้นๆ (แม้ว่าจะคล้าย anonymous class) โดยใช้ annotation @FunctionalInterface เพื่อให้ compiler เช็คว่า interface เป็น SAM (Single Abstract Method) หรือเปล่า หรือจะใช้ predefined functional type (java.util.function.*) ก็ได้
- Optional ซึ่งเป็น class ใหม่ เพื่อไม่ให้เกิด NullPointerException แต่ต้องใช้คู่กับ method orElse, orElseGet, orElseThrow หรือ ifPresent (ทั้งนี้จะใช้ Optional ก็จะต้องรู้เรื่อง Lambda ก่อน เพราะว่าหลาย method จะต้องใช้ความสามารถนี้)
- Stream เป็น class ใหม่ และเพิ่ม method steam() ใน Collection และ Arrays เพื่อใช้ในการสร้าง stream หรือใช้ method of ของ Stream และเพิ่มค่าใน Stream โดย method add
Stream ss = Arrays.stream(array);
Stream sa = Stream.of(array);
Stream sd = Stream.generate(Math::random).limit(3); // สร้างค่าสุ่ม 3 ค่า
Stream sf = Files.lines(Paths.get("test.txt")); // สามารถอ่านจาก IO Stream ได้ด้วย
- Parallel โดยสามารถใช้ได้บน Stream โดยแค่กำหนดเป็น Stream.parallel()
- Parallel โดยใช้ class CompletableFuture
Port Exhaustion
ตามที่ได้เคย blog ไว้ว่า บังเอิญได้มาเกี่ยวข้องกับการทดสอบประสิทธิภาพของระบบซึ่งเป็น Window-base และได้เห็นปัญหาในการได้มาของ software จึงอยากจะจดบันทึกไว้เตือนตัวเอง และเผื่อจะเป็นประโยชน์กับคนอื่นได้บ้าง
ซึ่งจากการทดสอบระบบ เราพบว่า web application ที่ได้ทดสอบมีปัญหา เมื่อต้องรองรับผู้ใช้จำนวนมากๆ และจากผู้รู้หลายคนช่วยกันตรวจสอบจึงรู้ว่า อาการนี้เรียกว่า port exhaustion ซึ่งก็คือ application มีการใช้ dynamic port จนเต็ม ซึ่ง port ที่ใช้จะเป็น outbound connection (เพราะถ้าเป็น inbound มันจะมีอยู่ port เดียวอ่ะนะ)
ซึ่งวิธีการที่จะตรวจสอบการใช้ คือการใช้ netstat
> netstat -nao
ซึ่งจะแสดง connection ทั้งหมด และ pid เราจะต้องมองหา connection ที่ผิดปกติเอง ซึ่งโดยปกติถ้ามีอาการของ port exhaustion แสดงว่าจะต้องมีการใช้ port จำนวนมากจาก application หนึ่ง ซึ่งอาจจะดูได้จาก application ที่มี pid เดียวกัน และมีการใช้ port เป็นจำนวนมาก
ทีนี้หาได้แล้วทำไง ซึ่งจากเอกสารที่อ่านมา ที่ทำได้คือแจ้งเจ้าของ application ให้มาดูและแก้ไข หรือไม่ในฐานะของผู้พัฒนา application ก็คือจะต้องตรวจสอบ application ของเราเองว่ามีการใช้ connection เยอะเกินไปหรือไม่ แต่สำหรับบาง application ที่มาไกลเกินว่าจะแก้ไข วิธีที่จะแก้ไขได้ก็คือ
ทั้งนี้วิธีแก้ไข Port หรืออาการของ Port โดยละเอียด ดูได้จาก reference ข้างท้ายนะค่ะ (งานใหม่ๆ ไม่ได้มาพร้อมความลำบากเพียงอย่างเดียว มันมาพร้อมความรู้ใหม่ๆ เสมอ - เหรียญมี 2 ด้านเสมอเช่นเดียวกัน)
Reference:
Port Exhaustion
Avoiding TCP/IP Port Exhaustion
TcpTimedWaitDelay
MaxFreeTcbs
ซึ่งจากการทดสอบระบบ เราพบว่า web application ที่ได้ทดสอบมีปัญหา เมื่อต้องรองรับผู้ใช้จำนวนมากๆ และจากผู้รู้หลายคนช่วยกันตรวจสอบจึงรู้ว่า อาการนี้เรียกว่า port exhaustion ซึ่งก็คือ application มีการใช้ dynamic port จนเต็ม ซึ่ง port ที่ใช้จะเป็น outbound connection (เพราะถ้าเป็น inbound มันจะมีอยู่ port เดียวอ่ะนะ)
ซึ่งวิธีการที่จะตรวจสอบการใช้ คือการใช้ netstat
> netstat -nao
ซึ่งจะแสดง connection ทั้งหมด และ pid เราจะต้องมองหา connection ที่ผิดปกติเอง ซึ่งโดยปกติถ้ามีอาการของ port exhaustion แสดงว่าจะต้องมีการใช้ port จำนวนมากจาก application หนึ่ง ซึ่งอาจจะดูได้จาก application ที่มี pid เดียวกัน และมีการใช้ port เป็นจำนวนมาก
ทีนี้หาได้แล้วทำไง ซึ่งจากเอกสารที่อ่านมา ที่ทำได้คือแจ้งเจ้าของ application ให้มาดูและแก้ไข หรือไม่ในฐานะของผู้พัฒนา application ก็คือจะต้องตรวจสอบ application ของเราเองว่ามีการใช้ connection เยอะเกินไปหรือไม่ แต่สำหรับบาง application ที่มาไกลเกินว่าจะแก้ไข วิธีที่จะแก้ไขได้ก็คือ
- เพิ่ม dynamic port ซึ่งแต่เดิม Windows Server 2012 จะมีการกำหนดค่า MaxUserPort ไว้ใน Windows Registry โดยสามารถกำหนได้สูงสุดคือค่า 65534 (แต่ port 1024 แรก จะกันไว้สำหรับ application บางตัวอยู่แล้ว)
- กำหนด connection timeout ของ port ให้ลดลง เนื่องจาก หลังจากที่ application ได้มีการปิด port ไปแล้ว port นั้นๆ จะยังใช้ไม่ได้จนกว่า 4 นาทีต่อมา ซึ่งจะต้องไปแก้ไขค่า TcpTimedWaitDelay ใน Windows Registry (แต่อยากให้ลองหาข้อมูลเพิ่มเติมกันนะค่ะ ว่าทำไมมันถึงต้องกันไว้ 4 นาที เพื่อสวัสดิภาพของระบบโดยแท้จริง)
ทั้งนี้วิธีแก้ไข Port หรืออาการของ Port โดยละเอียด ดูได้จาก reference ข้างท้ายนะค่ะ (งานใหม่ๆ ไม่ได้มาพร้อมความลำบากเพียงอย่างเดียว มันมาพร้อมความรู้ใหม่ๆ เสมอ - เหรียญมี 2 ด้านเสมอเช่นเดียวกัน)
Reference:
Port Exhaustion
Avoiding TCP/IP Port Exhaustion
TcpTimedWaitDelay
MaxFreeTcbs
Thailand SPIN 2015
- เน้น business value สำหรับแต่ละ feature
- gap between business and technical make agile stuck.
- อะไรที่เกี่ยวกับ budget เป็นหน้าที่ของ pm.
- cost of quality มีจริง (including agile)
- การได้ cert มาง่าย การรักษาให้ quality of process คงอยู่ยาก
- agile ต้องทำทุกระดับในองค์กร
- agile เป็นแค่ tools เลือกใช้ให้ถูก
ติดตั้ง Git เชื่อมต่อกับ GitHub
1. สมัคร GitHub ที่ https://github.com/
เมื่อสมัครแล้ว GitHub จะส่งเมล์มา verify email ที่เราใส่ไป เพราะจะใช้เป็น email ในการส่งการเปลี่ยนแปลงของ project ที่เราเข้าร่วมมาให้ ให้เราทำการ verify ให้เรียบร้อย
2. download โปรแกรมจาก http://git-scm.com/
3. double click เพื่อติดตั้ง
4. สร้าง ssh key สำหรับเชื่อมต่อกับ GitHub ในการ push, pull ไฟล์
โดยการ คลิ๊กขวาที่ directory ใดๆ เลือก Git Bash
เมื่อเข้าหน้า command ให้ใช้คำสั่ง
$ ssh-keygen
ซึ่ง git จะไปสร้าง key file ใน home directory\.ssh ของ user ซึ่งสำหรับ Windows จะอยู่ที่ C:\Users\[username]\.ssh
ซึ่งไฟล์จะประกอบด้วย
5. add public key ใน GitHub
โดย login เข้า GitHub
เลือก Setting
เลือก SSH Keys
กดปุ่ม Add SSH Key
ตั้งชื่อ title ซึ่งเป็นอะไรก็ได้
copy content ของ id_rsa.pub ใส่ใน key
โดย 1 user จะสามารถมี key ที่เครื่องใดๆ ได้ 1 key เท่านั้น แต่ถ้า 1 user มีหลายเครื่องก็จะต้องสร้าง key สำหรับแต่ละเครื่องในการติดต่อกับ GitHub
6. ตั้งค่า user name, email
ใน Git Bash
$ git config --global user.name "xxx"
$ git config --global user.email "xxx@xxx"
เท่านี้ก็น่าจะเสร็จเรียบร้อยสำหรับการติดตั้งค่ะ
เมื่อสมัครแล้ว GitHub จะส่งเมล์มา verify email ที่เราใส่ไป เพราะจะใช้เป็น email ในการส่งการเปลี่ยนแปลงของ project ที่เราเข้าร่วมมาให้ ให้เราทำการ verify ให้เรียบร้อย
2. download โปรแกรมจาก http://git-scm.com/
3. double click เพื่อติดตั้ง
4. สร้าง ssh key สำหรับเชื่อมต่อกับ GitHub ในการ push, pull ไฟล์
โดยการ คลิ๊กขวาที่ directory ใดๆ เลือก Git Bash
เมื่อเข้าหน้า command ให้ใช้คำสั่ง
$ ssh-keygen
ซึ่ง git จะไปสร้าง key file ใน home directory\.ssh ของ user ซึ่งสำหรับ Windows จะอยู่ที่ C:\Users\[username]\.ssh
ซึ่งไฟล์จะประกอบด้วย
- known_hosts เป็น ip และ public key ของ GitHub
- id_rsa ซึ่งเป็น private key
- id_rsa.pub เป็น public key
5. add public key ใน GitHub
โดย login เข้า GitHub
เลือก Setting
เลือก SSH Keys
กดปุ่ม Add SSH Key
ตั้งชื่อ title ซึ่งเป็นอะไรก็ได้
copy content ของ id_rsa.pub ใส่ใน key
โดย 1 user จะสามารถมี key ที่เครื่องใดๆ ได้ 1 key เท่านั้น แต่ถ้า 1 user มีหลายเครื่องก็จะต้องสร้าง key สำหรับแต่ละเครื่องในการติดต่อกับ GitHub
6. ตั้งค่า user name, email
ใน Git Bash
$ git config --global user.name "xxx"
$ git config --global user.email "xxx@xxx"
เท่านี้ก็น่าจะเสร็จเรียบร้อยสำหรับการติดตั้งค่ะ
สรุปคำสั่ง run Robot Framework
สำหรับการทำงานพื้นฐานเลย คือสั่งให้ script ทำงานธรรมดา
> pybot [filename.txt]
สำหรับการกำหนดตำแหน่งที่เก็บไฟล์ที่ได้จากการทำงานของ script
> pybot --output [folder] [filename.txt]
> pybot --log [folder] [filename.txt]
> pybot --report [folder] [filename.txt]
และถ้าต้องการให้ไฟล์ที่ได้มีการใส่วันเวลาต่อท้าย เพื่อไม่ให้ทับไฟล์เก่า
> pybot --timestampoutputs [filename.txt]
> pybot -T [filename.txt]
> pybot --variable [name]:[value]
หรือกำหนดประเภทการทำงานซึ่งได้แก่ ExitOnFailure, random:test, random:suit, randam:all
> pybot --runmode [mode] [filename.txt]
> pybot [filename.txt]
สำหรับการกำหนดตำแหน่งที่เก็บไฟล์ที่ได้จากการทำงานของ script
> pybot --output [folder] [filename.txt]
> pybot --log [folder] [filename.txt]
> pybot --report [folder] [filename.txt]
หรือถ้าต้องการเก็บทั้งหมดไว้ใน folder เดียวกัน
> pybot --outputdir [folder] [filename.txt]
> pybot -d [folder] [filename.txt]
> pybot -d [folder] [filename.txt]
> pybot --timestampoutputs [filename.txt]
> pybot -T [filename.txt]
หรือในกรณีต้องการกำหนดค่าตัวแปรที่จะใส่เข้าไปใน script
หรือกำหนดประเภทการทำงานซึ่งได้แก่ ExitOnFailure, random:test, random:suit, randam:all
> pybot --runmode [mode] [filename.txt]
ติดตั้ง Sublime สำหรับ Robot Framework
Sublime เป็น text editor ตัวหนึ่งเท่านั้นเองค่ะ แต่ว่ามันมี package เสริมสำหรับเขียน Robot Framework script
วิธีการติดตั้ง
1. download โปรแกรมกันได้ที่ http://www.sublimetext.com/
สำหรับเราเลือก download เป็น portable ค่ะ
2. extract ตัว .zip ก็เป็นอันเสร็จเลย
3. ติดตั้ง package control ของ sublime โดย copy คำสั่งใน https://packagecontrol.io/installation#st2
ไปที่ sublime console (เมนู View > Show Console) แล้ว enter เลย
4. ติดตั้ง Robot Framework package
ไปที่เมนู Tools > Command Palette...
พิมพ์และเลือก "Package Control : Install Package"
พิมพ์ Robot เลือกติดตั้ง Robot Framework 2 package
เสร็จแล้วค่า... ต่อไปก็เริ่มเขียนได้เลย
วิธีการติดตั้ง
1. download โปรแกรมกันได้ที่ http://www.sublimetext.com/
สำหรับเราเลือก download เป็น portable ค่ะ
2. extract ตัว .zip ก็เป็นอันเสร็จเลย
3. ติดตั้ง package control ของ sublime โดย copy คำสั่งใน https://packagecontrol.io/installation#st2
ไปที่ sublime console (เมนู View > Show Console) แล้ว enter เลย
4. ติดตั้ง Robot Framework package
ไปที่เมนู Tools > Command Palette...
พิมพ์และเลือก "Package Control : Install Package"
พิมพ์ Robot เลือกติดตั้ง Robot Framework 2 package
เสร็จแล้วค่า... ต่อไปก็เริ่มเขียนได้เลย
ติดตั้ง Robot Framework
ก่อนจะติดตั้ง Robot Framework กรุณาติดต้้ง Python ก่อนนะค่ะ
หลังจากติดตั้ง Python เสร็จแล้ว ก็ติดตั้ง Robot Framework จาก pip เลยค่ะ
1. ติดตั้ง Robot Framework โดย run command
> pip install robotframework
จากนั้นให้ลอง run command
> pybot
จะได้ดังนี้
2. ติดตั้ง Selenium บน Robot Framework เพื่อใช้ในการทดสอบ web application
> pip install robotframework-selenium2library
แค่นี้เสร็จแล้วค่ะ
หลังจากติดตั้ง Python เสร็จแล้ว ก็ติดตั้ง Robot Framework จาก pip เลยค่ะ
1. ติดตั้ง Robot Framework โดย run command
> pip install robotframework
จากนั้นให้ลอง run command
> pybot
จะได้ดังนี้
2. ติดตั้ง Selenium บน Robot Framework เพื่อใช้ในการทดสอบ web application
> pip install robotframework-selenium2library
แค่นี้เสร็จแล้วค่ะ
ติดตั้ง Python และ pip
เริ่มมาจากไปเรียน Robot Framework ซึ่งเป็น Tools สำหรับทำการทดสอบโปรแกรม และตัว Robot Framework มันเป็น Python ค่ะ ก็เลยต้องติดตั้ง ก็เลยเอามาฝากเล่นๆ
1. download Python ก่อนค่ะ ที่นี่ https://www.python.org/downloads/ ซึ่งสำหรับ Robot Framework จะต้องใช้ version 2 เพราะเหมือนยังมีปัญหากับ version 3 ก็ download version 2.7.9 มาค่ะ เป็น file .msi สำหรับการติดตั้งบน Windows
2. ก็ double click ที่ตัว .msi ที่ได้มา แล้วอย่าลืมเลือก "Add python.exe to Path" ด้วยนะค่ะ จะได้ไม่ต้องมา add เองทีหลัง
3. จากนั้น ติดตั้ง pip ซึ่งเป็นตัวจัดการ package สำหรับ Python (Package Installation for Python)
โดยการ download get-pip.py จากหน้า http://www.pip-installer.org/en/latest/installing.html
4. แล้ว run command
เมื่อลงเสร็จแล้ว เราสามารถลบตัว get-pip.py ออกไปได้เลยค่ะ
1. download Python ก่อนค่ะ ที่นี่ https://www.python.org/downloads/ ซึ่งสำหรับ Robot Framework จะต้องใช้ version 2 เพราะเหมือนยังมีปัญหากับ version 3 ก็ download version 2.7.9 มาค่ะ เป็น file .msi สำหรับการติดตั้งบน Windows
2. ก็ double click ที่ตัว .msi ที่ได้มา แล้วอย่าลืมเลือก "Add python.exe to Path" ด้วยนะค่ะ จะได้ไม่ต้องมา add เองทีหลัง
แต่ถ้าใครลืม ก็สามารถเพิ่ม PYTHON_HOME ไปยัง directory ที่ติดตั้ง ลงในตัวแปร PATH ใน environment variable ที่หลังได้ค่ะ
ทดสอบโดยการพิมพ์ python ที่หน้า command
ถ้าได้ฉะนี้ ก็แปลว่า ลง Python เรียบร้อย
3. จากนั้น ติดตั้ง pip ซึ่งเป็นตัวจัดการ package สำหรับ Python (Package Installation for Python)
โดยการ download get-pip.py จากหน้า http://www.pip-installer.org/en/latest/installing.html
4. แล้ว run command
> python get-pip.py
5. เพิ่ม %PYTHONE_HOME%/Scripts ในตัวแปร PATH เพื่อให้สามารถ run pip ได้เมื่อลงเสร็จแล้ว เราสามารถลบตัว get-pip.py ออกไปได้เลยค่ะ
Cloud (สรุปอย่างย่อ)
Cloud Computing Definition - Key Character
- On-demand self-service
- Ubiquitous network access
- Location independent resource polling
- Rapid elasticity
- Pay per use
Cloud Delivery Model
Traditional Model
- Software as a Service (SaaS)
- Platforms as a Service (PaaS)
- Infrastructure as a Service (Iaas)
Latest Model
- Process as a Service คือ Traditional Model ที่ความสามารถ Business Process Management, Service Oriented Architecture, Social Software
Cloud Technology's Type
- Cloud 1.0 : IaaS - ทดแทน Hosting Service
- Cloud 2.0 : Iaas + Mobile App - จัดการพวก non-sql data, non-structure data (Hadoop)
- Cloud 3.0 : IaaS, PaaS, HPC, Big Data Analysis
Cloud Computing Standard Recommendation
- ISO 27001 (Security Foundation)
- ISO 22301 (BCM)
- CSA Star Cert (Cloud, Governance)
- ISO 50000 (Energy Management)
- ISO 14001 (Environmental)
- ISO 14064 (Greenhouse Gas)
Big Data's Type
- 1.0 (Transaction Data, Structure Data) - ข้อมูลจากในองค์กร ex. ERP ใช้ Data Mining
- 2.0 (Non-structure Data) - เพิ่มข้อมูลจาก Social Nework ใช้ Grid Computing (Hadoop)
- 3.0 (Huge, Very Large Data) - เพิ่มข้อมูลจาก IoT ใช้ HPC ไม่เน้น Hadoop
.Net constants, Settings.settings, Resources.resx
ไม่รู้คนอื่นเป็นหรือเปล่า แต่เรามีความสับสนในการกำหนดค่าต่างๆ ในโปรแกรม ไม่รู้ว่าควรจะกำหนดยังไงดี
- กำหนดเป็นค่าคงที่ใน Code
- กำหนดใน Settings.settings
- กำหนดใน Resources.resx
ก็ไปอ่านเจอบทความหนึ่ง ซึ่งรู้สึกว่าอ่านแล้วกระจ่างมาก เลยแปลมาให้กัน สำหรับใครที่อยากอ่านต้นฉบับดูที่ที่ลิงค์ท้ายบทความค่ะ
เค้าบอกว่าเกณฑ์ในการเลือกว่าควรจะกำหนดค่าอะไรไว้ยังไงมีดังนี้
- ถ้าเป็นค่าที่ไม่ได้ให้ผู้ใช้แก้ไข และเกี่ยวข้องกับ class ใด class หนึ่งโดยเฉพาะ ให้กำหนดเป็นค่าคงที่ใน class นั้นๆ
- ถ้าเป็นค่าที่ไม่ได้ให้ผู้ใช้แก้ไข แต่เกี่ยวข้องกับหลาย class ให้กำหนดเป็นค่าคงที่ใน class กลางของโปรเจค
- ถ้าเป็นค่าที่ให้ผู้ใช้แก้ไขได้ ให้กำหนดใน Settings.settings.
- ถ้าเป็นค่าที่ต้องแก้ไขโดยขึ้นกับ locale ให้กำหนดใน Resources.resx
- ถ้าเป็นค่าที่ต้องเปลี่ยนแปลงตามกลุ่ม (เข้าใจว่า เช่นค่าที่กำหนดสำหรับแต่ละหน้าจอ เหมือนที่เรากำหนด label ในหน้าจอ) ก็ให้กำหนดใน Resource.resx ตามโฟลเดอร์
และในบทความก็สรุปว่า Resources.resx จะกำหนดได้ก่อน build เท่านั้น ผู้ใช้ไม่สามารถเปลี่ยนค่าได้ ในขณะที่ Settings.settings สามารถแก้ได้โดยผู้ใช้ แต่ Settings.settings จะไม่เปลี่ยนตาม locale เหมือนกับ Resources.resx
References:
การ Generate Entity class จาก Entity Framework
ที่เราใช้อยู่ขณะนี้เป็น EF 6 นะค่ะ
1. คลิ๊ก Add > New Item... ที่โปรเจค
2. เลือก ADO.NET Entity Data Model และตั้งชื่อ ซึ่งจะเป็นชื่อของ .edmx ไฟล์
3. เลือกวิธีที่จะได้ diagram มา ซึ่งเราเลือกเป็น Empty EF Designer model ซึ่งจะได้ diagram เปล่าๆ มาแล้วมาใส่ entity ต่างๆ เองค่ะ
4. จากนั้นก็สร้าง Entity โดยใช้ Toolbox ด้านข้าง
5. หลังจากนั้นก็ถึงวิธีการ generate Entity โดยคลิ๊กขวาที่ diagram เลือก Generate Database from Model...
6. ถ้าเป็นการ generate ครั้งแรก VS จะขึ้นหน้าต่างมาให้เราสร้าง Connection string โดยเราจะต้องเลือกฐานข้อมูลที่เราต้องการจะให้สร้าง Entity (ทั้งนี้มันจะไม่ได้ไปสร้าง table หรืออะไรในฐานข้อมูลนั้นๆ หรอกนะค่ะ แค่เลือกเพื่อเอาไปสร้าง Connection string เฉยๆ เราจะต้องไปสร้าง table เองค่ะ)
เมื่อเสร็จแล้ว มันจะให้เรายืนยันว่าจะให้บันทึก password ของฐานข้อมูลใน Connection string หรือเปล่า ซึ่งเราจะให้มันบันทึกหรือไม่ก็ได้ค่ะ
7. เราจะได้
1. คลิ๊ก Add > New Item... ที่โปรเจค
2. เลือก ADO.NET Entity Data Model และตั้งชื่อ ซึ่งจะเป็นชื่อของ .edmx ไฟล์
3. เลือกวิธีที่จะได้ diagram มา ซึ่งเราเลือกเป็น Empty EF Designer model ซึ่งจะได้ diagram เปล่าๆ มาแล้วมาใส่ entity ต่างๆ เองค่ะ
4. จากนั้นก็สร้าง Entity โดยใช้ Toolbox ด้านข้าง
5. หลังจากนั้นก็ถึงวิธีการ generate Entity โดยคลิ๊กขวาที่ diagram เลือก Generate Database from Model...
6. ถ้าเป็นการ generate ครั้งแรก VS จะขึ้นหน้าต่างมาให้เราสร้าง Connection string โดยเราจะต้องเลือกฐานข้อมูลที่เราต้องการจะให้สร้าง Entity (ทั้งนี้มันจะไม่ได้ไปสร้าง table หรืออะไรในฐานข้อมูลนั้นๆ หรอกนะค่ะ แค่เลือกเพื่อเอาไปสร้าง Connection string เฉยๆ เราจะต้องไปสร้าง table เองค่ะ)
เมื่อเสร็จแล้ว มันจะให้เรายืนยันว่าจะให้บันทึก password ของฐานข้อมูลใน Connection string หรือเปล่า ซึ่งเราจะให้มันบันทึกหรือไม่ก็ได้ค่ะ
7. เราจะได้
- file .sql มา สำหรับไป execute ในฐานข้อมูล
- ได้ Entity Container .cs
- ได้ Entity .cs
เป็นอันเสร็จค่ะ
หมายเหตุ
- ใน Entity Framework ไม่สามารถสร้าง unique key ที่ไม่ใช่ primary ได้ค่ะ ตามลิงก์
หมายเหตุ
- ใน Entity Framework ไม่สามารถสร้าง unique key ที่ไม่ใช่ primary ได้ค่ะ ตามลิงก์
Subscribe to:
Posts (Atom)





