Mọi developer thì đều chắc cũng đã biết đến sublime text, nói ngắn gọn thì nó là một chương trình dùng để code. Nhưng ở bài viết này tôi sẽ không hướng dẫn về code mà sẽ hướng dẫn về những thủ thuật của sublime text mà sẽ giúp chúng ta tăng hiệu suất làm việc lên.
2. Ví dụ
Tôi sẽ cho ví dụ về một bài tập java Problem1, bài tập này yêu cầu chúng ta tạo class Drink, Food, Cloth, Material và tạo các thuộc tính cho những class đó theo như hình bên dưới.
Nếu ai đã làm qua java hoặc môt ngôn ngữ nào đó thì khi đọc vào bài Prolem1 này thì các bạn sẽ đều hình dung ra cách làm rồi. Đầu tiên là chúng ta sẽ tạo class Drink sau đó sẽ copy các thuộc tính vào và tạo public/private, kiểu dữ liệu cho các thuộc tính đó. Tuy nhiên những class này có số lượng các thuộc tính ít cho nên sẽ không mất thời gian nhiều cho việc này. Giả sử những class sẽ có vài chục hay lên đến cả trăm thuộc tính thì cũng sẽ mất rất nhiều thời gian để tạo.
Vì vậy bài viết này ra đời nhằm giúp cho các bạn rút ngắn được thời gian tạo các thuộc tính cho class. Tôi sẽ sử dụng chức năng trong sublime text để hỗ trợ cho việc này. Hãy cùng bắt đầu nhé.
2.1 Tạo class Drink (Tôi sử dụng eclipse)
2.2 Copy các thuộc tính và kiểu dữ liệu của Drink vào sublime text
2.3 Nhấn giữ nút Shift + Chuột phải, rê chuột từ đầu dòng của vị trí 1 – 6 để chọn toàn bộ tất cả các đầu dòng.
2.4 Gõ vào chữ [private]
2.5 Nhấn giữ nút Ctrl + Shift, và nhấn nút > để chọn tất cả các tên thuộc tính, khi đó ra được hình bên dưới.
2.6 Nhấn phím > (2 lần), để di chuyển con trỏ sang phải 2 ký tự.
2.7 Nhấn giữ nút Shift và nhấn thêm nút End để chọn toàn bộ những kiểu dữ liệu phía sau.
2.8 Nhấn Ctrl + X để cắt toàn bộ kiểu dữ liệu để di chuyển ra vị trí trước của thuộc tính.
2.9 Nhấn phím BackSpace để xóa đi khoảng trắng, sau đó nhấn ; để thêm vào cuối cho các thuộc tính.
2.10 Nhấn giữ Ctrl + Shift và nhấn phím < (Left) để chọn toàn bộ tên các thuộc tính.
2.11 Nhấn phím < để di chuyển sang trái 1 ký tự và Ctrl + V để dán các kiểu dữ liệu mà đã cắt ở 2.8, sau đó nhấn phím space sẽ được như sau.
2.12 Cuối cùng ta copy toàn bộ và paste vào trong eclipse
Quá trình trên tuy nhiều bước nhưng nếu các bạn mà thao tác quen thì sẽ làm rất là nhanh, không mất quá nhiều thời gian. Hãy xem video demo nhé, mình thao tác rất chậm mà chưa tới 1p
Bài viết được sự cho phép của tác giả Trần Hữu Cương
Java Reflection là gì?
Java Refelection là một tính năng (gọi là API hay thư viện cũng được) trong Java. Java Reflection cho phép truy cập các thông tin của đối tượng (tên class, các field, các method) và chỉnh sửa các field của đối tượng (kể cả các field private) trong quá trình run time.
Ta có thể áp dụng Java Reflection trong những trường hợp không biết object được xử lý là gì. (tên class là gì, ở package nào, có những field nào, method nào…).
Ví dụ mình muốn viết một hàm copy 2 đối tượng có thể dùng cho loại đối tượng khác nhau. Thì mình cần phải biết 2 đối tượng có cùng kiểu không, có những field nào, lấy và copy giá trị từng field.
Ngoài ra, với các field, method có modifier là private thì ta không thể truy cập ở bên ngoài class đó. Trong những trường hợp bắt buộc phải gọi, truy cập các field, method private ở bên ngoài class đó thì Reflection là một giải pháp.
Trong trường hợp đã biết rõ cấu trúc class, có quyền truy cập các field, method thì ta không nên sử dụng Java Reflection bởi các lý do sau:
Hiệu năng thấp: Ví dụ nó phải quét classpath để tìm class.
Các vấn đề bảo mật: Việc chỉnh sửa class/object trong quá trình runtime có thể ảnh hưởng tới các thread … khiến cho ứng dụng bị fail.
Khó bảo trì: Việc Reflection khá khó hiểu với người mới và không dễ để debug, nên sẽ rất khó để có thể tìm ra lỗi. Ngoài ra chúng ta cũng không thể check được một số lỗi trong quá trình compile (không tìm thấy class, không tìm thấy field…)
Các thành phần trong Java Reflection
Tương ứng với các thành phần trong một class, thì Java Reflection cũng cung cấp các class tương ứng để ta có thể xử lý:
Class: Đại diện cho class/interface để lấy ra các thông tin của class (tên class, super class, class modifier, các method, các field …)
Constructor: Xử lý các hàm khởi tạo của class
Field: Xử lý các field của class (tên, modifier của field, lấy giá trị, thiết lập giá trị cho object…)
Method: Xử lý các method của class (liệt kê các method, thực thi các method …)
Bạn có thể lấy đối tượng Class thông qua một object với method getClass() hoặc thông qua tên package + tên class với method Class.forName
Để lấy danh cách các hàm khởi tạo, các field, các method ta có thể dùng method getConstructors(), getFields() hoặc getMethods(). Tuy nhiên các method không cho phép lấy các constructor, method, field có modifier là private do đó mình sẽ dùng getDeclaredConstructors(), getDeclaredFields(), getDeclaredMethods().
Method getModifier() trả về modifier của class, method, field nhưng ở dạng số dó đó mình sẽ viết thêm method getModifierName để hiển thị nó dưới dạng String.
Để lấy giá trị hoặc truyền giá trị cho các field của đối tượng bạn có thể dùng method field.set() / field.get()
Demo:
Class name: stackjava.com.reflection.CustomerSuper Class name: stackjava.com.reflection.PersonIs interface: falseConstructors: Number of parameters: 0 - modifier: public Number of parameters: 2 - modifier: publicFields: age - type: int - modifier: private gender - type: class java.lang.String - modifier: protected name - type: class java.lang.String - modifier: public phone - type: class java.lang.String - modifier: defaultMethods: toString - modifier: public getName - modifier: public setName - modifier: public setAge - modifier: public hello - modifier: public setPhone - modifier: public goodbye - modifier: private setGender - modifier: public getPhone - modifier: public getAge - modifier: public getGender - modifier: public
Học lập trình? – Yêu thích và đam mê phát triển website, các ứng dụng, phần mềm, thiết kế game là những lý do khiến nhiều bạn trẻ muốnhọc Code. Tuy nhiên, không phải bạn trẻ nào cũng may mắn có được những định hướng tốt và tìm ra cho mình con đường học tập nhanh nhất.
Nay mình muốn giới thiệu đến anh em 38 blog kỹ thuật của các công ty lớn mà bạn nên theo dõi. Hoặc bạn có thể bookmark chúng để tham khảo khi cần.
Hy vọng danh sách trở thành hành trang cho anh em khởi đầu con đường học Coder, nâng cao kiến thức về các hệ sinh thái công nghệ toàn cầu. Mình biết danh sách trên cũng chưa hẳn là nhiều. Nên nếu có thể, hy vọng anh em sẽ đóng góp thêm một vài blog khác bên dưới comment. Cảm ơn mọi người
Bài viết được sự cho phép của tác giả Vũ Công Tấn Tài
Con trỏ this có lẽ là một khái niệm không mấy xa lạ trong lập trình hướng đối tượng, nó là một thể hiện cho đối tượng đang chứa đoạn mã lệnh đang được thực thi, hiểu nôm na kiểu ngôn ngữ con người là thế này:
Nam học bài rất chăm chỉ vì sẽ có một bài kiểm tra vào cuối tuần, bài kiểm tra này rất quan trọng đối với Nam.
Có thể biểu diễn câu nói này bằng một cách khác như sau:
Nam học bài rất chăm chỉ vì sẽ có một bài kiểm tra vào cuối tuần này, bài kiểm tra này rất quan trọng đối với anh ấy.
Hai câu trên hoàn toàn đồng nghĩa với nhau, mặc dù không nói rõ ràng nhưng tất cả chúng ta đều hiểu “anh ấy” chính là “Nam”. Con trỏ this cũng có ý nghĩa tương tự như thế, và nếu nói theo ngôn ngữ con người, thì con trỏ this chính là một “đại từ nhân xưng” nhằm ám chỉ một đối tượng cụ thể đã được chỉ rõ ở ngữ cảnh trước đó. Con trỏ this được sử dụng rất nhiều trong các đoạn mã JS, và nó cũng là một trong những khái niệm gây ra nhiều sự hiểu lầm (dẫn đến bug) nhất trong ngôn ngữ này.
Để lập trình tốt bằng Javascript thì người lập trình viên buộc phải hiểu rõ cách mà con trỏ this vận hành, sẽ là hơi dài dòng nếu ta muốn tìm hiểu đầy đủ về nó, nhưng một khi đã hiểu về nó, ta sẽ thấy công sức ta bỏ ra không phí một chút nào. Mọi người sẽ cần 1 chút kiên nhẫn để đạt được điều đó
Trong các ngôn ngữ lập trình như C++, C#, Java, PHP hay cả Javascript, con trỏ this thường được sử dụng để chỉ đến object chứa phương thức đang được gọi thực thi, trông ra thì cách dùng này có vẻ tường minh và dễ hiểu, các đoạn mã kiểu đó thường có dạng như:
Khi đoạn code trên được biên dịch và hàm getName() được gọi, thì con trỏ this trong hàm getName() được hiểu là đối tượng Hocsinh1 và this.name chính là chỉ định tới thuộc tính name của đối tượng Hocsinh1 đó. Cũng giống như “đại từ nhân xưng” trong ngôn ngữ nói, this đại diện cho đối tượng (object) ở trong ngữ cảnh (context) được nhắc đến trước đó. Rất dễ hiểu phải không nào, tuy nhiên ta hãy xem xét một chút sâu hơn bên trong, chúng ta cũng sẽ bàn sâu hơn về khái niệm object và context ở những phần tiếp theo.
Cần nói qua một chút về hàm (function) ở trong Javascript, như ta đã biết thì trong JS một hàm cũng chính là một đối tượng (object), và đối tượng thì sẽ có những thuộc tính của riêng nó. Trong JS, khi một hàm được gọi, thì nó sẽ có một thuộc tính là this, và thuộc tính this này chứa giá trị về một đối tượng đang gọi tới hàm này.
Tức là, khi một function được gọi (tạm gọi là function A), thì con trỏ this chứa giá trị của đối tượng gọi tới A, và ta có thể thông qua con trỏ this này để lấy các giá trị thuộc tính khác nằm trong đối tượng vừa gọi tới A.
var Hocsinh1 = {
name: “John”,
getName: function(){
return this.name;
}
};
var _name = Hocsinh1.getName();
Quay lại ví dụ trước, this được khai báo trong hàm getName(), và hàm getName() là hàm sẽ được gọi tới bởi đối tượng Hocsinh1, do đó this ở đây được hiểu là sẽ mang giá trị tham chiếu tới đối tượng Hocsinh1. Tới đây thì cách dùng con trỏ this trong Javascript là tương đồng với các ngôn ngữ khác: giá trị của con trỏ this là rỗng cho tới khi thực sự có một đối tượng gọi tới hàm chứa con trỏ this.
Trong hầu hết mọi trường hợp, this sẽ chứa giá trị của đối tượng gọi tới nó, tuy nhiên việc một hàm trong Javascript cũng chính là 1 đối tượng khiến ta có thể dễ dàng truyền nó vào một tham số của hàm nào đó để sử dụng như một hàm callback, chính điều này sẽ dẫn tới các tình huống mà con trỏ this không thực sự chứa giá trị của đối tượng mà nó thuộc về.
Chúng ta sẽ xem xét 4 trường hợp mà con trỏ this trở nên mơ hồ hơn so với ví dụ ở trên, chúng ta sẽ đi phân tích chi tiết từng trường hợp ở phần tiếp theo:
Con trỏ this trong việc sử dụng hàm callback
Con trỏ this bên trong 1 closure
Con trỏ this trong trường hợp gán hàm cho một biến khác
Mặc dù các ngôn ngữ lập trình hiện đại như C# hoặc Java cũng hỗ trợ hàm callback (như delegate function của C#), tuy nhiên việc sử dụng hàm callback ở trong Javascript thông dụng hơn rất nhiều. Có thể nói nôm na hàm callback là việc chúng ta truyền 1 hàm với vai trò như một tham số vào một hàm khác để có thể kích hoạt hàm đó sau này. Xét ví dụ sau:
//Định nghĩa 1 đối tượng với phương thức hiển thị thuộc tính ra màn hình
var Hocsinh = {
name: “John”,
printName: function(){
console.log(this.name);
}
};
//Bắt sự kiện click chuột lên button, sẽ thực thi hàm hiển thị tên của Hocsinh lên màn hình
$(‘button’).click(Hocsinh.printName);
Theo ý tưởng của người lập trình, khi người dùng click chuột vào button thì hàm printName() sẽ được gọi để hiển thị tên của Hocsinh lên màn hình. Tuy nhiên đoạn code trên sẽ không thể chạy đúng như mong muốn. Lí do bởi vì khi sự kiện click được kích hoạt, thì sự kiện này đang được gán tới đối tượng $(‘button’), chúng ta truyền hàm Hocsinh.printName vào bên trong hàm click() như một đối tượng callback. Lúc này – khi hàm click() được gọi – hàm Hocsinh.printName được kích hoạt, tuy nhiên đối tượng gọi tới hàm này không còn là đối tượng Hocsinh nữa (mà là đối tượng $(‘button’) của jQuery) nên cho trỏ this không còn tham chiếu tới giá trị của đối tượng Hocsinh, dẫn tới việc gọi “this.name” là vô nghĩa.
Sự nhập nhằng này có thể được mô tả ngắn gọn như sau: khi hàm click() kích hoạt hàm callback Hocsinh.printName, thì context của hàm Hocsinh.printName đã bị thay đổi sang đối tượng $(‘button’).
Để đoạn code trên chạy đúng như mong muốn – in ra được name của Hocsinh – thì ta phải đảm bảo được context của hàm callback Hocsinh.printName là chính đối tượng Hocsinh lúc hàm này được gọi. Để thay đổi context, chúng ta có thể dùng hàm Apply(), Call() hay Bind() hỗ trợ sẵn bởi Javascript. Cụ thể trong trường hợp này chúng ta có thể dùng hàm Bind() để gắn context vào hàm callback đó.
//Thay vì viết
$(‘button’).click(Hocsinh.printName);
//Chúng ta sẽ viết
$(‘button’).click(Hocsinh.printName.Bind(Hocsinh));
Đoạn code trên có ý nghĩa là: khi hàm click() gọi tới hàm callback Hocsinh.printName, thì context của hàm callback này là đối tượng Hocsinh chứ không phải đối tượng $(‘button’). Khi đó thì hàm callback Hocsinh.printName sẽ lấy đúng giá trị this.name là Hocsinh.name. Vấn đề được giải quyết!
2. Con trỏ this trong closure
Nói một cách ngắn gọn thì closure là một hàm con (inner function) nằm bên trong 1 hàm khác (outer function). Mọi người có thể tìm hiểu thêm ở đây. Ta đã biết rằng closure thì không thể truy cập tới con trỏ this của hàm cha (outer function), do đó sẽ có thể xuất hiện trường hợp như sau:
var user = {
tournament:"The Masters",
data: [
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],
clickHandler: function () {
//Sử dụng con trỏ this ở đây thì OK, this đang mang giá trị tham chiếu tới đối tượng “user”
this.data.forEach (function (person) {
//Tuy nhiên, trong closure này thì this không còn tham chiếu tới đối tượng “user” nữa
// Hàm inner function này không thể truy cập tới this của outer function
console.log (person.name + " is playing at " + this.tournament);
})
}
}
user.clickHandler();
Kết quả của đoạn mã trên như sau:
//Chú ý kết quả undefined
T. Woods is playing at undefined
P. Mickelson is playing at undefined
Như mong đợi của chúng ta, thì this (bôi đỏ) phải tham chiếu tới giá trị của đối tượng user, khi đó ta sẽ lấy được thông tin về tournament của đối tượng user. Tuy nhiên giá trị this bên trong một hàm closure thì không thể truy cập tới giá trị this của hàm bên ngoài (trong trường hợp này nếu không dùng strict mode thì this mang giá trị của biến toàn cục window).
Để sửa lỗi cho trường hợp này, các javascript developer thường giải quyết bằng việc gán giá trị của biến this vào một biến trung gian trước khi gọi closure:
var user = {
tournament:"The Masters",
data: [
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],
clickHandler: function () {
//Sử dụng con trỏ this ở đây thì OK, this đang mang giá trị tham chiếu tới đối tượng “user”
var self = this;
this.data.forEach (function (person) {
//Ta sẽ dùng biến self như một biến bình thường trong hàm closure
console.log (person.name + " is playing at " + self.tournament);
});
}
}
user.clickHandler();
Đoạn code trên trông có vẻ kì lạ đối với những người ít code bằng Javascript trước đây, tuy nhiên đây là một tình huống xảy ra khá thường xuyên trong Javascript.
3. Con trỏ this trong trường hợp gán hàm cho một biến khác
Trường hợp ta gán hàm cho một biến khác, cũng sẽ xảy ra tình trạng thay đổi context của hàm nếu được gọi. Ta xét ví dụ sau:
//Định nghĩa 1 đối tượng với phương thức hiển thị thuộc tính ra màn hình
var name = “Peter”;
var Hocsinh = {
name: “John”,
printName: function(){
console.log(this.name);
}
};
//Gán hàm Hocsinh.printName vào một biến
Var printHocsinhName = Hocsinh.printName;
//Gọi hàm printHocsinhName để hiển thị tên học sinh
printHocsinhName();
//------> Kết quả
Peter
Cũng tương tự như các trường hợp đã phân tích ở trên, context của hàm Hocsinh.printName đã bị thay đổi khi ta thực hiện gán hàm cho đối tượng khác. Để giữ nguyên được context là biến Hocsinh thì ta sẽ sửa lại code như sau:
//Gán hàm Hocsinh.printName vào một biến
Var printHocsinhName = Hocsinh.printName.bind(Hocsinh);
//Gọi hàm printHocsinhName để hiển thị tên học sinh
printHocsinhName();
//------> Kết quả
John
4. Con trỏ this trong hàm mượn (borrowing methods)
Hàm mượn (borrowing method) là một trong những khái niệm độc đáo của Javascript. Để hiểu rõ được nó có lẽ cần thêm một bài viết riêng, tuy nhiên mình sẽ đưa ra ví dụ về việc nó thay đổi context của con trỏ this như thế nào. Xét ví dụ sau:
// Chúng ta có 2 đối tượng, 1 đối tượng có hàm computeAvg() và 1 đối tượng thì không
// Chúng ta sẽ thực hiện mượn hàm này
var gameController = {
scores: [10, 15, 20],
avgScore: null,
players: [
{name: "Tommy", playerID: 987, age: 23},
{name: "Pau", playerID: 87, age: 33}
]
};
var appController = {
scores: [30, 40, 50],
avgScore: null,
computeAvg: function () {
var sumOfScores = this.scores.reduce (function (prev, cur, index, array) {
return prev + cur;
});
this.avgScore = sumOfScores / this.scores.length;
}
};
Ta muốn mượn hàm computeAvg() của đối tượng appController để tính điểm trung bình cho đối tượng gameController, vậy cần gọi hàm này như thế nào? Ở đây do hàm computeAvg() thuộc đối tượng appController, nếu muốn thực hiện tính điểm trung bình cho đối tượng gameController thì hàm này phải truy cập được tới các thuộc tính của đối tượng này. Do đó ta cần phải thay đổi context của hàm computeAvg() sang thành đối tượng gameController khi chạy, ta sẽ dùng hàm apply() trong JS để làm được điều này:
Như vậy ta vừa thực hiện dùng hàm mượn (borrowing method) và thay đổi context để thực hiện.
Tóm lại
Qua vài chia sẻ trên đây, hi vọng mọi người có thể hiểu rõ hơn về con trỏ this trong lập trình Javascript. Chúng ta có trong tay các công cụ là các hàm như apply(), bind(), call() để kiểm soát con trỏ this trong nhiều tình huống khác nhau.
Chúng ta thấy rằng, hầu hết mọi rắc rối xảy ra với con trỏ this là do dự thay đổi context của hàm khi được gọi (đã không còn là context ban đầu nơi bản thân hàm được khai báo), cụ thể là trong: hàm callback, closure, gọi từ một đối tượng khác hay khi trong thực thi hàm mượn (borrowing method). Do đó, quy tắc cốt lõi cần nhớ khi làm việc với con trỏ this là: luôn chú tới context của con trỏ this khi hàm được gọi, đảm bảo chúng ta đang sử dụng đúng context của hàm như ý muốn.
Typescript là gì? Hôm nay chúng ta sẽ cùng nhau phân tích cặn kẽ điểm mạnh và điểm yếu của typescript để có thể quyết định xem nên sử dụng nó như thế nào cho hiệu quả nhé!
Định nghĩa Typescript là gì?
TypeScript là gì? – Là một ngôn ngữ được Microsoft tặng free cho chúng ta, nền tảng của TypeScript ít nhiều cũng có sự liên quan đến JavaScript vì nó là một ngôn ngữ mã nguồn mở của JavaScript. Vai trò của TypeScript là dùng để thiết kế và xây dựng các dự án ứng dụng quy mô lớn mang tính chất phức tạp.
Khác với sự đơn giản của JavaScript, du TypeScript cũng đồng thời kế thừa nhiều định nghĩa, khái niệm của đa dạng các ngôn ngữ C#, Java,… nhưng TypeScript lại có yêu cầu cao về trật tự rõ ràng.
TypeScript được xem là một phiên bản nâng cao hơn của JavaScript vì nó được thiết kế thêm nhiều chức năng tiện lợi hơn, cải tiến hơn từ những điểm yếu của JavaScript như các lớp hướng đối tượng và Static Structural typing, bên cạnh đó TypeScript còn có thể hoạt động rộng rãi cho các ứng dụng của ngôn ngữ Angular2 và Nodejs.
Một trong những chức năng không thể lẫn vào đâu được của TypeScript đó là hỗ trợ ‘static typing’. Đồng nghĩa với việc bạn có thể khai báo kiểu cho biến, và trình biên dịch sẽ giảm được tỷ lệ gán sai kiểu của các giá trị. Nếu khai báo kiểu bị bỏ qua, chúng sẽ được tự động phát hiện từ code của bạn.
Ví dụ: Các biến, tham số của hàm hoặc giá trị trả lại có thể có các kiểu được định nghĩa khi khởi tạo:
var burger: string = 'Spaghetti', // String
calories: number = 400, // Numeric
tasty: boolean = true; // Boolean
// Alternatively, you can omit the type declaration:
// var pasta = 'Spaghetti';
// The function expects a string and an integer.
// It doesn't return anything so the type of the function itself is void.
function speak(food: string, energy: number): void {
console.log("Our " + food + " has " + energy + " calories.");
}
speak(pasta, calories);
Toàn bộ khai báo kiểu sẽ bị xóa trong trường hợp TypeScript biên dịch thành JavaScript thành công
// JavaScript code from the above TS example.
var burger = 'Spaghetti',
calories = 400,
tasty = true;
function speak(food, energy) {
console.log("Our " + food + " has " + energy + " calories.");
}
speak(Spaghetti, calories);
Biên dịch tsc sẽ báo lỗi khi chúng ta thao tác không hợp lệ. Ví dụ:
// The given type is boolean, the provided value is a string.
var tasty: boolean = "I haven't tasted it yet";
main.ts(1,5): error TS2322: Type 'string' is not assignable to type 'boolean'.
Hệ thống cũng sẽ báo lỗi nếu thao tác truyền sai tham số tới một hàm:
function speak(food: string, energy: number): void{
console.log("Our " + food + " has " + energy + " calories.");
}
// Arguments don't match the function parameters.
speak("Sea Food Spaghetti", "a ton of");
main.ts(5,30): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
Các kiểu dữ liệu được sử dụng phổ biến nhất:
Any – Một biến với kiểu này có thể có giá trị là một string, number hoặc bất kỳ kiểu nào.
String – Giống chức năng của string trong JavaScript, có thể được bao quanh bởi ‘dấu nháy đơn’ hoặc “dấu nháy kép”.
Number – Tất cả giá trị số trong hàm đều được biểu diễn bởi kiểu number, không có định nghĩa riêng cho số nguyên (interger), số thực (float) cũng như các kiểu khác.
Boolean – true hoặc false, sử dụng 0 và 1 sẽ gây ra lỗi biên dịch.
Arrays – Có 2 kiểu cú pháp: my_arr: number[]; hoặc my_arr: Array<number>.
Void – sử dụng khi hàm không trả lại bất kỳ giá trị nào.
Để xem danh sách tất cả các kiểu biến, đọc tài liệu hướng dẫn của TypeScript tại đây.
Interfaces
Chức năng chính của Interfaces là sử dụng để kiểm tra, xem một đối tượng có phù hợp với một cấu trúc nhất định hay không, trợ giúp trong giai đoạn giai đoạn phát triển.
Bằng cách định nghĩa một interface, ta có thể đặt tên trong trường hợp có sự kết hợp đặc biệt của các biến, đảm bảo rằng chúng luôn luôn đi cùng nhau.
Ví dụ:
// Here we define our Food interface, its properties, and their types.
interface Food {
name: string;
calories: number;
}
// We tell our function to expect an object that fulfills the Food interface.
// This way we know that the properties we need will always be available.
function speak(food: Food): void{
console.log("Our " + food.name + " has " + food.calories + " calories.");
}
// We define an object that has all of the properties the Food interface expects.
// Notice that types will be inferred automatically.
var ice_cream = {
name: "cookies",
calories: 250
}
speak();
Ngoài ra bạn nên biết rằng, thứ tự của các thuộc tính không quan trọng bằng việc chúng ta phải fill đủ số lượng các thuộc tính và đúng kiểu. Nếu một thuộc tính nào đó bị thiếu, hoặc sai kiểu, hoặc sai tên, trình biên dịch sẽ cảnh báo chúng ta.
interface Food {
name: string;
calories: number;
}
function speak(food: Food): void{
console.log("Our " + food.name + " has " + food.calories + " grams.");
}
// We've made a deliberate mistake and name is misspelled as nmae.
var cookies = {
nmae: "cookies",
calories: 250
}
speak(cookies);
main.ts(16,7): error TS2345: Argument of type '{ nmae: string; calories: number; }
is not assignable to parameter of type 'Food'.
Property 'name' is missing in type '{ nmae: string; calories: number; }'.
Classes
Trong các dự án, ứng dụng lớn, lập trình hướng đối tượng rất hay được các Dev sử dụng nhất là trong các ngôn ngữ như Java hoặc C#.
TypeScript cung cấp hệ thống class khá tương đồng với các ngôn ngữ này ví dụ như chức năng kế thừa, abstract classes, interface implementations, setter/getters, …
Từ phiên bản ECMAScript 2015 trở đi, classes được xem là một tính năng có sẵn trong JS và có thể không cần sử dụng TypeScript. Mặc dù 2 phiên bản này có nhiều chức năng tương tự nhau, nhưng chúng vẫn có điểm khác biệt, đó là TypeScript nghiêm ngặt hơn.
Ví dụ:
class Menu {
// Our properties:
// By default they are public, but can also be private or protected.
items: Array<string>; // The items in the menu, an array of strings.
pages: number; // How many pages will the menu be, a number.
// A straightforward constructor.
constructor(item_list: Array<string>, total_pages: number) {
// The this keyword is mandatory.
this.items = item_list;
this.pages = total_pages;
}
// Methods
list(): void {
console.log("Our special meal today is:");
for(var i=0; i<this.items.length; i++) {
console.log(this.items[i]);
}
}
}
// Create a new instance of the Menu class.
var sundayMenu = new Menu(["Banana cakes","waffles","Lemon juice"], 1);
// Call the list method.
sundayMenu.list();
Cú pháp này khá quen thuộc cho dân Java hoặc C#. Tương tự cho kế thừa:
class HappyMeal extends Menu {
// Properties are inherited
// A new constructor has to be defined.
constructor(item_list: Array<string>, total_pages: number) {
// In this case we want the exact same constructor as the parent class (Menu),
// To automatically copy it we can call super() - a reference to the parent's constructor.
super(item_list, total_pages);
}
// Just like the properties, methods are inherited from the parent.
// However, we want to override the list() function so we redefine it.
list(): void{
console.log("Our special menu for children:");
for(var i=0; i<this.items.length; i++) {
console.log(this.items[i]);
}
}
}
// Create a new instance of the HappyMeal class.
var menu_for_children = new HappyMeal(["French Fries","Coke","toy"], 1);
// This time the log message will begin with the special introduction.
menu_for_children.list();
Modules
Tính module hóa rất quan trọng khi bạn đang thực hiện những dự án lớn. Nó phân chia code thành nhiều thành phần nhỏ và còn có khả năng tái sử dụng giúp dự án của bạn dễ tổ chức và dễ hiểu hơn so với file có hàng ngàn dòng code.
TypeScript có chức năng exporting và importing các module, nhưng bản thân nó không thể xử lý thực sự việc liên kết giữa các file. Dùng require.js cho các ứng dụng client và CommonJS cho Node.js để cho phép modules TS dựa trên các thư viện của bên thứ ba.
Đặt trường hợp có 2 file: 1 file export một hàm, 1 file import, chúng ta sẽ gọi nó là:
Để có thể hoàn thành thao tác, cần download require.js và thêm nó trong một thẻ script – xem hướng dẫn typescript là gì của requirejs.org. Sau đó biên dịch 2 file .ts. Mộ tham số mở rộng cần được thêm vào để nói với TypeScript chúng ta đang xây dựng các module cho require.js (còn được gọi là AMD):
tsc --module amd *.ts
Generics
Chức năng của Generics là cho phép cùng một hàm có thể chấp nhận các tham số với nhiều kiểu khác nhau. Việc tạo ra các thành phần có thể tái sử dụng với generics tốt hơn sử dụng kiểu any, vì generics bảo tồn kiểu của các biến vào và ra của chúng.
Ví dụ: Generics trong ví dụ dưới đây đã nhận một tham số và trả lại một mảng chứa cùng tham số
// The <T> after the function name symbolizes that it's a generic function.
// When we call the function, every instance of T will be replaced with the actual provided type.
// Receives one argument of type T,
// Returns an array of type T.
function genericFunc<T>(argument: T): T[] {
var arrayOfT: T[] = []; // Create empty array of type T.
arrayOfT.push(argument); // Push, now arrayOfT = [argument].
return arrayOfT;
}
var arrayFromString = genericFunc<string>("beep");
console.log(arrayFromString[0]); // "beep"
console.log(typeof arrayFromString[0]) // String
var arrayFromNumber = genericFunc(42);
console.log(arrayFromNumber[0]); // 42
console.log(typeof arrayFromNumber[0]) // number
Lần đầu tiên gọi hàm chúng ta thiết lập kiểu thành string. Điều này không bắt buộc vì trình biên dịch có thể xem tham số được truyền và tự động quyết định kiểu nào phù hợp nhất, giống như lần gọi hàm thứ 2.
Mặc dù không bắt buộc, luôn luôn cung cấp kiểu được coi là cần thiết vì trình biên dịch có thể đoán sai kiểu trong các kịch bản phức tạp.
Tài liệu hướng dẫn của TypeScript là gì gồm một vài ví dụ cao cấp bao gồm generics classes, kết hợp chúng với interfaces, …ở typescriptlang.org.
TypeScript thật sự thuận tiện và hoàn toàn miễn phí
Đối với loại ngôn ngữ lập trình tĩnh như TypeScript, tất cả những số liệu, thông số của bạn sẽ dễ dàng được lấy hơn nhờ IDE và trình biên dịch.
TypeScript hỗ trợ quá trình tìm kiếm giúp bạn tiết kiệm thời gian kiểm tra lại code, không cần thông qua bất cứ một ai để có thể tìm thông tin dữ liệu, ngoài ra TypeScript làm giảm phần trăm va chạm lỗi trong thời gian vận hành.
Ngoài ra, đây cũng là một trong những phần mềm nổi trội được Microsoft hỗ trợ hoàn toàn miễn phí.
Ngôn ngữ TypeScript có thao tác khá đơn giản, tiết kiệm thời gian hơn nhưng lại đem đến kết quả tốt đến bất ngờ, nó khắc phục tình trạng xuất hiện lỗi và dễ đọc hơn.
Cụ thể là, đối với ngôn ngữ thông thường người dùng thường thao tác theo các bước như:
Restart lại hàm, tạo đối số, hoàn thành đoạn mã
Sau khi apply hết các đoạn mã, công cụ cần thiết thì cho vận hành
Trong quá trình vận hành nếu phát hiện lỗi thì sửa chữa lại.
Tái cấu trúc
Chắc chắn trong quá trình viết code, các lập trình viên sẽ thường xuyên mắc phải nhiều lỗi nhỏ và cần chỉnh sửa, việc sử dụng TypeScript sẽ giúp bước chỉnh sửa code trở nên dễ dàng hơn nhờ hiệu quả của lệnh Rename Symbol/Find All Occurrences.
Đối với các ngôn ngữ khác, khi muốn sửa chi tiết nào đó thì thường phải thay đổi luôn những tập tin khác nếu có liên quan hoặc sử dụng RegEx
Trong trường hợp người dùng TypeScript muốn nâng cấp hệ thống của mình (thêm hoặc xóa thuộc tính, đổi tên,…) thì TypeScript sẽ giúp bạn tái cấu trúc lại sao cho phù hợp với nhu cầu tìm kiếm của bạn mà không gây náo loạn trong hệ thống. Trong trường hợp code của bạn không match được bất cứ dữ liệu nào thì sẽ được báo đến bạn ngay để được xử lý ổn thỏa.
Giảm tỷ lệ mắc lỗi trong hệ thống
Nhờ vào việc cảnh báo lỗi ngay khi viết code, nên tỷ lệ mắc lỗi trong hệ thống khi sử dụng TypeScript khá thấp, TypeScript sẽ trả lại giá trị null hoặc gợi ý thay đổi chỉnh sửa. Mỗi lần chỉnh sửa sau khi được TypeScript báo lỗi thì phần trăm hệ thống hoạt động mà không mắc phải lỗi là rất cao, có thể dễ dàng thấy được TypeScript giúp người dùng tiết kiệm không ít thời gian để sửa lỗi.
Với quy trình kiểm tra và báo lỗi tự động ngay khi code, khi bạn đã chắc chắn rằng các biến dữ liệu của mình nằm ở đúng chỗ thì bạn không cần phải lo hệ thống không vận hành hoặc không cần phải kiểm tra lại nữa.
Điều này sẽ giúp bạn tiết kiệm thời gian, không đặt quá nhiều chú ý vào những thao tác đơn giản cho việc kiểm tra mà có thể tận dụng thời gian tối ưu hơn bằng cách kiểm tra chất lượng logic của hệ thống.
Việc hạn chế được các bước thử nghiệm sẽ giúp tiết kiệm được thời gian hơn, nâng cao hiệu quả công việc của các lập trình viên.
Hợp nhất mã đơn giản
Sau khi hoàn thiện được một đoạn code và cho chúng chạy thử nghiệm, có thể ngay trong môi trường đó mọi thứ đều hoạt động trơn tru, nhưng bạn có chắc được đoạn code đó cũng sẽ hoạt động tốt khi ở trong môi trường điều kiện khác?
Một trong những điểm mạnh của TypeScript là bạn có thể hợp nhất mã một cách đơn giản để có thể dễ dàng kiểm tra đánh giá đoạn mã bạn vừa mới cho ra đời kia bằng cách sử dụng Typedef – kiểm tra biên dịch.
Lại một lần nữa, TypeScript lại giúp người dùng tiết kiệm thời gian và công sức!
TypeScript sẽ không khuyến khích người dùng nhảy bước, thực hiện sai thao tác. TypeScript khuyến khích người dùng đưa ra quyết định về kiểu dữ liệu khi sử dụng ngôn ngữ kiểu tĩnh trước khi thực hiện thao tác, các bước tiếp theo. Chính vì những quy luật như thế sẽ giúp cho các lập trình viên tối ưu được quy trình làm việc hiệu quả hơn.
Nhược điểm của Typescript là gì?
Bất kỳ ngôn ngữ nào cũng có điểm yếu và hạn chế của nó, và TypeScript cũng vậy, điểm hạn chế của TypeScript là:
Bắt buộc dùng biên dịch
Để có thể vận hành một tệp TypeScript với đuôi .js trên nền tảng Node.js bạn bắt buộc phải dùng trình biên dịch để có thể sử dụng.
Bước thiết lập cồng kềnh
Trước khi có thể sử dụng được TypeScript, bạn cần đảm bảo rằng máy chủ Node.js, trình thử nghiệm và webpack đều có thể hoạt động với TypeScript, nếu không thì bạn sẽ không sử dụng được.
Bên cạnh đó, mỗi khi bạn apply thêm bất kỳ library nào như Redux, React và Styled-Component thì bạn cũng phải thêm Typedef vào.
Chỉ là phần ngôn ngữ mở rộng hỗ trợ
Sau cùng, chức năng của TypeScript cũng chỉ là để biên dịch về JavaScript, nó không phải là một ngôn ngữ có thể vận hành độc lập và nó cũng đồng thời không thể thay thế được vai trò của JavaScript. Chức năng của TypeScript bị giới hạn bởi chức năng của JavaScript, TypeScript chỉ là được nâng cấp từ điểm yếu của JavaScript.
Chỉ với mỗi TypeScript, người dùng không thể nào hoàn thiện được các công đoạn của dự án, công dụng của TypeScript chỉ thực sự nổi bật khi được kết hợp nhuần nhuyễn và tối ưu với các ngôn ngữ, nền tảng và tool khác.
TypeScript có thực sự là một mã nguồn mở?
Có nhiều luồng ý kiến cho rằng TypeScript là một mã nguồn mở, và đó cũng là một trong những lý do họ thích sử dụng TypeScript. Nhưng liệu đó có phải sự thật?
Đúng! TypeScript thực sự là một mã nguồn mở nhưng nó vẫn nằm dưới sự chi phối của Microsoft – công ty phần mềm nổi tiếng về các phiên bản phần mềm độc quyền.
Nhiều người dự đoán, TypeScript là một sản phẩm marketing của Microsoft dùng để thu hút người dùng về công năng và sự miễn phí. Tuy nhiên sau cùng, việc Microsoft có kéo dài việc miễn phí này hay không vẫn phụ thuộc rất nhiều vào Microsoft và người dùng hoàn toàn bị động trong chuyện này.
Cài đặt TypeScript
Cách dễ nhât để thiết lập TypeScript là thông qua trình quản lý NPM (Node.js).
Các bạn có thể dễ dàng thao tác và sử dụng thử các lệnh cơ bản, đơn giản sau đây dưới để có thể cài đặt TypeScript package toàn cục:
npm install -g typescriptjavascript:void(0)
Open bât kỳ cửa sổ terminal ở bất kỳ đâu và chạy lệnh tsc -v, nếu cài đặt thành công màn hình sẽ như thế này:
tsc -v
Version 1.8.10
Hướng dẫn biên dịch sang từ TypeScript sang JavaScript
TypeScript được viết trong các file .ts (hoặc .tsx cho JSX), nó không thể sử dụng trực tiếp trong trình duyệt và cần biên dịch thành JavaScript. Điều này có thể thực hiện với một số cách:
Sử dụng các task runner như Gulp
Trực tiếp trong Visual Studio hoặc các IDE và trình soạn thảo khác
Trong terminal sử dụng lệnh tsc
Đối với Newbie chúng nên bắt đầu từ cách dễ nhất:
Câu lệnh sau sẽ nhận một file TypeScipt là main.ts và chuyển nó thành JavaScipt main.js. Nếu main.js đã tồn tại nó sẽ bị ghi đè:
tsc main.ts
Trong cùng 1 thời điểm, chúng ta có thể biên dịch nhiều file bằng cách liệt kê chúng hoặc áp dụng các wildcard:
# Will result in separate .js files: main.js worker.js.
tsc main.ts worker.ts
# Compiles all .ts files in the current folder. Does NOT work recursively.
tsc *.ts
Chúng ta cũng có thể sử dụng tùy chọn –watch để tự động biên dịch một file TypeScript khi có thay đổi:
# Initializes a watcher process that will keep main.js up to date.
tsc main.ts --watch
Một file tsconfig.json chứa nhiều thiết lập đôi khi cũng được viết bởi các TypeScript giàu kinh nghiệm. Các file như thế rất tiện lợi khi làm việc trên các dự án lớn có nhiều file .ts, nó hỗ trợ tự động hóa một phần tiến trình.
Đối với những hệ thống nhỏ chỉ cần 1 Database thì chắc chẳng mấy ai quan tâm đến việc tạo ra ID cho bản ghi. Vì dùng auto increment trong MySQL là có thể làm được rồi, chẳng cần phải làm gì thêm.
Thế nhưng với dữ liệu càng ngày càng to ra thì hệ thống chỉ có 1 database duy nhất có thể sẽ không thể đáp ứng được. Bởi vì traffic đang tập trung hết vào database đó.
Để giải quyết bài toán đó thì người ta đã tách database ra thành nhiều database khác nhau, và mỗi database đó sẽ chứa 1 phần dữ liệu. Ví dụ db01 chứa thông tin user từ 1 đến 1000, db02 chứa thông tin user từ 1001 đến 2000 chẳng hạn. Và khi query sẽ tìm xem user thuộc database nào và thực hiện truy vấn.
Thế nhưng có vấn đề xảy ra ở đây là làm thế nào sinh ra ID cho user mà không bị trùng lặp giữa các database đó? Dùng auto increment mặc định của database có giải quyết được không? Làm thế nào để từ 2 ID có thể phán đoán cái nào được sinh ra trước, cái nào được sinh ra sau?
Vậy cùng đọc bài này xem các kĩ sư Instagram đã giải quyết bài toán này thế nào nhé.
Mục tiêu bài viết:
Hiểu thêm được 1 cơ chế sinh ID mới.
Có thể áp dụng vào các bài toán sharding data trong database.
Bối cảnh
Instagram là 1 trong những mạng xã hội chia sẻ ảnh nổi tiếng nhất cái hành tinh này.
Theo thống kê năm 2016 thì cứ mỗi giây sẽ có 915 photos, 1k post được tạo ra. Quá khủng khiếp phải không nào.
Khi dữ liệu tăng lên kinh khủng như thế thì 1 database sẽ không thể lưu trữ hết được dữ liệu, cùng với tốc độ truy vấn sẽ trở nên ì ạch và tốn nhiều dung lượng bộ nhớ.
Để đảm bảo tất cả dữ liệu quan trọng luôn được lưu trữ trên memory, và sẵn sàng trả về kết quả nhanh nhất cho người dùng thì Instagram bắt đầu thực hiện Sharding dữ liệu.
Ảnh bên dưới là 1 ví dụ về sharding trong database. Database sẽ được tách ra thành nhiều database khác nhau, mỗi database sẽ chứa 1 phần dữ liệu. Như ví dụ bên dưới là tách bảng user ra thành nhiều database, mỗi database sẽ chứa 1 phần dữ liệu của bảng user.
Người ta gọi mỗi database tách biệt này là ”Shard“.
Tuy nhiên tại thời điểm này có 1 bài toán được đặt ra. Làm thế nào có thể sinh ra ID duy nhất trên từng shard mà không sợ bị trùng lặp (Ví dụ như mỗi photo được upload vào trong hệ thống)? Cùng đi đọc tiếp phần tiếp theo nhé.
Yêu cầu về mặt chức năng
Trước khi đi vào giải quyết bài toán bên trên, thì cùng xem hệ thống Instagram yêu cầu những gì về ID của từng shard nhé.
ID được tạo ra phải được sắp xếp theo thời gian. Ví dụ như với 2 ID thì có thể phán đoán được ID nào tạo ra trước, ID nào tạo ra sau.
ID sẽ bao gồm 64 bits. (Vì sao lại cần 64 bits? Vì nó tương thích với các hệ thống như Redis …)
Thuật toán sinh ra ID phải đơn giản, dễ hiểu và đặc biệt không được làm thay đổi architecture server của Instagram.
1 số giải pháp generate ID
Hiện tại có rất nhiều giải pháp cho việc sinh ra ID unique. Cụ thể như:
Sử dụng auto increment trong database
Về chức năng này thì ai cũng biết rồi. Lúc tạo bảng chỉ cần khai báo auto increment là xong.
Ưu điểm:
Cách dùng đơn giản.
Nhược điểm:
Chỉ tập trung vào 1 database và không thể phân chia sang database khác được.
Không thể đảm bảo rằng việc sinh ID ở nhiều database là không bị trùng nhau.
Sử dụng UUID
Đây cũng là 1 cách khá hay để giải quyết bài toán. UUID là 1 chuẩn chung nhằm sinh ra chuỗi random không trùng nhau (xác suất gần như bằng 0). Ví dụ như: b875d561-20fd-498d-8452-5d5ffa879856.
Thế nhưng cùng xem nó có ưu điểm nhược điểm gì nhé.
Ưu điểm:
Cho dù chạy trên nhiều máy tính cùng thời điểm đi chăng nữa thì xác suất các string đó trùng nhau dường như gần bằng 0.
Nhược điểm:
Nó bao gồm 128 bits nên hơi to, không phù hợp với yêu cầu của hệ thống (là 64 bits)
Với 2 ID thì không thể phân biệt ID nào tạo trước, ID nào tạo sau.
Đây chính là 1 công cụ sinh ra ID random được phát triển bởi Twitter. Cái này sử dụng Apache Zookepper để phối hợp với các node để tạo ID 64 bit duy nhất.
Ưu điểm:
Snowflake ID có 64 bit
Có thể sử dụng time trong component đầu tiên của ID nên có thể sắp xếp được
Nhược điểm:
Phải đưa ZooKeeper, Snowflake vào trong kiến trúc của Instagram.
Giải pháp của Instagram
Những giải pháp trên đều không đáp ứng được yêu cầu của Instagram nên họ quyết định tự xây dựng cho mình 1 giải pháp riêng.
Họ sẽ dùng thuật toán đơn giản để sinh ra 1 chuỗi ID random duy nhất từ 1 số input đầu vào. Và từ chuỗi ID đó có thể decode ngược lại để lấy ra được input.
ID ở đây chính là ID của photo, ID của posts chẳng hạn.
Database họ sử dụng là PostgreSQL.
Cụ thể như sau.
ID có độ dài 64 bits, sẽ bao gồm những bộ phận sau:
41 bits để lưu thời gian (đơn vị milliseconds). Khoảng thời gian này sẽ được tính từ ngày 2011/01/01 00:00.
13 bits để lưu shard ID. (tối đa có thể tạo ra được 2^13 = 8192 shard)
10 bits để lưu auto-incrementing sequence, sau đó module 1024. (Vì sao lại là 1024 vì tối đa có 10 bit thôi, mà 2^10 = 1024). Điều đó có nghĩa là có thể tạo ra 1024 IDs trên 1 shard, trên millisecond.
Câu hỏi đặt ra là nếu tạo upload quá 1024 bức ảnh trong 1ms có được không?
Câu trả lời là không nhé. Vì lúc đó thằng thứ 1025 sinh ra ID sẽ bị trùng với thằng thứ 1. Với cả ID là khoá chính nên khi insert vào sẽ bị lỗi. Nên lúc đó chỉ cần try cach đoạn đó là ok.
Từ công thức trên ta có thể thấy ID được tạo ra bằng cách:
**ID = (Dịch trái time sang trái 23 bit) bitwise OR (dịch trái shardID 10 bit) bitwise OR (dịch trái seqID 0 bit) **
Để mình tổng hợp lại kiến thức về bitwise cho mọi người hiểu nhé:
Dịch trái, dịch phải nó cũng giống như chúng ta kéo cảnh cửa sang trái, sang phải thôi. Nếu dịch trái n bit tức là sẽ điền n số 0 vào sau số đó. Ví dụ như dịch trái số 7 (dạng nhị phân là 110) sang trái 5 bit, khi đó nó sẽ thành: 11000000
bitwise OR tức là thực hiện OR từng bit 1 của 2 số từ phải sang trái. Nếu 2 bit đều là 1 thì sẽ cho kết quả là 1, ngược lại sẽ cho kết quả là 0. Ví dụ như 7 (dạng nhị phân là 110) OR 8 (dạng nhị phân là 111) khi đó kết quả là: 110 OR 111 = 110.
Ví dụ:
Giả sử như người dùng có user_id là 5001, post bức ảnh lên instagram vào thời điểm 2019/05/19 00:00. Tại thời điểm đó sequence hiện tại của table đang là 9000.
Cách tính:
Do thời gian được tính từ ngày 2011/01/01 00:00 nên từ thời điểm đó đến ngày 2019/05/19 00:00 có time = 264384000000 ms.
=> ID = 264384000000 << 23 (dịch sang trái 23 bit)
Do user_id = 5001, và instagram chỉ có 2000 shard. Nên shardId = 5001 % 2000 = 1001
=> ID |= 1001 << 10
sequence hiện tại của table đang là 9000, khi đó nextsequenceid là 9001. vậy seqId = 9001 % 1024 = 809
=> ID |= (809) << 0
Sau khi tính chúng ta ra kết quả ID = 2217813737473025832.
Vậy làm thế nào mà từ số 2217813737473025832 chúng ta có thể decode ngược lại ra time là 264384000000, shardId là 1001, seqId là 809?
Đây có lẽ là phần mình thấy hay nhất. Chúng ta cùng xem tiếp nhé:
Time sẽ được tính bằng cách dịch sang phải ID 23 bit, sau đó thực hiện AND với 1 số 41 bit toàn số 1. Cái số 41 bit toàn số 1 này chuyển sang dạng hex sẽ là 0x1FFFFFFFFFF.
ShardID và seqId cũng được decode tương tự.
Đây là 1 example về encode và decode mình đã chuẩn bị được. Dành cho ai muốn test:
Sau khi lấy được shardId là chúng ta có thể dễ dàng truy cập vào từng shard để lấy ra record dựa vào ID (photoid, postid …) được rồi. Mà chẳng phải tốn công đi join, select làm gì cho mệt cả.
Hơn nữa nó thao tác giữa các bit nên cứ gọi là nhanh đừng hỏi.
Và đây là ví dụ về PL/PGSQL trong PostgreSQL:
CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $
DECLARE
our_epoch bigint := 1293843600000;
seq_id bigint;
now_millis bigint;
shard_id int := 5;
BEGIN
SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id;
SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
result := (now_millis - our_epoch) << 23;
result := result | (shard_id <<10);
result := result | (seq_id);
END;
$ LANGUAGE PLPGSQL;
Khi tạo bảng sẽ làm như sau:
CREATE TABLE insta5.our_table (
"id" bigint NOT NULL DEFAULT insta5.next_id(),
...rest of table schema...
)
Kết luận
Từ 1 con số mà có thể dễ dàng decode nó ra để lấy các thông tin bên trong nó. Đoạn này mình thấy thật vi diệu.
Đúng là mấy anh kĩ sư có kinh nghiệm về design mấy bo mạch, chip các thứ áp dụng vào thấy nó khác bọt thật.
Hi vọng qua bài này sẽ giúp các bạn có 1 kiến thức mới về việc sinh ra ID random, và decode ngược lại.
Trong những năm vừa qua tôi đã thực hiện hơn 100 cuộc phỏng vấn về kỹ sư phần mềm – software engineer. Nếu các bạn thắc mắc cách mà nhà phỏng vấn hiểu ứng viên, làm thế nào họ đánh giá ứng viên có phù hợp với vị trí công việc hay không, hãy đọc hết bài viết này. Mặc dù mỗi công ty có một quy trình của riêng họ, nhưng vẫn có một số bẫy rất quen thuộc mà ứng viên thường không vượt qua được, và sau đây là lời khuyên chân thành để tránh được chúng.
Colin R. Davis từng nói “Con đường dẫn đến thành công và thất bại là gần như nhau”. Không có một tiêu chuẩn độc nhất nào để miêu tả một SE – software engineer giỏi cả. Nó còn phụ thuộc vào nhu cầu vị trí ấy và mức độ đa dạng sản phẩm và tuổi đời của một công ty. Một công ty startup dĩ nhiên thì cần marketing trong thời gian ngắn, trong khi một công ty lão làng đã có lượng khách hàng lớn và ổn định sẽ đối mặt với những thách thức khác về quy mô và cấu trúc công ty. Từ đó, xây dựng product với sự hiểu biết về doanh nghiệp sẽ khác với chuyện giải quyết những challenge công nghệ phức tạp.
Một engineer cầu toàn đến từng chi tiết sẽ khác với engineer phải thực hiện công việc trong thời gian gấp rút. Vì thế bài toán ở đây là phải hiểu được công ty nào đang tìm kiếm điều gì và hướng hành động và cách giao tiếp phù hợp vào “khung” ấy. Hạn chế những CV “one-fits all” mà hãy ứng dụng với từng trường hợp thực tế. Ngoài ra bạn cũng nên định hình “giỏi” là như thế nào trong tình cảnh của công ty và chứng minh kiến thức, kinh nghiệm và thái độ của mình phù hợp thế nào với hoàn cảnh ấy.
Hãy làm homework
Benjamin Franklin nói rằng “Thất bại trong khâu chuẩn bị cũng có nghĩa là chuẩn bị để thất bại”
Đi phỏng vấn mà không biết chút gì về công ty cũng như đi hẹn hò mà chỉ toàn nói về bản thân, cũng không hẳn là sẽ không có buổi hẹn tiếp theo mà chỉ là ấn tượng đầu chưa được tốt lắm. Hãy bỏ một chút công sức tìm hiểu về doanh nghiệp, mục tiêu, sứ mệnh, chiến lược và kết quả. Tôi thì không đánh rớt ứng viên chưa tìm hiểu về công ty, nhưng đó là dấu hiệu cho động lực của người nhân viên ấy. Ngoài những mục đích kinh doanh, bạn cũng nên check qua techblog của công ty (nếu có) và tìm hiểu chút về team tech. Không nhiều ứng viên thể hiện sự quan tâm đến doanh nghiệp, nên nếu bạn làm những chuyện ấy thì bạn sẽ rất nổi bật.
Tư duy phản biện
“Trí óc có học thức sẽ có khả năng suy nghĩ phản biện, chứ không dễ dàng chấp nhận và hài lòng với bất cứ điều gì” – Aristotle
Trong suốt sự nghiệp của mình, tôi đã gặp nhiều chuyên gia công nghệ “ngoại hạng” và họ đều là những tuýp người rất khác nhau. Dù vậy thì ở họ có ít nhất một điểm chung như: họ sẽ là những người thách thức tình trạng hiện tại để cải tiến quy trình và công nghệ.
Một số người khi được yêu cầu đưa ra câu hỏi cho người phỏng vấn, thì không biết phải hỏi cái gì. Trốn tránh việc đặt câu hỏi là chính bạn đã lãng phí cơ hội. Hãy chớp lấy thời cơ để hỏi về những quyết định technical của công ty và những thách thức mà họ đang đối mặt, từ đó trao đổi về ưu/khuyết điểm của từng loại công nghệ.
Họ có đang chuyển sang cấu trúc event-driven microservice không? Họ đang dùng message broker gì? Tại sao không dùng Kafka thay vì RabbitMQ?
Họ đang dùng công nghệ database gì? Usecase là gì?
Liệu rằng ElasticSearch có là sự thay thế hoàn hảo cho SQL trong use case đó không?
Vân vân. Đặt câu hỏi về technical decision sẽ chứng minh không những bạn hiểu về những thứ công nghệ ấy, có thể tranh luận khi nào nên sử dụng mà còn show được mức độ bạn quan tâm đến việc cải thiện những công nghệ được công ty áp dụng.
Câu hỏi phỏng vấn về thách thức kỹ thuật
“No amount of experimentation can ever prove me right; a single experiment can prove me wrong.” | – Albert Einstein
Với một số quy trình, có thể bạn sẽ phải đối mặt với những vấn đề về thuật toán hay cấu trúc dữ liệu, và sẽ không thể nào tránh chúng được đâu trừ việc nắm chắc những kiến thức nền tảng về khoa học máy tính. Những cuốn sách bạn có thể tham khảo: Cracking the coding interview, Leetcode, or Pramp.
Hãy nhớ giải thích cách làm của bạn thành tiếng. Bài toán này có khi lại là lời giải của bài toán khác, nên nếu bạn không giải được bài toán này cũng không sao, miễn sao bạn có thể vượt qua được hầu hết bài toán. Ngoài ra người phỏng vấn còn có thể cho bạn một số lời khuyên nếu bạn trục trặc trong quá trình xử lý, và điều đó cũng không “trừ điểm” bạn đâu. Vì vậy đừng ngại trình bày những khó khăn cũng như hướng giải quyết để người phỏng vấn có thể nắm được mức độ hiểu biết của bạn.
Đừng nản chí nếu phỏng vấn thất bại
“Thành công là đứng lên nhiều hơn một lần so với thất bại” Oliver Goldsmith
Có lần tôi phỏng vấn một ứng viên khá run và không tự tin lắm trong buổi phỏng vấn. Tuy nhiên anh ấy làm khá tốt nên vẫn được nhận. Đến ngày nhận việc, anh ấy đột nhiên rất tự tin, có thể dẫn các cuộc thảo luận discussion và hướng dẫn team về vấn đề kỹ thuật. Tôi hỏi ảnh tại sao có sự khác biệt về phong độ như thế, thì ảnh giải thích rằng trong khoảng thời gian trước đó ảnh đã trải qua một chuỗi những buổi phỏng vấn thất bại, và ảnh không thể đối mặt với chuyện ấy. Tuy rằng từ chối là một phần của quy trình nhưng bạn lại không thể chấp nhận nó.
Đơn giản mà nói thì không thể đánh giá chính xác một kỹ sư chỉ trong vài giờ phỏng vấn. Mỗi quy trình chỉ chọn người phù hợp với công ty và phát triển họ sau đó theo cách tốt nhất. Những gì bạn đang làm rất tốt có thể không phải thứ công ty đang tìm kiếm.
Nếu tôi rớt phỏng vấn mà lại đọc những dòng thế này thì tôi cũng thấy nhảm nhí. Tôi luôn cố gắng trở thành chiến binh. Tuy nhiên, có thời điểm chiến binh này thua quá nhiều trận đấu, một chiến binh mà luôn thua cuộc thì không khác gì một cái bao cát boxing. Tuy vậy, hãy tìm lấy sức mạnh nội tại để kéo bản thân ra khỏi những gì làm bạn nản chí. Để đứng lên, hãy chiến đấu thêm một lần để thất bại không còn là điểm đến tiếp theo.
Phỏng vấn về đam mê
“Công việc của bạn sẽ lấp đầy phần lớn cuộc sống của bạn, và cách duy nhất để hài lòng tuyệt đối là làm những gì bạn tin đó là một công việc tuyệt vời. Vậy nên hãy tiếp tục tìm kiếm cho đến khi bạn thấy nó. Đừng dừng lại. Sẽ đến lúc con tim sẽ chỉ lối cho bạn. Giống như một mối quan hệ, hãy quyết tâm đến cùng, đừng bao giờ bỏ cuộc.” – Steve Jobs
Khi làm chuyện mà bạn đam mê, bạn thậm chí còn không biết cả cuộc đời đã trôi qua. Đó là ý nghĩa bất biến của lập trình, niềm đam mê của tôi và chính bạn. Niềm đam mê chính là nguyên liệu bí mật để thành công,
Đôi lúc bạn giỏi hơn ở những mảng bạn không thật sự thích, nhưng chính niềm đam mê sẽ thúc đẩy bạn. Và để đánh giá sự yêu nghề của một kỹ sư thì không hề dễ dàng. Tuy vậy, khi tôi hỏi bạn về side project hay project đỉnh nhất bạn từng làm, có thể bạn sẽ kể về chúng cả buổi. Không cần biết đó là một platform có hàng triệu người dùng hay một side project chưa từng hoạt động, một lập trình viên đam mê sẽ mô tả rất nhiệt tình về từng cái pattern, từng challenge phải vượt qua, thậm chí những lần hack chưa được. Ứng viên, hay người phỏng vấn, cũng chỉ là những techguy với những dòng code đầy nhiệt huyết.
Người phỏng vấn có thể nhận ra nhiệt huyết thông qua ánh mắt hay body language của ứng viên. Hãy kể về dự án khiến bạn khó quên nhất và đó chính là điểm khác biệt giữa bài phỏng vấn trung bình với buổi phỏng vấn xuất sắc.
Tóm lại
Phần căng thẳng nhất đối với ứng viên là khi rất cần công việc và phải chứng minh mình đủ giỏi. Người phỏng vấn cũng không hề dễ dàng, họ phải có những lý do xác đáng để chọn hay loại ứng viên. Hy vọng bài viết này sẽ cho bạn cái nhìn rõ hơn về suy nghĩ của một người phỏng vấn, từ đó giúp bạn nắm bắt cơ hội việc làm mà bạn đang tìm kiếm.
Cùng chung một quỹ thời gian là 15 phút, tại sao bạn chỉ làm được một việc trong khi nhiều người lại làm được nhiều việc khác nhau. Do hiệu suất về công việc nhiều hơn, họ có nhiều cơ hội tích lũy các kinh nghiệm. Vì thế, thành công đến nhanh với họ là tất yếu. Cùng TopDev phân tích về những lý do thực tế giúp họ đạt được những thành công.
Bài toán nhận diện mức độ: Quan trọng – Khẩn cấp
Là một người thông minh, bạn cần nhận diện, đánh giá được mức độ ưu tiên. Tức đâu là công việc quan trọng, đâu là công việc khẩn cấp cần phải thực hiện.
80% kết quả của bạn đến từ 20% công việc. Vì vậy, bạn hãy ưu tiên lựa chọn và thực hiện các công việc thật sự quan trọng. Hãy quan tâm đến những công việc có thể mang lại nhiều giá trị cho bản thân.
Tât nhiên, bạn phải dành thời gian để kiểm tra mức độ hiệu quả ban đầu. Đồng thời, cần tập trung vào những sai sót có thể phát sinh để kịp thời đưa ra các giải pháp phù hợp nhất.
Khai thác mức độ quan trọng – khẩn cấp trong công việc còn giúp bạn sắp xếp, nắm bắt tính tổng thể trong quá trình giải quyết công việc. Đôi khi sẽ có những công việc quan trọng nhưng chưa khẩn cấp. Và ngược lại, có những công việc lại rất khẩn cấp nhưng chưa thật sự quan trọng. Việc tự xem xét về một công việc nào đó rất khó khăn, bởi bạn không phải chuyên gia. Tuy nhiên, hãy rèn luyện kỹ năng này từng ngày để gia tăng được năng lực cảm thụ, đánh giá được tiềm năng các giá trị, hiệu quả mà một công việc nào đó có thể mang lại.
Trao quyền – Bản lĩnh của người thành công
Việc trao quyền cho nhân viên không còn là vấn đề xa lạ. Dựa vào sự đánh giá của bạn về từng cá nhân, bạn sẽ cho họ cơ hội đảm nhận; chịu trách nhiệm một phần công việc nào đó. Tuy nhiên, khi không có nhân viên, bạn có thể trao quyền cho các cộng sự, các đối tác đáng tin cậy.
Là một lãnh đạo, bạn đừng để cái tôi quá cao. Nếu ví các dự án bạn thực hiện là các mảnh ghép rời rạc, thì bạn phải là người kết nối chúng. Khi sự trao quyền được thiêt lập, bạn phải sẵn sàng đối mặt với những thách thức có thể xảy ra. Đồng thời, đó cũng là cách để bạn hoàn thiện hơn về bức tranh tổng thể.
Quan trọng nhất là một khi đã chấp nhận trao quyền tức là chấp nhận rủi ro. Ván cờ đã diễn ra và bạn không thể dừng lại khi thấy những quân bài dần trở nên xấu đi. Hãy lưu tâm: Khi sở hữu các quân bài xấu, bạn vẫn phải là một người chơi giỏi.
Bạn đừng đặt nặng vấn đề về sự hoàn hảo khi trao quyền. Điều quan trọng chính là bạn sẽ tìm kiếm và thiết lập các mối quan tốt đẹp. Đồng thời, đó cũng là cách bạn tạo ra sự thúc đẩy cho các nhân viên mình.
Hãy thể hiện thông minh và có chừng mực
Bạn có thể làm ít, nhưng nó phải chất lượng. Làm ít nhưng vẫn đủ khối lượng công việc. Chính điều này tạo ra sự khác biệt. Và sự khác biệt luôn dẫn đến sự đố kỵ, ganh đua. Đồng nghiệp họ sẽ nghĩ bạn là luôn giả vờ, họ hoài nghi về khả năng thật sự của bạn. Bạn không nên tạo ra cho họ những lối suy nghĩ như vậy.
Thế nên, điều bạn cần quan tâm chính là hãy thể hiện bản thân một cách thông minh và có chừng mực. Đây cũng được đánh giá là một chiến lược giúp bạn chạm đến sự thăng tiến trong sự nghiệp.
Bạn cần giao tiếp với đồng nghiệp một cách cởi mở, học hỏi để gia tăng các hệ giá trị của bản thân về niềm tin. Hãy ghi nhớ, đừng tỏ vẻ mình là một người quá sành sỏi về cả chuyên môn lẫn cách sống. Đó được xem là một biểu hiện tiêu cực. Hãy đi từ từ, chậm mà chắc, cho họ có đủ thời gian nhìn nhận được thực lực của bạn. Đó sẽ là lúc thích hợp để bạn tăng tốc trên cuộc đua nghề nghiệp
Sở hữu tầm nhìn nhà lãnh đạo
Có những cá nhân chỉ làm tốt vai trò của mình và cái họ thiếu chính sự bức phá. Đây cũng lý do cản trở sự thăng tiến của họ. Họ dậm chân không phải không đủ giỏi mà do họ chưa thật sự có cái nhìn xa hơn.
Có lẽ, tiền và những áp lực trước mắt khiến họ chỉ tập trung vào giai đoạn hiện tại. Họ nhận lương cuối tháng, ít giao thiệp với mọi người. Họ lại thiếu đi các mối quan hệ. Chúng ta sẽ không có ý kiến vì thực tế, đây không phải là sự lựa chọn tồi. Chỉ là họ hoàn toàn có thể thành công hơn với một sự lựa chọn khác.
Ngược lại, nếu bạn xem mỗi ngày đi làm là mỗi bước trưởng thành hơn, có ý nghĩa lớn đối với sự nghiệp, bạn sẽ có động lực hơn. Chính lối suy nghĩ, cách nhìn nhận tích cực giúp bạn vạch ra những hướng đi cụ thể. Để mỗi chăng đường bạn đi, bạn biết mình cần phải làm gì, làm như thế nào, làm chúng với ai,… Khi có tầm nhìn tốt, bạn sẽ phấn đấu để hoàn thiện để mỗi ngày trôi qua, bạn đều là một phiên bản tốt hơn của chính mình.
Lời kết
Thành công là đỉnh cao ai cũng muốn chạm đến. Và tất nhiên, để đạt được nó là cả một sự nỗ lực, đôi khi bạn còn phải đánh đổi nhiều thứ. Quan trọng nhất vẫn nằm ở chính bạn. Bạn cần áp dụng các bí quyết đồng thời phối hợp các kỹ năng để có cho mình những định hướng thật sự phù hợp. TopDev hi vọng các bạn sẽ có những kế hoạch đầu tư phát triển bản thân đề con đường vươn đến thành công không còn xa nữa.
FreeCodeCamp là gì? – Trong ngành IT chúng mình, tự học cũng là một phần nhiệm vụ của lập trình viên vì:
Để làm mới những skill của bản thân, để theo kịp thời đại, không bị thụt lùi so với thế giới, chúng ta phải tự học.
Đôi khi vì yêu cầu của dự án, vì nhu cầu tìm việc chúng ta phải học và tìm hiểu những ngôn ngữ/công nghệ mới.
Lập trình là một lộ trình “tự mài dũa” liên tục, và các nền tảng cho phép lập trình viên luyện tập code hàng ngày – miễn phí – dễ sử dụng là điều cần thiết cho cộng đồng IT hiện tại. Và đương nhiên nói đến “luyện tập” và “luyện hàng ngày” thì không thể không nói đến freeCodeCamp, nền tảng miễn phí cung cấp chứng chỉ lập trình phi lợi nhuận hàng đầu cho lập trình viên. Đối với các bạn lập trình viên Việt Nam mới vào nghề chắc chắn không thể bỏ qua và nên dành một ít thời gian tìm hiểu và cân nhắc nếu phù hợp với mình.
freeCodeCamp là gì?
freeCodeCamp là một “tượng đài” với dân lập trình và người mê code nói chung, là “học viện code trực tuyến” miễn phí nổi tiếng nhất trong cộng đồng developer nhiều năm qua. Tuy nhiên, không ít bạn trẻ Việt Nam mới vào nghề có thể chưa hiểu rõ về nó cũng như cần một guideline hướng dẫn cụ thể hơn để tận dụng triệt để nền tảng này cho mục tiêu lập trình dài hạn của mình.
freeCodeCamp chính thức gia trình làng giới code vào năm 2014, với mục tiêu của họ là “giúp mọi người đều biết viết code” hoàn toàn miễn phí. Cách thức để phục vụ cho mục tiêu này đó là thông qua các bài giảng theo chương trình học cụ thể, video hướng dẫn, article bài blog và các nhóm cùng học tập trên khắp thế giới.
Có rất nhiều chứng chỉ học tập trên freeCodeCamp offer đa dạng các chương trình học tập khác nhau – tình từ thời điểm năm 2014 đã có đến 40,000 “developer” tốt nghiệp từ nền tảng. Và bộ phận không nhỏ đã được recruit vào các công ty “tech khủng” nhất trên thế giới.
freeCodeCamp là một cộng đồng chứa những mã nguồn mở bởi những con người bận rộn – những người học cách viết code và xây dựng các dự án cho các tổ chức phi lợi nhuận. Kênh youtube của họ đăng tải các video hướng dẫn dưới dạng một khóa học trực tuyến.
Kênh có nhiều gia sư khác nhau dạy đa dạng các công nghệ hiện nay. Nếu bạn đang muốn học phát triển Android hoặc Ionic, bạn cũng có thể tham khảo ở kênh này.Kênh của họ còn có một chương trình âm nhạc có thể giúp bạn thư giãn trong khi code. Bạn có thể xem qua kênh freeCodeCamp tại đây.
Forum của freeCodeCamp hỗ trợ cộng đồng, như “Quora của giới code” vậy. Khi học mà gặp phải vấn đề hoặc bất kì thắc mắc về chương trình bạn hoàn toàn có thể lên forum gửi thông tin.
freeCodeCamp mang tính cộng đồng cao, nên phần nhiều các lập trình viên hoạt động tạo profile để trau dồi kỹ năng qua việc luyện tập và support các coder khác tại trên forum. Ở giao diện chính của người dùng, freeCodeCamp có mục cho người dùng setting, sign out, ảnh đại diện người dùng trên freeCodeCamp và bên dưới là các tài khoản social như GitHub hay LinkedIn.
Bên dưới cùng sẽ có điểm của bạn hiện tại, các link dẫn tới Certification, lịch làm việc gần đây của bạn trên freeCodeCamp (đo bằng cách hôm đó có ghi điểm nào hay không), số ngày liên tiếp dài nhất, số ngày liên tiếp hiện tại và bên dưới cùng là các thử thách đã vượt qua.
freeCodeCamp hiện offer đến cộng đồng 6 chứng chỉ lập trình quan trọng và giúp bạn đi từ beginner lên fullstack.
Mỗi chứng chỉ cần 300 giờ học, trung bình (chăm chỉ) mỗi ngày học 3 tiếng thì có thể hoàn thành 1 chứng chỉ trong 3 tháng. Một số người có thể mất nhiều thời gian hơn. Các chứng chỉ này hoàn toàn do bạn tự thực hiện, vì vậy, bạn có thể mất bao lâu tùy ý.
Tất cả các khóa học bao gồm một bộ các bài học phụ hỗ trợ và chi tiết. Mỗi bài học dạy cho bạn một khái niệm duy nhất. Sau đó, bạn phải hoàn thành một thử thách ngắn. Mỗi khóa học sẽ kết thúc sau 5 dự án và hiển thị những gì bạn đã học được.
Bạn có thể tham gia tất cả các khóa học theo bất kỳ thứ tự nào. Nhưng hiện tại chúng đã được sắp xếp một cách khá khoa học bạn hoàn toàn có thể follow. freeCodeCamp sẽ đặc biệt dạy cho sinh viên IT mới các kỹ năng quan trọng đối với một software developer và các khóa học tập trung phát triển web chuyên sâu.
Hiện freeCodeCamp offer 6 chứng chỉ basic “hot nhất” bạn có thể follow bao gồm:
Responsive Web Design: Khóa học này đi từ những step cơ bản nhất như HTML, CSS cùng các bài học về thiết kế ứng dụng và thành phần cho CSS flexbox và grid. Đây là giáo trình đầy đủ nhất, cho các bạn kiến thức cơ bản về HTML, CSS và javascript. Hoàn thành nó bạn sẽ có chứng chỉ Front-end Developers
Thuật toán JavaScript và Data Structures (Cấu trúc dữ liệu): Khóa học sẽ dạy về cả JavaScript và lập trình nói chung. Ngoài ra sẽ cover cả hai định nghĩa căn bản trong lập trình như debug hoặc object-oriented và lập trình hàm (functional programming) song song với các bài về JavaScript như ES6 và Thuật toán JavaScript.
Front End Libraries: Khoá này sẽ dạy cho bạn các kĩ thuật và công nghệ front-end mới nhất gồm jQuery, React, Redux, và Bootstrap.
Data Visualization: Một khoá học tập trung về visualize dữ liệu, một trong những kỹ năng rất quan trọng nhất nếu bạn muốn trở thành data scientist và data analyst, qua các skill như D3, JSON APIs, và Ajax. Hoàn thành xong bạn sẽ có chứng chỉ Data Visualization tương ứng.
APIs và Microservices: Khoá chuyên về API và công nghệ mới như Npm, Node, Express, MongoDB, và Mongoose.
Information Security (Bảo mật thông tin) và Quality Assurance: Một khóa học trau dồi các kỹ năng hiện được săn đón nhất trên thị trường, gồm Helmet JS cho security testing và Chai cho QA testing.
Mỗi chứng chỉ yêu cầu 5 project bắt buộc, và các câu hỏi bài tập là không bắt buộc. Nếu hoàn thành đầy đủ lộ trình 6 chứng chỉ trên sẽ được chứng chỉ Full Stack – một điểm sáng phân biệt freeCodeCamp với các nền tảng học code khác vì họ đã định hướng rõ lộ trình để cả newbie hoàn toàn có thể theo học và định hướng.
Bên cạnh đó là còn có một khoá Technical interview để trang bị cần thiết cho bạn khi đi phỏng vấn xin việc.
Lưu ý rằng đây không phải là 6 khoá học duy nhất trên freeCodeCamp. Trên kênh youtube của freeCodeCamp bạn sẽ nhận được rất nhiều source free và tut hướng dẫn nhiều chủ đề khác nhau như lập trình, bao gồm cả ngôn ngữ đang hot nhất hiện nay – Python và Machine Learning.
Style giảng dạy của nền tảng rất trực tiếp qua thiết kế rõ ràng, giống như một khóa học đại học. Các bài học rõ ràng dễ nhìn như thiết kế của trang web. Bài giảng được thể hiện hiện chủ yếu qua các ví dụ thực tế để bạn dễ học – nhớ lâu hơn.
Chính sự đơn giản này cũng mang lại một mặt bất lợi cho một số level nhất định. Có những bài học đơn giản sẽ rất phù hợp cho level các bạn mới học – mới vào nghề. Và các bài học sau sẽ mở rộng hơn tuỳ thuộc vào nội dung. Tuy nhiên, có nhiều cách để sử dụng code nên bài học có thể sẽ hơi chậm với một số bạn.
Nhưng đây là vấn đề chung đối với hầu hết các khóa học và chương trình đào tạo coding online. Nói chung, cách tốt nhất để học viết code là học qua kinh nghiệm thực hành. Và freeCodeCamp cung cấp cho các bạn nền tảng mở và MIỄN PHÍ để làm chuyện này. Cứ mỗi cuối bài học sẽ có một project. Và chương trình học sẽ chú trọng nâng cao các kỹ năng một lập trình viên giỏi cần có.
Giao diện sử dụng
Thoạt nhìn giao diện của freeCodeCamp rõ ràng đến mức nhìn như một trang web thuở mới có Internet. Nhưng thực tế bên trong là một số thiết kế rất thông minh. Ít hình ảnh gây rối mắt và không có quảng cáo. Bố cục của mỗi trang rất đơn giản, chỉ có người học – trang học và code thôi.
Chính vậy mà freeCodeCamp cung cấp được một trải nghiệm học tập tập trung hơn, hiển thị lộ trình tiến bộ rõ ràng và là một điểm bắt đầu cụ thể cho các bạn mới vào ngành. Khi bắt đầu các bài học, bạn không cần phải quay lại danh sách chính, vì mỗi bài học sẽ tự sang bài tiếp theo khi hoàn thành.
Khi bắt đầu vào bài học, giao diện sẽ hiển thị chia thành 3 lane (cột). Ví dụ như bài HTML dưới đây, trang sẽ tách làm 3 cột từ trái qua: cột “bài giảng” => cột “user code” => cột “Ví dụ” hiển thị kết quả. Với thiết kế này hiện đang được xem là dễ sử dụng nhất với cho tất cả các trình độ.
Đây lại là một cộng đồng phi lợi nhuận nên bạn học hoàn toàn miễn phí
Các chứng chỉ từ freeCodeCamp khá là được quan tâm từ các doanh nghiệp khi tuyển dụng.
Riêng với thị trường Việt Nam thì vẫn chưa nhiều, tuy nhiên với các công ty Global – công ty IT mới sẽ rất coi trọng nếu như Portfolio / Linkedin của bạn có Certificate từ freeCodeCamp.
Bạn sẽ có trợ giúp từ chatroom 24/7 từ khắp nơi trên thế giới – như “Quora của giới code”
Với các bạn Lập trình viên thì thật sự không quá nhiều lý do để từ chối lên freeCodeCamp vì:
Nó FREE.
Có lộ trình sẵn cụ thể, dành ra 1 khoảng thời gian mỗi ngày để học liền tay
Học được nhiều ngôn ngữ code và tự trau dồi trở thành một lập trình viên full-stack thành thạo cả frontend và backend
Được nhúng tay vào các project real-life
Nhận certificate chứng nhận – làm đẹp “Giấy bán thân” CV & Portfolio
Kết nối với cộng đồng các coder khắp nơi
Nhược điểm
Nếu có những điểm để các bạn sinh viên từ chối không đụng đến freeCodeCamp thì:
Phần đông mọi người khá lười và chỉ lấy chứng chỉ cơ bản như front end – vừa đủ cho mình.
Việc này không sai, mỗi bạn sẽ có một định hướng và kế hoạch riêng cho mình để trang bị, tuy nhiên với các bạn chưa có định hướng hoặc căn bản là lười thì không tốt.
Ngay cả khi mang chứng chỉ thì bạn vẫn cần đi thực tập hay tham gia các dự án phi lợi nhuận về code
Nói đi cũng phải nói lại, riêng với đặc thù các công ty IT tại Việt Nam sẽ require các bạn nhiều hơn các tấm Certs, mặt bằng chung ai đã tìm việc đều sẽ nắm chuyện này. Nên freeCodeCamp có tác dụng bổ trợ, như một lớp học thêm các bạn trang bị các nhiều vũ khí thì chinh chiến càng có nhiều cơ hội hơn thôi!
Kết luận: Liệu freeCodeCamp có đáng thử không?
Đây là nền tảng DIY “Do It Yourself” hơn là một bootcamp theo mô hình thông thường. Mô hình ở đây của freeCodeCamp chỉ cung cấp lộ trình, bài học giáo án cụ thể và còn đặt lịch học schedule cụ thể cho bạn. Vì thế, nếu bản thân là một người tự học giỏi, gọi là self-motivation cao (có tinh thần cầu tiến) cũng như có kỷ luật, thì không hà cớ gì mà skip freeCodeCamp cả, log in và tìm niềm vui ngay. Bản thân viết tự học và tự phấn đấu qua các khóa học này cũng đã giúp bạn có vững vàng hơn khi đối mặt với các khó khăn thực tế của nghệ lập trình.
Còn nếu như, các ví dụ trên không áp dụng được cho bạn, thì bạn có thể cân nhắc về các dạng bootcamp. Các dạng coding bootcamp nổi tiếng về mức độ khắt khe về thời gian, lịch trình để đôn thúc người dùng “lên tay” trong thời gian ngắn. Và đương nhiên là có nhiều cơ hội nghề nghiệp chất lượng sau các khóa bootcamp cho bạn. Không ít bạn thích có trải nghiệm thực tế – tương tác qua lại nhiều để thúc đẩy học nhanh hơn, và rất nhiều service trên thị trường cung cấp dạng này – KHÔNG FREE nhé.
Ngoài ra, các chương trình học lập trình truyền thống cũng là 1 option cho các bạn – chi tiết hơn, lộ trình rõ ràng có hướng dẫn hơn. Và đương nhiên là option nhiều phí nhất trong cả ba, do chất lượng và thời gian đảm bảo hơn nếu như không thể làm quá nhiều thứ một mình.
Bonus: Những nguồn tài liệu đáng xem cho những ai đang tự học lập trình
Hãy bắt đầu với kiến thức giới thiệu về CS50 trong khoa học máy tính trên edXCS50’s Introduction to Computer Science, đây đơn giản là những tài liệu cho người mới miễn phí tốt nhất và dễ học nhất được đánh giá. Sau đó hãy đọc tiếp lập trình web CS50 bằng Python và JavaScriptCS50’s Web Programming with Python and JavaScript.
Xem qua lộ trình mới nhất về thiết kế web qua video tạiđây.
Một số subreddit nên theo dõi:r/learnprogramming,r/programming,r/webdev,r/web_design, r/reactjs,r/freecodecamp,r/cscareerquestions ,… Bạn có thể tự tạo một tài khoản Reddit chỉ đơn thuần cập nhật các subreddit về CS, để đảm bảo rằng feed không bị nhiễm những thứ không liên quan khác.
Udemy: khóa học hot nhất từng mua làMERN Stack Front To Back của Brad Traversy. Những video hướng dẫn rất tuyệt vời sẽ giúp bạn trở thành một chuyên gia trên các platform mạng xã hội. Tuy nó mất phí nhưng đáng đồng tiền bát gạo.
Stack Overflow, cái này thì không cần phải động não quá nhiều. Search GG và đọc định nghĩa là đủ.
Học CSS qua các kênhFlexbox Froggy,Grid Garden. Xem xong bạn sẽ vận dụng khá tốt cho các buổi phỏng vấn đấy.
Các nguồn sách ebook về JavaScript miễn phí:The Road to Learn React,You Don’t Know JS, vàEloquent Javascript nếu bạn muốn thử cái gì khó hơn.
HackerRank hoặcLeetcode để rèn luyện kĩ năng problem solving (giải toán) của bạn. Nếu bạn thực sự giỏi kĩ năng này bạn có thể apply vào Big-N.
Tính chần chừ không dám hành động có thể là một trở ngại lớn trong công việc của bạn. Nếu bạn đang là một con người như vậy, đừng lo lắng hãy yên vị ở một công ty tốt và bạn sẽ cải thiện được tính chất này.
Qua bài viết này hãy tìm hiểu nhiều cách làm khác nhau để merge các list trong Python.
List trong Python là gì?
Python biết được 1 số loại dữ liệu phức hợp, vốn được dùng để group các giá trị khác lại cùng nhau. Và cách linh hoạt nhất chính là list, có thể được viết dưới dạng 1 list các giá trị (hay item) được phân tách bằng dấu phẩy giữa các dấu ngoặc vuông. Các list có thể chứa các loại item khác nhau, nhưng thông thường tất cả item đều có cùng 1 loại.
– Phương pháp extend sẽ mở rộng list bằng cách nối tất cả các item từ iterable.
– Độ dài của list sẽ được tăng lên phụ thuộc vào độ dài của iterable. – Nó sẽ tự cập nhật list gốc cho mình. – Loại return là None.
– List cũng hỗ trợ cho concatenation operations – các toán tử kết hợp. – Chúng ta có thể thêm 2 hay nhiều list hơn bằng cách dùng toán tử +. – Nó sẽ không cập nhật list gốc. – Loại return là 1 list object mới. Ví dụ 1: Concatenating 2 list
Dấu hoa thị * biểu thị việc giải nén các iterable. Toán hạng của nó phải thuộc dạng iterable. Iterable được mở rộng thành 1 chuỗi các item, được đặt trong tuple, list, hay set mới tại vị trí giải nén. list1=[*list2,*list3] Đầu tiên, nó sẽ giải nén phần nội dung và rồi tạo 1 list từ những nội dung đó.
Hãy tạo 1 iterator để trả về từng phần tử từ iterable đầu tiên cho tới hết, sau đó chuyển sang iterable tiếp theo. Nó sẽ xem các chuỗi liên tiếp như là 1 chuỗi đơn.
itertools.chain(*iterables)
List cũng là iterable, nên chúng ta có thể dùng itertools.chain() để merge 2 dictionaries lại. Loại return sẽ là đối tượng itertools.chain. Chúng ta có thể convert tới 1 list bằng cách dùng constructor list().
import itertools
l1=itertools.chain([1,2,3],[4,5,6])
#Returns an iterator object
print (l1)#Output:<itertools.chain object at 0x029FE4D8>
#converting iterator object to list object
print(list(l1))#Output:[1, 2, 3, 4, 5, 6]
6. List comprehension
1 list comprehension bao gồm dấu ngoặc [] chứa 1 biểu thức – expression được theo sau bởi 1 mệnh đề for, rồi tới 0 hay nhiều mệnh đề for hay if. Kết quả sẽ là 1 list mới mang kết quả từ việc đánh giá biểu thức trong ngữ cảnh của mệnh đề for và if theo sau nó.
[expression for item in iterable if conditional] Ví dụ 1: Joining 2 list bằng cách dùng list comprehension
l1=[1,2,3]
l2=[4,5,6]
l3=[x for n in (l1,l2) for x in n]
print (l3)#Output:[1, 2, 3, 4, 5, 6]
7. for loop
– for loop đầu tiên là để đi qua các list (for n in (l1,l2) – for loop thứ hai là để đi qua các phần tử trong list (for x in n) – Sau đó nó sẽ append mỗi phần tử tới list trống được tạo ra trước l3
l1=[1,2,3]
l2=[4,5,6]
l3=[]
for n in (l1,l2):
for x in n:
l3.append(x)
print (l3)
#Output:[1, 2, 3, 4, 5, 6]
———
Cách để join tất cả các chuỗi (string) trong 1 list:
str.join(iterable)
Return 1 chuỗi vốn là concatenation của các chuỗi trong iterable. 1 TypeError sẽ được trả ra nếu có bất kỳ giá trị không phải là chuỗi (non-string values) nào trong iterable, bao gồm các đối tượng bytes. Separator giữa các phần tử chính là chuỗi cung cấp phương thức này.
Ví dụ 1: Join tất cả các chuỗi trong list. Separator được cho là khoảng trắng (space)
l1=["Welcome", "to", "python", "programming", "language"]
l2=" ".join(l1)
print (l2)
#Output:
Welcome to python programming language
Ví dụ 2: Join tất cả các chuỗi trong list. Separator được cho là -
Cách để gỡ bỏ các phần tử trùng lặp trong lúc merging 2 list:
Các set Python không chứa các phần tử trùng lặp. Để gỡ bỏ các phần tử trùng lặp từ các list ta có thể convert list thành set bằng cách dùng set() và rồi convert ngược lại tới list bằng cách dùng constructor list().
Return thời gian tính bằng giây bởi vì epoch như 1 số thực dấu phẩy động (a floating-point number). Epoch chính là điểm nơi thời gian bắt đầu và phụ thuộc vào nền tảng (platform dependent). Date cụ thể của epoch và việc xử lý giây nhuận cũng phụ thuộc vào nền tảng.
Tính thời gian thực hiện để merge các list bằng cách dùng list comprehension
import time
l1=list(range(1,1000000))
l2=list(range(1000000,2000000))
start5=time.time()
l3=[x for n in (l1,l2) for x in n]
print (time.time()-start5)
#Output:0.06680965423583984
Tính thời gian thực hiện để merge các list bằng cách dùng for loop
import time
l1=list(range(1,1000000))
l2=list(range(1000000,2000000))
start5=time.time()
l3=[]
for n in (l1,l2):
for x in n:
l3.append(x)
print (time.time()-start5)
#Output:0.23975229263305664
Hãy so sánh thời gian thực hiện bằng tất cả các phương pháp để merge các list:
Kết luận:
– Phương pháp append sẽ thêm list như 1 phần tử tới 1 list khác. Độ dài của list sẽ được tăng lên 1 chỉ sau khi appending 1 list. – Phương pháp extend sẽ mở rộng list bằng cách appending tất cả các item từ iterable(list khác). Độ dài của list sẽ được tăng lên tùy thuộc vào độ dài của iterable. – Cả 2 phương pháp append và extend sẽ sửa đổi list gốc ban đầu. – Concatenation, giải nén, list comprehension return 1 đối tượng list mới. Nó sẽ không sửa đổi list gốc ban đầu. – itertools.chain() – Loại return sẽ là đối tượng itertools.chain. Chúng ta có thể convert tới 1 list bằng cách dùng constructor list(). _________ Các nguồn tài nguyên bạn có thể tham khảo:
1. An Informal Introduction to Python – Python 3.8.5 documentation https://docs.python.org/3/tutorial/introduction.html#lists
Bài viết được sự cho phép của tác giả Trần Duy Thanh
Với sự thay đổi như vũ bão của công cụ lập trình Android Studio, năm 2020 Tui tranh thủ viết bổ sung thêm một số tính năng hữu ích trong phiên bản mới này.
Bài đầu tiên trong chuỗi các hướng dẫn là Cách cài đặt và sử dụng Android Studio phiên bản năm 2020
Nói chung 1 đứa con nhà nghèo và 1 đứa con nhà giàu, 2 đứa này tính cánh và năng lực giống nhau thì đứa con nhà giàu sẽ học tốt hơn vì nó có điều kiện hơn.
Học là sự đầu tư có lãi trong tương lai, ráng đầu tư để có công cụ hỗ trợ chúng ta lập trình tốt hơn.
Bước trước tiên, ta cần tải Android Studio phiên bản mới nhất tại đây:
Nhấn vào “DOWNLOAD ANDROID STUDIO”, ở trên thấy là 3.6.2 (và không quan trọng, bao nhiêu kệ nó):
Màn hình trên hiện ra, check vào “I have read and agree with the above terms and conditions”
Sau đó bấm “DOWNLOAD ANDROID STUDIO FOR WINDOWS”. Máy bạn là MAC , LINUX thì cũng tương tự.
Bấm save để tải về, tùy tốc độ mà lâu hay mau, đợi chỗ này nó tải cho xong.
Sau khi tải xong thì bắt đầu cài đặt.
Trước khi cài đặt thì nên tạo 1 thư mục Android trong ổ C, ví dụ:
Khi cài đặt sẽ có 2 thành phần mà ta nên cài vào bên trong thư mục Android, đó là:
android-studio->công cụ lập trình
sdk->các thư viện để hỗ trợ lập trình
Bây giờ double click vào file cài mới tải ở trên về để cài đặt:
Nhấn Next để tiếp tục:
Để mặc định như trên rồi tiếp tục nhấn Next:
Ở màn hình trên lưu ý cài vào thư mục C:\Android\android-studio
Sau đó nhấn Next để tiếp tục:
Sau đó nhấn “Install” để bắt đầu cài đặt
Ngồi chờ xíu cho nó cài đặt, khi cài đặt xong sẽ có thông báo như dưới đây:
Nếu như trước đó đã làm làm Android thì dĩ nhiên có SDK sẵn và phần mềm không yêu cầu gì thêm cả, nếu chưa bao giờ cài thì sẽ tiếp tục được yêu cầu cài SDK:
Chương trình sẽ báo Missing SDK, ta tiếp tục nhấn Next
Lưu ý Android SDK Location ta chọn đúng nơi mà ta đã tạo thư mục trước đó: C:\Android\sdk
Sau đó nhấn Next để tiếp tục. Màn hình Verify Settings sẽ xuất hiện như dưới đây:
Nhấn FINISH để cài, màn hình Downloading Components sẽ hiển thị như dưới đây, chờ:
Bài viết được sự cho phép của tác giả Trần Anh Tuấn
Gần đây mình thấy có một bạn hỏi về việc làm sao để hiển thị được ngôn ngữ như tiếng Nhật, Hàn từ trên xuống dưới chứ không phải mặc định là theo tiếng latin như tiếng Anh chạy từ trái sang phải như chúng ta hay làm. Thì mình tìm thấy một thuộc tính là writing-mode để làm việc đó. Và điều thú vị là nó không chỉ áp dụng cho những ngôn ngữ như tiếng Nhật mà khi làm với ngôn ngữ khác như tiếng Anh thì chúng ta có thể tạo đoạn chữ đứng thẳng một cách dễ dàng hoặc làm được nhiều thứ hay ho khác. Cùng tìm hiểu thêm dưới đây nhé.
Giá trị mặc định của thuộc tính này là horizontal-tb, tức là nó sẽ hoạt động với những ngôn ngữ như tiếng Anh, tiếng Pháp…. như bình thường chúng ta hay thấy trên trang web. Và writing-mode có một giá trị khác rất là thú vị mà chúng ta sẽ cùng nhau khám phá tiếp theo đây đó chính là vertical-lr (trong đó lr nghĩa là Left to right) với các ví dụ sau.
Ví dụ số 1
Với giao diện như trên thì chúng ta có một section-title nằm xoay 90 độ và nằm phía trên bên trái. Nếu các bạn muốn làm ra như vậy thì các bạn cần phải làm từng bước phân tích như sau:
Đầu tiên là các bạn cần CSS cho lớp bao ngoài ví dụ ở đây là wrapper với thuộc tính position: relative.
Sau đó các bạn sẽ dùng position: absolute cho section-title.
Sau đó các bạn đổi trục xoay của nó bằng việc dùng thuộc tính transform-origin: left top vì nó nằm ở trên cùng bên trái.
Tiếp đến để nó xoay 90 độ thì các bạn dùng transform: rotate(90deg).
Cuối cùng các bạn cần thêm padding-left cho wrapper để nội dung của cái grid bên phải không tràn qua chỗ section-title.
Chúng ta có HTML và CSS cho giao diện ở trên như sau:
<section class=“wrapper”>
<h2 class=“section-title”>Our Works</h2>
<div class=“grid”>
<div class=“grid__item”></div>
<div class=“grid__item”></div>
<div class=“grid__item”></div>
<div class=“grid__item”></div>
</div>
</section>
.wrapper {
position:relative;
padding-left:70px;
padding-top:30px;
margin:0auto;
max-width:500px;
}
.section-title {
// 4 dòng đầu
position:absolute;
left:0;
transform-origin:lefttop;
transform:rotate(90deg);
//
font-size:20px;
font-weight:bold;
font-family:“Arial”;
}
.grid__item {
-webkit-box-flex:0;
flex:0048%;
height:150px;
background:#e1e1e1;
padding:1.35em;
box-sizing:border-box;
margin-bottom:1em;
}
Các bạn thấy đó việc để làm cái section-title nằm dọc thôi mà phải CSS tận 4 dòng. Tiếp theo đây thì chúng ta sẽ khám phá xem là writing-mode sẽ làm nó như thế nào đây.
.wrapper {
display:flex;
}
.section-title {
writing-mode:vertical-lr;// thay bằng dòng này
}
.grid{
display:flex;
flex:1;
flex-wrap:wrap;
-webkit-box-pack:justify;
justify-content:space-between;
}
Chỗ section-title thay vì dùng 4 dòng CSS thì giờ đấy với tinh chỉnh CSS một chút kết hợp với writing-mode thì chỉ còn một dòng mà thôi. Quá tuyệt phải không nào. Các bạn có thể lấy code để chạy thử nhé.
Ví dụ số 2
Với thiết kế này, thì các bạn cũng dễ dàng thấy là các social widget được sắp xếp nằm hàng dọc phía bên trái của nội dung. Nhìn vào thì chắc là nhiều bạn cũng code ra được mà không nhất thiết phải dùng tới writing-mode, nhưng điều thú vị ở đây là khi các bạn sử dụng social widget, các bạn đôi khi sẽ muốn nó hiển thị chiều dọc ở phía trên, ở giữa hay thậm chí là ở dưới hoặc ở giữa.
Thì như trên hình các bạn thấy rằng cái social widget này nó nằm chiều dọc được canh trên top của thằng cha chứa nó với giá trị text-align: left thì để thay đổi vị trí của nó chúng ta sẽ đổi giá trị của text-align. Ví dụ:
.social-widget {
writing-mode:vertical-lr;
text-align:right;
}
Hoặc là canh giữa với đoạn code này. Các bạn có thể nhấn vào đây để xem demo online nhé, và đừng quên F12 để check code và sửa lại text-align cho social-widget thay đổi vị trí đúng không nhé.
.social-widget {
writing-mode:vertical-lr;
text-align:center;
}
Trình duyệt hỗ trợ
Thật sự là may mắn vì thuộc tính này đa số các trình duyệt đều hỗ trợ, với global là 96.08% tại caniuse. Vì thế các bạn có thể sử dụng nó trong các trình duyệt hiện đại rồi, nhưng hãy cẩn thận khi làm việc với những trình duyệt như IE từ 6-11 nhé.
Bài viết được sự cho phép của BBT Tạp chí Lập trình
Trong những ngày đầu của web động, việc viết một ứng dụng web khác rất nhiều so với ngày nay. Các nhà phát triển sau đó chịu trách nhiệm viết mã cho không chỉ logic duy nhất của các ứng dụng đó, mà còn viết lại từng thành phần rất phổ biến trên các trang web khác – xác thực người dùng, xác thực đầu vào, truy cập cơ sở dữ liệu, tạo khuôn mẫu,…
Ngày nay, các lập trình viên có rất nhiều framework và hàng ngàn thành phần và thư viện có thể truy cập dễ dàng. Nhưng khi bạn học một framework mới, thì 3 framework mới hơn (và có ý nghĩa tốt hơn) đã xuất hiện với ý định thay thế nó.
Có nhiều lý do để chọn sử dụng một framework nào đó. Vậy tại sao phải sử dụng framework? Cụ thể hơn, tại sao nên sử dụng Laravel?
Thật dễ hiểu vì sao lại có lợi khi sử dụng các thành phần hoặc packages riêng lẻ có sẵn cho các nhà phát triển PHP.
Với các packages, người khác chịu trách nhiệm phát triển và duy trì một đoạn mã bị cô lập, có công việc được xác định rõ và theo lý thuyết thì người đó hiểu sâu hơn về thành phần này hơn bạn.
Các framework như Laravel – và Symfony, Silex, Lumen và Slim – đóng gói một bộ sưu tập các packages của bên thứ ba cùng với framework “tùy chỉnh” như các tệp cấu hình, service providers, cấu trúc thư mục được quy định… Vì vậy, lợi ích của việc sử dụng một framework nói chung là “ai đó” đã đưa ra quyết định không chỉ về các packages riêng lẻ cho bạn, mà còn về cách các packages đó phù hợp với nhau.
“Tôi có thể xây dựng nó”
Hãy nói rằng bạn bắt đầu một ứng dụng web mới mà không dùng framework. Bạn bắt đầu từ đâu? Chà, có lẽ nên định tuyến các yêu cầu HTTP, vì vậy bây giờ bạn cần đánh giá tất cả các thư viện phản hồi yêu cầu HTTP có sẵn và chọn một. Ồ, và bạn có thể cần phải thiết lập một số dạng tệp cấu hình v.v.. Nó nên sử dụng cú pháp nào? Nó nên đi đâu? Còn bộ điều khiển thì sao? Nó nằm ở đâu, và nó được tải lên như thế nào? Và rất nhiều thiết lập khác.
Hơn nữa, điều gì sẽ xảy ra nếu bạn dành thời gian để trả lời tất cả những câu hỏi đó và tạo thành công ứng dụng của bạn – điều gì tác động đến nhà phát triển tiếp theo? Thế còn khi bạn có 4 ứng dụng tùy chỉnh như vậy, hoặc nhiều hơn, và bạn phải nhớ nơi các bộ điều khiển nằm trong đó, hoặc cú pháp định tuyến là gì?
Như vậy việc tự xây dựng từ đầu vô cùng khó khăn và phức tạp, giải quyết quá nhiều vấn đề liên quan.
Tính nhất quán và linh hoạt
Các framework giải quyết vấn đề này bằng cách cung cấp một câu trả lời được xem xét cẩn thận cho từng câu hỏi. Chúng ta nên sử dụng thành phần nào ở đây? và đảm bảo rằng các thành phần cụ thể được chọn làm việc tốt với nhau. Ngoài ra, các framework cung cấp các quy ước làm giảm số lượng mã nguồn mà nhà phát triển mới cho dự án phải hiểu – ví dụ, nếu bạn hiểu cách định tuyến hoạt động trong một dự án Laravel, bạn hiểu cách nó hoạt động trong tất cả các dự án khác được xây dựng trên Laravel.
Các framework không chỉ cung cấp cho bạn một nền tảng vững chắc mà còn cho bạn tự do tùy chỉnh nội dung. Và điều này, Laravel làm rất tốt, đó là một trong các lý do làm cho Laravel trở nên đặc biệt.
Một phần quan trọng để có thể trả lời câu hỏi “Tại sao lại sử dụng Laravel?” là hiểu về lịch sử của Laravel – và hiểu những gì xảy ra trước nó. Trước khi Laravel trở nên nổi tiếng, đã có một loạt các PHP framework khác và những sự thay đổi trong PHP và các công cụ phát triển web khác.
Ruby on Rails
David Heinemeier Hansson đã phát hành phiên bản đầu tiên của Ruby on Rails vào năm 2004, và thật khó để tìm thấy một framework để phát triển ứng dụng web kể từ đó, điều đó đã bị ảnh hưởng bởi Rails theo một cách nào đó.
Rails phổ biến MVC, API API RESTful, quy ước về cấu hình, ActiveRecord và nhiều công cụ và quy ước khác có ảnh hưởng sâu sắc đến cách các nhà phát triển web tiếp cận ứng dụng của họ – đặc biệt là liên quan đến phát triển ứng dụng nhanh chóng.
Dòng chảy của các PHP Framework
Rõ ràng với hầu hết các nhà phát triển rằng Rails và các framework web tương tự, là làn sóng của tương lai và các framework PHP, bao gồm cả các framework được thừa nhận, các framework bắt đầu phát triển cũng như các framework đang bật lên nhanh chóng.
CakePHP là sản phẩm đầu tiên vào năm 2005 và ngay sau đó là Symfony, CodeIgniter, Zend Framework và Kohana (một ngã ba CodeIgniter). Yii đến vào năm 2008, và Aura và Slim vào năm 2010. 2011 đã mang ra FuelPHP và Laravel, cả hai đều không phải là nhánh của CodeIgniter, mà thay vào đó được đề xuất như là lựa chọn thay thế.
Một số framework có nhiều Rails-y hơn, tập trung vào các trình ánh xạ quan hệ đối tượng cơ sở dữ liệu (ORM), cấu trúc MVC và các công cụ khác nhắm đến mục tiêu phát triển nhanh. Những framework khác, như Symfony và Zend, tập trung nhiều hơn vào các mẫu thiết kế doanh nghiệp và thương mại điện tử
Cái tốt và cái chưa tốt của CodeIgniter
CakePHP và CodeIgniter là hai framework PHP ban đầu cởi mở nhất về mức độ cảm hứng của họ được rút ra từ Rails. CodeIgniter nhanh chóng nổi tiếng và đến năm 2010 được cho là phổ biến nhất trong các framework PHP.
CodeIgniter đơn giản, dễ sử dụng và tự hào về tài liệu tuyệt vời và một cộng đồng mạnh mẽ. Nhưng việc sử dụng công nghệ hiện đại và các mẫu của nó phát triển chậm, và khi thế giới framework phát triển và công cụ PHP phát triển, CodeIgniter bắt đầu tụt hậu về cả tiến bộ công nghệ và các tính năng vượt trội. Không giống như nhiều framework khác, CodeIgniter được quản lý bởi một công ty và họ chậm bắt kịp với các tính năng mới hơn của PHP 5.3 như namespaces và chuyển sang GitHub và sau đó là Composer. Đó là vào năm 2010, Taylor Otwell, người tạo ra Laravel, đã không hài lòng với CodeIgniter và anh ấy đã bắt đầu viết ra framework của riêng mình.
Laravel 1, 2 và 3
Bản beta đầu tiên của Laravel 1 đã được phát hành vào tháng 6 năm 2011 và nó được viết hoàn toàn từ đầu. Nó có tính năng ORM tùy chỉnh (Eloquent); định tuyến dựa trên routing (lấy cảm hứng từ Ruby Sinatra); một hệ thống mô-đun để mở rộng; và trợ giúp cho các biểu mẫu form, xác nhận, xác thực người dùng, và nhiều hơn nữa.
Sự phát triển sớm của Laravel trở lên nhanh chóng, và lần lượt Laravel 2 và 3 được phát hành vào tháng 11 năm 2011 và tháng 2 năm 2012. Họ đã giới thiệu controllers, unit testing, command- line tool, IoC, mối quan hệ Eloquent (Eloquent relationships) và migrations.
Laravel 4
Với Laravel 4, Taylor viết lại toàn bộ từ đầu. Đến thời điểm này, Composer, trình quản lý package phổ biến hiện nay của PHP, đã có dấu hiệu trở thành một tiêu chuẩn công nghiệp và Taylor thấy giá trị của việc viết lại Laravel như một bộ sưu tập các component, được phân phối và kết hợp với nhau bởi Composer.
Taylor đã phát triển một bộ các thành phần với tên mã Illuminate và vào tháng 5 năm 2013, đã phát hành Laravel 4 với cấu trúc hoàn toàn mới. Thay vì gói phần lớn mã của nó dưới dạng tải xuống, giờ đây, Laravel đã lấy phần lớn các thành phần từ Symfony (một framework khác phát hành các thành phần của nó để người khác sử dụng) và các thành phần Illuminate thông qua Composer .
Laravel 4 cũng giới thiệu hàng đợi-queues, email, tạo dữ liệu mẫu-seeding.
Laravel 5
Laravel 4.3 đã được lên kế hoạch phát hành vào tháng 11 năm 2014, nhưng khi sự phát triển tiến triển, rõ ràng tầm quan trọng của những thay đổi của nó là một bản phát hành chính, và Laravel 5 đã được phát hành vào tháng 2 năm 2015.
Laravel 5 có cấu trúc thư mục được tân trang lại, loại bỏ biểu mẫu và trình trợ giúp HTML, giới thiệu giao diện interfaces, một loạt các chế độ xem mới, Socialite để xác thực phương tiện truyền thông xã hội, Elixir để biên dịch tài sản, Scheduler biểu để đơn giản hóa cron, dotenv để quản lý môi trường đơn giản, form request và REPL hoàn toàn mới.
Laravel có gì đặc biệt?
Vậy điều gì làm nên sự khác biệt của Laravel? Tại sao nó đáng để sử dụng hơn một framework PHP khác? Hãy tìm hiểu những gì làm cho Laravel trở lên đặc biệt.
Triết lý của Laravel
Bạn chỉ cần đọc qua các tài liệu marketing của Laravel và READMEs để bắt đầu thấy các giá trị của nó. Taylor sử dụng những từ liên quan đến ánh sáng như là “Illuminate” và “Spark”. Và sau đó là: “Nghệ nhân-Artisan”, “Thanh lịch-Elegant.” Ngoài ra, đây là: Hơi thở của không khí trong lành. “Khởi đầu mới-Fresh start” Và cuối cùng là: Rapid Rapid. Tốc độ Warp.
Hai giá trị được truyền đạt mạnh mẽ nhất của Laravel là tăng tốc độ của nhà phát triển và hạnh phúc của nhà phát triển. Taylor đã mô tả ngôn ngữ của Nghệ nhân là cố ý tương phản với các giá trị thực dụng hơn. Bạn có thể thấy nguồn gốc của kiểu suy nghĩ này trong câu hỏi năm 2011 của anh ấy trên StackExchange, trong đó anh ấy đã nói – “đôi khi tôi dành thời gian (giờ) lố bịch để làm cho mã trông khá đẹp – chỉ vì một trải nghiệm tốt hơn khi tìm kiếm tại chính mã ấy” Và anh ấy thường nói về giá trị của việc giúp các nhà phát triển dễ dàng và nhanh chóng hơn để đưa ý tưởng của họ thành hiện thực, thoát khỏi những rào cản không cần thiết để tạo ra những sản phẩm tuyệt vời.
Mục tiêu của Laravel là cung cấp mã và các tính năng rõ ràng, đơn giản và đẹp mắt, giúp các nhà phát triển nhanh chóng tìm hiểu, bắt đầu và phát triển và viết mã đơn giản, rõ ràng
Các khái niệm được viết rõ ràng trên các tài liệu của Laravel.Trong đó có viết “Happy developers make the best code” – tạm dịch: “các nhà phát triển hạnh phúc khi viết mã tốt nhất”. Tất nhiên, bất kỳ công cụ hoặc framework nào cũng sẽ nói rằng nó muốn các nhà phát triển được hạnh phúc. Nhưng việc có được hạnh phúc của nhà phát triển là mối quan tâm chính, thay vì thứ yếu, đã có tác động rất lớn đến phong cách và tiến trình ra quyết định của Laravel. Khi các framework khác có thể nhắm mục tiêu về độ tinh khiết của kiến trúc làm mục tiêu chính của chúng hoặc tương thích với các mục tiêu và giá trị của các nhóm phát triển doanh nghiệp, thì trọng tâm chính của Laravel là phục vụ nhà phát triển cá nhân.
Làm thế nào Laravel đạt được hạnh phúc của nhà phát triển
Việc nói rằng bạn muốn làm cho các nhà phát triển hạnh phúc là một điều. Làm điều này là một việc khác, và nó đòi hỏi bạn phải đặt câu hỏi điều gì trong một framework có khả năng làm cho các nhà phát triển không hài lòng và điều gì có khả năng làm cho họ hài lòng nhất. Có một vài cách mà Laravel cố gắng để làm cho các nhà phát triển có cuộc sống dễ dàng hơn.
Đầu tiên, Laravel là một framework phát triển ứng dụng nhanh chóng. Điều đó có nghĩa là nó tập trung vào việc học tập dễ dàng và giảm thiểu các bước giữa bắt đầu một ứng dụng mới đến khi phát hành. Tất cả các tác vụ phổ biến nhất trong việc xây dựng các ứng dụng web, từ tương tác cơ sở dữ liệu, xác thực đến hàng đợi, đến email, bộ nhớ đệm, được thực hiện đơn giản hơn bởi các thành phần mà Laravel cung cấp.
Chưa hết, Laravel cung cấp toàn bộ hệ sinh thái các công cụ để xây dựng và khởi chạy các ứng dụng một cách dễ dàng. Bạn có Homestead và Valet để phát triển trên môi trường local, Forge cho quản lý máy chủ và Envoyer để triển khai nâng cao. Và có một bộ gói bổ trợ: Cashier cho thanh toán và đăng ký, Echo cho WebSockets, Scout cho tìm kiếm, Passport để xác thực API, Socialite để đăng nhập bằng mạng xã hội và Spark để khởi động SaaS của bạn. Laravel đang cố gắng loại bỏ công việc lặp đi lặp lại khỏi các công việc của nhà phát triển để họ có thể làm một cái gì đó độc đáo.
Tiếp theo, Laravel tập trung vào”convention over configuration”, – nghĩa là nếu bạn sẵn sàng sử dụng cấu hình mặc định của Laravel, bạn sẽ phải làm việc ít hơn nhiều so với các framework khác yêu cầu bạn phải khai báo tất cả các cài đặt của mình ngay cả khi bạn sử dụng cấu hình mặc định. Các dự án được xây dựng trên Laravel mất ít thời gian hơn so với các dự án được xây dựng trên hầu hết các framework PHP khác.
Laravel cũng tập trung vào sự đơn giản. Nó có thể sử dụng cơ chế “dependency injection” và “Mocking” và kho lưu trữ dữ liệu và phân chia trách nhiệm truy vấn và tất cả các loại mẫu kiến trúc phức tạp khác với Laravel, nếu bạn muốn.
Cộng đồng Laravel
Một trong những yếu tố nổi bật của Laravel, đóng góp cho sự phát triển và thành công của nó, là cộng đồng giảng dạy, hỗ trợ của Laravel. Từ các video hướng dẫn về Laracasts của Jeffrey Way đến Laravel News đến các kênh Slack và IRC, từ bạn bè Twitter đến các blogger đến các hội nghị của Laracon, Laravel có một cộng đồng lớn và sôi động, những người đã có mặt từ ngày đầu tiên và những người sống một mình ngày một
Taylor đã hiểu từ những ngày đầu của Laravel rằng một dự án nguồn mở thành công cần có hai điều: tài liệu tốt và một cộng đồng lớn. Và hai điều đó bây giờ là đặc điểm nổi bật của Laravel.
Tại sao lại là Laravel?
Vậy – tại sao bạn nên sử dụng Laravel?
Bởi vì Laravel giúp bạn đưa ý tưởng của mình thành hiện thực mà không bị lãng phí mã, sử dụng các tiêu chuẩn mã hóa hiện đại, được bao quanh bởi một cộng đồng lớn, với một hệ thống các công cụ hỗ trợ vô cùng mạnh mẽ.
Và bởi vì bạn, nhà phát triển thân yêu, bạn xứng đáng được hạnh phúc.
Cậu tệ quá! Tốt nghiệp loại giỏi, lại xuất thân từ trường danh tiếng, cậu thể hiện chỉ được như thế thôi sao? Cậu không phải là nhân viên tốt. Chúng tôi cần nhiều hơn thế!
Đó là những câu nói mà nhiều ứng viên đã chia sẻ với TopDev. Thực tế ấy cho thấy một sinh viên giỏi chưa hẳn đã làm việc tốt. Lãnh đạo là người có chuyên môn, và chắc chắn sự phê bình hay góp ý của họ đều có cơ sở? Vậy bạn lẽ làm gì? Không lẽ bạn sẽ xù lông để tự bảo vệ mình: Ai cũng bảo tôi học giỏi, từ ba mẹ đến thầy cô, bạn bè, các người dựa vào gì để chê tôi? Việc phản bác như vậy sẽ không khiến bạn trở thành một nhân viên tốt hơn.
Hãy bình tĩnh! Và thật tỉnh táo để loại bỏ ngay suy nghĩ “Các sinh viên ưu tú thì nhất định là một nhân viên giỏi”. Nhiều yếu tố khác nhau giữa cả hai môi trường doanh nghiệp và giảng đường đã tạo ra sự chi phối lớn đến tiêu chi đánh giá chất lượng một sinh viên/nhân viên. Do vậy, việc áp đặt chung một quy chuẩn đánh giá là thiếu nhất quán.
Cùng TopDev phân tích rõ hơn về vấn đề này thông qua bài viết sau.
Hệ tiêu chuẩn đánh giá không đồng nhất
Ở Đại học, tiêu chuẩn đánh giá về năng lực là thái độ, kết quả học tập. Ngược lại, môi trường doanh nghiệp lại đề cao về thái độ và sự thể hiện thông qua những kết quả thực tế.
Nếu ở chốn giảng đường, bạn đáp ứng được những chỉ dẫn, điểm của bạn sẽ tốt. Và hiển nhiên, bạn thuộc top những sinh viên nổi trội. Thế nhưng, trong một tổ chức, cấp trên chỉ đánh giá bạn dựa vào những kết quả đạt được.
Hơn thế nữa, tiêu chuẩn về năng lực trong công ty còn chịu tác động bởi các hệ giá trị về tính trách nhiệm: đi đúng giờ, hoàn thành deadline,… Trường hợp bạn đạt hiệu suất sẽ được xem xét là một nhân viên tốt. Ngược lại, việc khiển trách hoặc sa thải sẽ dành cho những cá nhân không thể hoàn thành tốt nhiệm vụ được giao.
Nhiều sinh viên mới ra trường do thiếu trải nghiệm, họ bị chật vật với mọi thứ. Dù họ đã cố gắng nhưng vẫn luôn bị phê bình. Dường như lời phát ngôn: “Tôi đã cố gắng rồi” không còn hữu hiệu trong hoàn cảnh công sở nữa. Thay vào đó, giá trị của bạn chỉ được công nhận khi bạn thực hiện được phát ngôn: “Tôi đã hoàn thành”.
Cách nhìn nhận về năng lực có sự khác biệt
Học tập trên giảng đường, IQ được xem là hệ giá trị phản ánh tài năng. Thế nhưng, khi đi làm EQ mới là hệ giá trị được các công ty quan tâm nhất.
Chẳng hạn, các sinh viên khối ngành khoa học xã hội cần tận dụng năng lực trí nhớ. Sinh viên khối ngành khoa học tự nhiên tận dụng năng lực suy luận – tính toán.
Thế nhưng, các doanh nghiệp lại cần mỗi nhân viên phát huy tối đa các kỹ năng: thiết lập mối quan hệ – networking, kỹ năng giao tiếp, kỹ năng đàm phán,… Đó lại là những năng lực về EQ.
Chúng ta không thể phủ nhận những thành tích xuất sắc mà một sinh viên giỏi đạt được. Đó là những nỗ lực thật sự của họ. Thế nhưng, để trở thành một nhân viên tốt với đầy đủ những tố chất thì họ chưa đạt được. Nhiều sinh viên có kết quả học tập chưa tốt nhưng họ lại thành công. Họ tinh tế và có cách ứng xử chuyên nghiệp. Đồng thời, biết phát huy thế mạnh EQ để chứng tỏ năng lực của mình. Đó là lý do tại sao họ lại nhận được nhiều sự hậu thuẫn từ đồng nghiệp, bạn bè.
Sự khác biệt trong quy luật về Điểm giá trị năng lực
Điểm số học tập càng cao thì điểm giá trị năng lực càng lớn. Đó cũng chính là thước đo đánh giá duy nhất tại môi trường Đai học. Ngoài ra, tiêu chí phụ sẽ được phát huy nếu cá nhân sinh viên có tham gia vào các họat động xã hội, công trình nghiên cứu. Lúc ấy, điểm giá trị năng lực của bạn có thể được gia tăng lên.
Khác với quy luật trên, thước đo đánh giá ở công ty rất đa dạng. Tùy vào từng vị trí khác nhau đều có sự linh hoạt thể hiện các năng lực tương ứng.
Ví dụ như cùng là công ty về công nghệ, ở phòng ban Dev, cần những bạn có kỹ năng lập trình tốt. Trong khi đó ở phòng ban Social lại đòi hỏi những bạn có kỹ năng về sáng tạo. Chính sự khác biệt ấy dẫn đến yêu cầu thể hiện và phát triển các năng lực cũng khác nhau. Điểm giá trị năng lực trong công ty hướng đến những nhân viên phù hợp nhất, không phải tìm kiếm những nhân viên ưu tú nhất.
Dù bạn giỏi hay chưa giỏi theo quy chuẩn về thành tích, bạn cũng cần quan tâm đến cái gọi là sự phù hợp với môi trường công ty. Hãy thật sự hiểu được công ty cần gì. Bạn có gì để đáp ứng được những nhu cầu mà họ đang tìm kiếm. Lúc ấy, bạn mới thật sự là một cử nhân/ứng viên giỏi đúng nghĩa.
Lời kết
Không cần biết bạn giỏi thế nào, khi bắt đầu trở thành một nhân viên tốt, hãy tôn trọng các quy tắc. Hãy tìm hiểu để thích nghi nhanh chóng với môi trường mới. Quan tâm đến việc học hỏi và phát huy tốt các kỹ năng, bạn sẽ tiến bộ nhanh thôi. Đối với các công ty, nên tăng cường công tác đào tạo kỹ năng cho nhân viên thay vì chỉ dựa vào sự phán đoán đơn thuần – thành tích học tập. Hãy lưu tâm: sự cân bằng luôn quan trọng.
Bài viết được sự cho phép của tác giả Nguyễn Trương Trung Tín
(Lời mở đầu, thích thì đọc không thích thì cho qua) Vậy là cũng ngót nghét 4 tháng từ lúc bỏ vị trí làm native của Android chuyển sang làm giao diện và tính năng người dùng. Trong 4 tháng đó thì hết 3 tháng giành ra để chạy tính năng, chỉ mới 1 tháng gần đây mới giành lại thời gian để nghiên cứu “lại” kiến thức Android. Sau khi kinh qua từ core, tầng native tới tầng UI của Android thì hầu như đã có cái nhìn tổng quan về lập trình Android nói riêng và lập trình di động nói chung. Vì vậy, mình dự định viết vài bài blog để tổng hợp kinh nghiệm, kiến thức và các bài học mình rút ra được trong qua trình làm việc. Xem như vừa ôn bài vừa chia sẽ kiến thức, còn viết được vài bài hay không thì còn tùy vào mức độ “siêng” level max của mình nữa :v.
Thì sau 4 tháng chuyển từ native sang làm UI mình chỉ muốn rút gọn bài viết này trong 1 câu duy nhất là “PLEASE! LET THE UI COME FIRST”, còn câu chuyện tại sao mình nói câu đó và làm thế nào để let it come first thì mình sẽ viết tiếp theo sau đây hoặc trong các bài kế tiếp
Sự khác biệt giữa mobile và computer (pc và laptop) – mình chỉ so sánh với Android vì nó khá phổ biến trên thế giới và đa dạng về cấu hình hơn.
– TỐC ĐỘ XỬ LÝ: Về tốc độ xử lý thì ai dùng qua computer và mobile đều sẽ dễ dàng khẳng định được là tốc độ của mobile mặc dù đã rất phát triển nhưng so với tốc độ xử lý của máy tính thì vẫn còn xa. Nhưng để nói có sách mách có chứng thì sau một hồi tìm hiểu các thông số CPU của một số máy mạnh nhất hiện nay thì:
+ Android: Đa số máy thuộc dạng trâu bò hiện này thì CPU đã đạt được ngưỡng 2.7GHz và lõi tứ http://news.zing.vn/10-de-Android-cau-hinh-manh-nhat-hien-nay-post482280.html .
+ Computer: Về phần máy tính thì sau khi tìm hiểu 1 số bài viết thì mình biết được CPU của máy laptop hiện nay đã có thế lên đến 3,4GHz và lõi 8 lõi 12 chứ không còn là lõi tứ nữa. Bên cạnh đó máy máy tính còn có thể được trang bị card màn hình cấu hình “khủng” để giúp cho việc xử lý đồ họa được mượt mà hơn.
– BỘ NHỚ RAM: RAM là 1 phần không thể thiếu nếu đem ra so sánh performance giữa 2 thiết bị nào đó.
+ Android: Mình vẫn chưa được thấy máy Android nào trang bị RAM lên đến 8GB, hoặc nếu có thì cũng thuộc dạng hàng hiếm hiện nay, đa số các máy Android tầm trung chỉ vào khoảng 2-3GB RAM là cùng, trong đó hệ điều hành thường chiếm tới vài trăm MB RAM.
+ Computer: Laptop hoặc PC hiện nay theo mình biết thì đã trang bị được tối đa lên đên 16GB và có vài máy đã được 32GB RAM, 1 số lượng bộ nhớ tuyệt vời để chạy được hàng tá ứng dụng.
– DUNG LƯỢNG LƯU TRỮ: Với nhu cầu kĩ thuật số ngày càng phát triển về lượng và cả về chất như hiện nay thì 1 tấm hình có dung lượng vài chục MB hoặc 1 2 game có dung lượng lên tới vài GB là chuyện hết sức bình thường.
+ Android: Với các máy hiện nay thì đa số chỉ hộ trợ bộ nhớ trong khoảng 64GB và nếu có hổ trợ thẻ nhớ ngoài nữa thì mình nghĩ cũng chỉ lên đến tầm 128GB nữa là cùng.
+ Computer: Laptop hiện nay thì ổ cứng 256GB là đã thuộc dạng vứt đi được rồi. Một số máy hiện nay đã trang bị ổ cứng 1TB, ngoài ra còn chưa kể đến việc có thể lắp song song ổ SSD vào để tăng tốc độ truy xuất của bộ nhớ.
– PIN: Đa số người dùng computer sẽ ít lo về vấn đề PIN trong khi đó việc dùng mobile sẽ bi ảnh hưởng rất nhiều đến dung lượng PIN của thiết bị.
– TỐC ĐỘ MẠNG: Với thời đại internet như hiện nay thì tốc độ mạng là vấn đề không thể không đề cập tới.
+ Android: Đa số người dùng di động sẽ sử dụng mạng di động 3G làm phương tiện truy cập internet chính vì vậy về chi phí sẽ tốn rất nhiều và tốc độ thì không thể so sánh với mạng cap quang được.
+ Computer: Người dùng computer đa số sẽ sử dụng wifi hoặc mạng cáp, vì vậy việc dùng thả ga mạng để download và sẽ không lo đến chi phí sẽ là điều hiển nhiên
Đương nhiên sẽ có rất nhiều khía cạnh còn phải so sánh, nhưng việc so sánh trên chủ yếu mình muốn nói là mobile còn rất hạn chế so với computer nên việc để làm được 1 ứng dụng tốt thì còn phải quan tâm trên mức “làm được” đối với 1 số vấn đề. Và như mình nói ở trên là “LET THE UI COME FIRST!”
Giao diện người dùng.
Hãy tưởng tượng việc bạn bật 1 ứng dụng xem hình gái xinh lên. Có 1 danh sách các hot girl được show ra, và khi bạn scroll xuống list hình giật tung chảo thì bạn có còn hứng thú với việc sử dụng app đó nữa hay không? hay là tìm 1 ứng dụng khác?? Hoặc vào 1 ứng dụng tìm quán ăn mà bạn phải đợi màn hình loading (thậm chí là không hiện gì) đến cả buổi thì bạn có nản và tắt nó đi trước khi dùng hay không? Việc người dùng tương tác với ứng dụng họ sẽ thấy giao diện và tương tác với nó đầu tiên, không cần biết tính năng bạn làm bá tới đâu, bao nhiêu công sức bạn bỏ ra để “make up” cho giao diện đẹp lung linh, nhưng khi người dùng tương tác vào cảm thấy không hài lòng thì việc ứng dụng bạn bị uninstall ngay sau đó là rất dễ xảy ra. Vì vậy giữa việc bạn làm được và làm tốt sẽ rất khác nhau.
Nói thì dễ làm mới khó, mình có nghiên cứu khá nhiều tài liệu và tự tìm hiểu cũng như hỏi han các “thánh” khác thì rút ra 1 số kinh nghiệm về việc optimize layout (nhưng chưa có cơ hội áp dụng hết), mình sẽ chia sẽ ở những bài sau nếu có cơ hội. Một số kỹ thuật cho các bạn muốn tìm hiểu là: lazy load, optimize view hierachy, thread, cache, reuse view by using view holder,…
Đừng làm tốn tài nguyên người dùng 1 cách không đáng.
Như đã nói ở phần so sánh trước, Người dùng mobile đa phần sẽ dùng 3G để làm phương tiện truy cập internet. Vì vậy, dung lượng 3G là 1 điều hết sức đáng lưu ý. Đem so sánh 1 số ứng dụng OTT hiện nay như Zalo, Skype, Viber,.. thì bạn sẽ thích dùng cái nào hơn, đương nhiên là ứng dụng nào có dung lượng cuộc gọi thấp nhất và chất lượng ok nhất. Nói ngắn gọn lại là tốn ít tiền 3G nhưng gọi vẫn ok. Hoặc việc bạn phải tải đi tải lại 1 bài nhặc hoặc hình ảnh nào đó mà bạn “ĐÔ tải trước đó rồi thì thật sự rất phí dung lượng 3G khi bạn sử dụng những app đó. Vì vậy việc chú ý tài nguyên từ bộ nhớ máy, RAM, dung lượng 3G,… rất đáng để chú ý khi bạn bắt đầu lập trình 1 ứng dụng di động.
Không nên làm người dùng khó hiểu và cảm thấy phức tạp khi dùng app.
Việc người dùng có sử dụng ứng dụng của bạn hay không còn tùy thuộc rất nhiều vào độ “đơn giản” của app bạn. Khi có 2 ứng dụng 1 ứng dụng bắt bạn phải điền đầy đủ thông tin và 1 ứng dụng chỉ cần click vào nút đăng nhập bằng facebook thì bạn sẽ chọn sử dụng ứng dụng nào? Đương nhiên là ứng dụng cho đăng nhập bằng facebook, vì nó khá đơn giản và dễ sử dụng. Ngoài ra những thao tác cơ bản nhưng số bước thực hiện quá nhiều cũng rất dễ làm cho user phát nản. Giả dụ khi bạn cần mua 1 món hàng online qua app. Thì bạn có muốn phải làm 3 4 bước thủ tục, qua 3 4 bước màn hình. Hay là chỉ cần click mua 1 phát là có hàng liền? Đơn cử cho việc này là sự xuất hiện của Dialog, giúp người dùng không phải chuyển màn hình nhiều và làm cho app có cảm giác là nhỏ và tiện dụng hơn.
Nên đặt ví trí của mình là một người dùng app
Bạn sẽ cảm thấy khó chịu, bức bối cực kì khi bạn làm được điều này. Vì đi đâu trong app bạn bạn cũng sẽ thấy chưa hài lòng, và muốn nó tốt hơn, nhanh hơn và “rẻ” hơn. Hoặc nếu bạn không làm được thì bạn cứ nghĩ, sau này công ty “kế tiếp” của bạn sẽ nhìn vào sản phẩm bạn đang làm và đánh giá. Họ sẽ có cái nhìn cực kì khách quan, vì thế nếu bạn không biết tự đặt lại vị trí của mình thì tương lai bạn cũng có thể gặp khó khăn.
Bài viết là 1 số kinh nghiệm ít ỏi mình rút ra được, mọi người có góp ý hay đóng góp thêm thì mail về cho mình nha. Email: ntttin132@Gmail.com!
Học lập trình tới khi nào có thể làm freelancer? Tôi thấy trên các group về lập trình thì thấy khá nhiều bạn post bài viết về mong muốn học lập trình xong để đi làm freelancer và coi đó là nghề tay trái của mình. Nên nay tôi sẽ viết bài này để nói về học lập trình khi nào thì có thể làm freelancer.
Đầu tiên thì chúng ta cần phải biết freelancer là gì? freelancer là những người làm công việc tự do, không bó buộc vào một công ty nào cả. Freelancer thì có hai dạng, một là làm freelancer toàn thời gian, hai là freelancer chỉ làm buổi tối và cuối tuần. Còn ngày thường thì vẫn đến công ty làm bình thường.
2. Học lập trình khi nào có thể làm freelancer?
Câu trả lời nay rất đơn giản, khi bạn có kiến thức thì bạn có thể làm freelancer. Nếu bạn lại hỏi tôi kiến thức như thế nào là đủ thì tôi xin trả lời là kiến thức thì không bao giờ là đủ cả. Tôi xin ví dụ bạn đang và đã học hết một khóa lập trình ở một trung tâm hay một khóa học online nào đó, trong một ngày đẹp trời bạn vô tình lướt facebook và thấy một người nào đó post bài thuê làm bài tập hay đồ án. Bạn đọc yêu cầu và cảm thấy mình làm được và nhận cái công việc đó, hay bất kể công việc gì liên quan đến lập trình như fix bug, làm đồ án, bài tập…Lúc này bạn cũng đã dấn thân vào con đường freelancer rồi đó.
Tuy nhiên đó là những công việc chỉ giúp bạn kiếm được vài đồng lẻ mà thôi, làm sao bạn có thể trang trải cuộc sống trong khi giá cả đang leo thang từng ngày. Để trở thành một freelancer thực thụ, người mà có thể kiếm được nhiều hơn những số tiền lẻ kia thì cần rất nhiều kỹ năng về lập trình, phân tích dự án, giải quyết vấn đề… Mà những kỹ năng này thì không có trường lớp nào dạy bạn cả, chỉ có đi làm thực tế ở những công ty khoảng 2-3 năm là kinh nghiệm bạn sẽ phát triển dần dần lên. Lúc này bạn sẽ tự tin nhận những dự án khó, tiền nhiều để làm. Nếu bạn đang đi một mình thì không bao giờ mà học lập trình để làm freelancer mà không phải trải qua một vài năm rèn dũa ở các công ty về lập trình cả. Còn nếu bạn có người dẫn dắt để làm freelancer thì có thể bạn sẽ không cần rèn dũa bởi công ty mà lúc này người rèn dũa bạn chính là người dẫn dắt bạn.
3. Những khó khăn khi làm freelancer?
* Khó khăn về tìm kiếm dự án
Để làm được freelancer thì bạn phải có dự án để làm, mà dự án ở đâu ra. Bạn phải có được nguồn cung cấp từ bạn bè, người thân.. hoặc phải tự đi kiếm dự án về làm.
* Khó khăn về kỹ thuật
Một ngày nọ bạn nhận làm một project, tuy nhiên đang làm đến một task khó nào đó thì bạn bí, làm hoài hai ba ngày không ra, deadline sắp tới gần, bạn cảm thấy chán nản, bạn muốn bùng dự án. Lúc này kỹ năng của bạn không đáp ứng được độ khó của dự án, bạn cứ nghĩ là bạn làm được rồi nhận đại, nhưng khi vào làm thì tá hỏa lên vì không giải quyết được những vấn đề trong đó.
* Khó khăn khi nhận dự án
Khi nhận một dự án thì bạn phải cân nhắc về độ lớn của dự án, nếu đang làm freelancer độc cô cầu bại thì bạn không thể nhận dự án quá lớn được vì một mình thì khó có thể ôm một dự án lớn. Khi mà kỹ thuật của bạn không đủ thì dự án rất dễ bị fail. Lúc này bạn phải có một team để làm, cùng nhau giải quyết những vấn đề đang gặp phải.
4. Lợi ích khi làm freelancer?
Khi làm freelancer thì lợi ích về tiền bạc thì cũng không hề nhỏ, những người làm freelancer toàn thời gian nếu dự án có đều thì số tiền của họ kiếm được là gấp rưỡi hoặc gấp đôi nếu đi làm ở công ty. Còn những người làm freelancer ít thời gian thì cũng có thể kiếm được tiền trang trải cho cuộc sống của mình.
Ngoài lợi ích về tiền bạc thì bạn cũng tăng được kỹ thuật lập trình của mình lên, nhờ những lần tôi làm freelancer có nhiều yêu cầu khác nhau nên tôi cũng biết thêm khá nhiều những cái mới lạ và hay ho.
Nhắc đến thiệt hại khi làm freelancer thì tôi vẫn đang cay, đó là việc bị khách hàng xù tiền. Vấn đề xù tiền khi giao hàng xong thì những người làm freelancer có lẽ ai cũng đã từng bị, lần đầu làm để tạo uy tín nên tôi đã không yêu cầu thanh toán trước 50% mà giao hàng họ test ổn thì sẽ yêu cầu thanh toán. Tuy nhiên sau khi giao hàng thì không liên lạc được nữa và mất trắng số tiền mà mình cực khổ làm cho họ. Thế nên nếu ai muốn theo nghiệp freelancer thì khi làm dự án nên cân nhắc số tiền đặt cọc để không mắc phải sai lầm giống như tôi nhé.
Bài viết được sự cho phép của tác giả Huỳnh Quán Cẩm
Chuyện là vài hôm trước, tui có fix được một lỗi tồn tại khá lâu của Nabo liên quan đến Elixir compiler. Bản fix thì chỉ vài dòng thôi, cơ mà nguồn cơn sâu xa thì hơi dài dòng. Giải thích trong PR không hết. Hơn nữa, từ lâu tui cũng đã muốn viết bài về chủ đề compiler của Elixir vì thấy nó cũng khá hay ho. Nhân cơ hội này, xin được chia sẻ cùng các bác.
Để tiện theo dõi, tui tạm chia Elixir Compiler ra làm 2 phần: Compiler và Parallel Compiler. Compiler chịu trách nhiệm compile một file ra Erlang binaries (BEAM byte code). Parallel Compiler cho phép compile nhiều file song song, nhằm tăng tốc quá trình compile.
Bài viết hơi khô khan, vui lòng tự tra dầu nhớt trước khi đọc!
Compiler
DQ;ĐĐ (Dài quá; đếu đọc)
Elixir compiler biên dịch một đoạn mã nguồn Elixir thành BEAM byte code.
DĐ;ĐĐ (Dài đó; đọc đi)
Mục tiêu của Elixir compiler là sinh ra BEAM byte code. Sau đó, byte code được sử dụng tùy theo mục đích biên dịch: mix compile, IEx, v.v.
Về bản chất, Elixir compiler là một chương trình Erlang. Khi cần biên dịch một file, đầu tiên nó sẽ bật máy ảo Erlang lên và bootstrap các module cần thiết (Kernel, code server).
Tương tự như các trình biên dịch khác, Elixir compiler cũng tokenize và parse source code thành abstract syntax tree (AST, cây cú pháp trừu tượng), thường gọi là quoted form trong Elixir. Mọi language construct trong Elixir đều được biểu diễn bằng quoted form.
AST của Elixir là một tuple gồm 3 phần tử: toán tử, metadata, và các tham số của toán tử đó. Ví dụ AST của câu lệnh a + b * c là:
Quoted form là building block của ngôn ngữ Elixir. Nó là code dưới dạng data, thao tác với nó cho phép ta dùng code để viết code. Elixir cung cấp interface quote, unquote và Macro để làm việc với quoted form. Để biết chi tiết hơn bạn có thể đọc qua bài Elixir—Ngôn ngữ được biết bằng macros.
Sau đó, từng bước một, compiler sẽ biên dịch AST thành BEAM byte code. Đây là một quá trình dài bao gồm nhiều bước:
expand—triển khai quoted form và thực hiện kiểm tra tính đúng đắn của quoted form.
translate: dịch từ expanded form sang Erlang Abstract Format, còn gọi là Erlang parse tree.
compile: biên dịch từ Erlang Abstract Format sang Core Erlang, cuối cùng là BEAM bytecode.
Thật ra thì trong các bước này chia ra nhiều bước và nhánh nhỏ khác, mà trong khuôn khổ bài viết này không thể trình bày hết. Xin được khất lại sang một bài khác.
Compiler ghi BEAM bytecode vào code path, cụ thể là /ebin, kết thúc quá trình biên dịch.
Một số câu hỏi thường được đặt ra
Nếu code Elixir được biên dịch ra Erlang, vậy nó có chậm hơn Erlang không?
Không và không hẳn. Code Elixir được biên dịch ra BEAM byte code (không phải Erlang). Code Erlang cũng vậy, tuy các bước có khác, nhưng output vẫn là BEAM byte code. Erlang không phải là ngôn ngữ bậc cao hơn Elixir.
Một số trường hợp Elixir sẽ chậm hơn đôi chút, ví dụ khi bạn làm việc với Enum. Đôi lúc code Elixir sẽ nhanh hơn, khi bạn sử dụng binary thay vì char list như Erlang. Cơ mà sự khác biệt chỉ là rất rất rất nhỏ, không thật sự đáng kể.
Vì sao compiler phải bỏ BEAM byte code vào trong ebin?
Erlang VM trong interactive mode có cơ chế autoload module vào code server ở lần đầu tiên bạn gọi module, từ ebin. Cơ chế autoloading chính là yếu tố làm nên sự thú vị của Elixir parallel compiler mà tui sẽ trình bày tiếp theo.
Elixir Parallel Compiler
Trước khi đi vào parallel compiler, hãy cùng tui kinh qua 2 thứ: Code Server và :error_handler.
Code Server là nơi chứa code của Erlang VM. Trước khi một module được thực thi, code của nó cần phải được nạp vào code server. (Ờ ha, không nạp code sao chạy ha.)
Module :code trong Erlang Kernel cung cấp một số interface để bạn thao tác với code server. Ví dụ :code.load_binary(Foo, "", beam) sẽ nạp module Foo với beam là byte code; trong khi :code.purge hoặc :code.delete giúp bạn xóa code ra khỏi code server.
iex> defmodule Foo do
...> deffoo(), do:true
...> end
{:module, Foo,
<<70, 79, 82, ...>>, {:foo, 0}}
iex> Foo.foo()
true
iex> :code.delete(Foo)
true
iex> Foo.foo()
** (UndefinedFunctionError) function Foo.foo/0 is undefined (moduleFooisnotavailable)
Foo.foo()
Elixir compiler chạy trên Erlang VM interactive mode. Compile-time của chúng ta chính là run-time của compiler ( Mr. Obvious!). Compiler của Elixir vừa biên dịch code, vừa thực thi code.
Đọc tới đây, một độc giả tinh ý phán xét: Quào, khúc này bối rối quá Quần Cam ơi. Vừa biên dịch code vừa chạy code là sao? Chẳng phải ông vừa chém là compiler phải dịch ra byte code, nạp nó vào code server thì mới thực thi được sao. Mâu thuẫn, mâu thuẫn! Trả lại tiền 2 tô sủi cảo đi.
Ở đây, ta muốn tính @heavy_computation ở compile time để tăng tốc hàm foo(), thay vì cứ phải tính đi tính lại ở run time. Cho nên khi biên dịch tới khúc đó, compiler cần phải thực thi code.
Để cho gọn code, đôi khi ta muốn bỏ tách phần code @heavy_computation vào một module khác cho code đẹp. Thế là code viết lại thành:
Tuy nhiên, việc này sẽ làm nảy sinh ra một vấn đề: compiler cần đảm bảo rằng HeavyComputation được biên dịch trước Foo. Hay nói cách khác, Foo có compile-time dependency vào HeavyComputation.
Để đảm bảo điều đó, cách giải quyết thông thường là sinh ra một cái dependency graph. Rồi dựa vào graph này để biết thứ tự biên dịch của các file. Cơ mà sẽ không có thuật toán liên quan đến dependency graph ở bài viết này đâu .
Đó là vì Elixir … không làm như thế mà chọn một lối đi riêng, dựa vào cơ chế :error_handler trong interactive mode. Nó tự tìm dependency on-the-fly (không biết dịch on-the-fly sao cho gọn).
Trong interactive mode, nếu module không tồn tại, Erlang VM sẽ kích hoạt callback trong :error_handler. :error_handler sẽ thử nạp module đang thiếu lên. Nếu load được, nó chạy tiếp như không có gì xảy ra. Nếu không load được, nó sẽ chửi vào mặt chúng ta.
Ngoài ra, Erlang cho phép chúng ta tự định nghĩa cách xử lý các lỗi liên quan tới module loading. Bạn có thể tạo một module implement các callback cần thiết của :error_handler, sau đó thay đổi biến cờ :error_handler. Bạn nào code Ruby có thể tưởng tượng nó hao hao method_missing (mặc dù không phải vậy).
Bạn có thể thử chơi với :error_handler trên IEx hoặc production tùy theo nồng độ liều trong máu bạn cao hay không:
iex(1)> defmoduleFooHandlerdo
...(1)> defundefined_function(mod, fun, args) do
...(1)> IO.puts("Could not find " <> inspect({mod, fun, args}))
...(1)> :error_handler.undefined_function(mod, fun, args)
...(1)> end
...(1)> end
iex(2)> :erlang.process_flag(:error_handler, FooHandler)
:error_handler
iex(3)> ABC.foo()
Could not find {ABC, :foo, []}
Could not find {Exception, :blame...}
Could not find {ErlangError, :normalize ...}
** (UndefinedFunctionError) function ABC.foo/0 is undefined (module ABC is not available)
ABC.foo()
Vậy error handler liên quan gì đến điều mà ta đang nói tới? Ở ví dụ đó, ngẫu nhiên 2 trường hợp có khả năng xảy ra:
HeavyComputation được biên dịch trước, trường hợp này thì không có gì đáng bàn.
Foo được biên dịch trước. Biên tới khúc gọi hàm thì nó phát hiện HeavyComputation không tồn tại (nhờ error handler). Nó sẽ tạm dừng lại, spawn ra một process khác để biên dịch module đang thiếu. Sau khi biên dịch HeavyComputation xong, Foo sẽ tiếp tục được biên dịch.
Về cơ bản thì cách này chạy được. Cơ mà spawn process vô tội vạ thì hay bị dính họa vào thân. Hơn nữa còn dễ xảy ra deadlock. Giả sử Foo và HeavyComputation có compile-time dependency lên lẫn nhau, HeavyComputation sẽ tiếp tục đẻ ra Foo, Foo lại đẻ ra HeavyComputation. Tốc độ lây lan nhanh như con virus Vũ Hán.
Process ở đây có thể hiểu nôm na là lightweight thread (mặc dù không hẳn vậy) trong Erlang VM. Ta có thể spawn hàng triệu process như thế. Bạn đọc có thể xem bài Elixir/Erlang, Actors model và Concurrency nếu muốn hiểu thêm.
Vì thế, ta cần phải có một con coordinator đứng ra làm nhiệm vụ điều tiết, với một số yêu cầu sau:
Các file source code không được sắp xếp theo một thứ tự nào cả.
Khi bạn có dependency graph kiểu A -> B, B -> C, C -> A, bạn có một cái cyclic deadlock. Coordinator phải detect được deadlock.
Coordinator sẽ spawn ra compiler process cho từng file, cho phép biên dịch nhiều file song song.
Tuy nhiên, khả năng xử lý song song của bạn bằng với số lượng online scheduler mà bạn có (nôm na là CPU cores). Có spawn hàng triệu task thì máy tính của bạn cũng không làm được hơn thế. Thậm chí nó còn làm giảm hiệu năng bởi vì scheduler phải tốn thêm công điều tiết.
Thuật toán xử lý của coordinator không phức tạp chút nào, có thể tóm gọn lại như sau:
Coordinator spawn ra một compiler process riêng cho mỗi file, duy trì số lượng process theo ý muốn bằng cách giữ một biến counter.
Mỗi con compiler này sẽ biên dịch file của nó. Nếu trong compile-time dependency Y trong file X chưa tồn tại, X sẽ dừng lại, nói cho coordinator biết nó đang đợi module Y, rồi khoanh tay đứng yên không làm gì cả.
Coordinator ghi nhận X -> Y (X đợi Y) vào trong waiting list của mình, rồi tiếp tục đẻ ra compiler process cho file tiếp theo trong danh sách.
Khi Y được biên dịch xong, coordinator sẽ báo cho X để X tiếp tục biên dịch.
Ví dụ
Tui hy vọng tới khúc này bạn đã hiểu. Nếu chưa thì bạn thể theo dõi ví dụ sau:
Cho một gia đình Quần Cam. Quần Cam phụ thuộc vào Cha và Mẹ, Cha và Mẹ phụ thuộc vào Cha và Mẹ của họ.
Bắt đầu với CODE server rỗng (chưa có module nào được load/compile). QUEUE chứa danh sách file cần biên dịch với thứ tự ngẫu nhiên. Coordinator duy trì mức 2 task song song.
CODE []
QUẦN CAM
/ \
CHA MẸ
/ \ / \
CHA CHA MẸ CHA CHA MẸ MẸ MẸ
QUEUE [CHA CHA, CHA, QUẦN CAM, MẸ, MẸ MẸ, MẸ CHA, CHA MẸ]
WAITING []
2 file đầu tiên là CHA CHA và CHA được đưa vào biên dịch.
Nói một cách ngắn gọn nhất, để bạn dễ nhớ thì hãy nhớ đến tên đầy đủ của từng thằng để hình dung công dụng của nó
npm viết tắt cho Node Package Manager
npx viết tắt cho Node Package eXecute
Một thằng dùng để quản lý package, thằng còn lại để thực thi package.
NPM là gì?
NPM là bộ quản lý package (như bộ giao thông vận tải, bộ giáo dục đào tạo) chính thức của Node.js, khi bạn cài Node.js là bạn được tặng kèm không thu giá một bộ command-line (câu lệnh để bạn gõ cọc cọc trong terminal) cũng tên là npm
Nó là một kho lưu trữ trực tuyến để xuất bản các dự án Node.js mã nguồn mở. NPM còn là một công cụ CLI hỗ trợ bạn cài đặt các gói đó và quản lý các phiên bản và phần phụ thuộc của chúng. Có hàng trăm nghìn thư viện và ứng dụng Node.js trên npm và nhiều thư viện khác được thêm vào mỗi ngày.
npm tự nó không chạy package. Nếu bạn muốn chạy package sử dụng npm, bạn phải chỉ định gói đó trong package.jsontệp của mình .
Khi các tệp thực thi được cài đặt thông qua các gói npm, npm sẽ tạo liên kết đến chúng:
cài đặt cục bộ có liên kết được tạo tại ./node_modules/.bin/thư mục
cài đặt toàn cầu có các liên kết được tạo từ bin/thư mục chung (ví dụ: /usr/local/bintrên Linux hoặc tại %AppData%/npmtrên Windows)
Để thực thi một gói với npm, bạn phải nhập đường dẫn cục bộ, như sau:
$ ./node_modules/.bin/your-package
hoặc bạn có thể chạy một gói được cài đặt cục bộ bằng cách thêm nó vào package.jsontệp của bạn trong phần tập lệnh, như sau:
NPX, được trình làng từ Node.js 5.2.0 (nghĩa là hiện tại bạn sẽ luôn có npx song song với npm, vì cái thời 5.2.0 là nó là thời mình còn cởi truồng tắm mưa rồi) được dùng để thực thi bất kỳ package nào có trên trang https://www.npmjs.com/ mà không cần cài đặt nó trước đó, bạn chỉ chạy nó thôi (tức nhiên nếu nó chạy được)
npx cũng là một công cụ CLI có mục đích là giúp dễ dàng cài đặt và quản lý các phần phụ thuộc được lưu trữ trong sổ đăng ký npm.
Giờ đây, rất dễ dàng để chạy bất kỳ loại tệp thực thi nào dựa trên Node.js mà bạn thường cài đặt qua npm.
Bạn có thể chạy lệnh sau để xem nó đã được cài đặt cho phiên bản npm hiện tại của bạn chưa:
$ which npx
Nếu không, bạn có thể cài đặt nó như sau:
$ npminstall -g npx
Sau khi chắc chắn rằng bạn đã cài đặt nó, hãy cùng xem một vài trường hợp sử dụng khiến npx trở nên cực kỳ hữu ích.
Chạy một gói được cài đặt cục bộ một cách dễ dàng
Nếu bạn muốn thực thi một gói được cài đặt cục bộ, tất cả những gì bạn cần làm là nhập:
$ npx your-package
npx sẽ kiểm tra xem có <command>hoặc <package>tồn tại trong $PATHhoặc trong tệp nhị phân dự án cục bộ hay không và nếu có thì nó sẽ thực thi.
Thực thi các gói chưa được cài đặt trước đó
Một ưu điểm lớn khác là khả năng thực thi một gói chưa được cài đặt trước đó.
Hãy kiểm tra điều này bằng cách chạy:
$ npx cowsay wow
Điều này thật tuyệt vời vì đôi khi bạn chỉ muốn sử dụng một số công cụ CLI nhưng bạn không muốn cài đặt chúng trên toàn cầu chỉ để kiểm tra chúng.
Điều này có nghĩa là bạn có thể tiết kiệm một số dung lượng ổ đĩa và chỉ chạy chúng khi bạn cần. Điều này cũng có nghĩa là các biến toàn cục của bạn sẽ ít bị ô nhiễm hơn.
Chạy mã trực tiếp từ GitHub
Bạn có thể sử dụng npx để chạy bất kỳ lưu trữ và kho lưu trữ GitHub nào. Hãy tập trung vào việc thực thi ý chính GitHub vì việc tạo một ý chính dễ dàng hơn.
Tập lệnh cơ bản nhất bao gồm tệp JS chính và a package.json. Sau khi bạn đã thiết lập các tệp, tất cả những gì bạn phải làm là chạy npx với liên kết đến ý chính như thể hiện trong hình trên
Ví dụ cho dễ hiểu nhé, trên tài liệu của create-react-app người ta sẽ hướng dẫn bạn chạy lệnh
npx create-react-app my-app
Bạn không cần cài create-react-app (bản thân nó là một package Node.js), mà chỉ thực thi nó để init source code
Để trở thành lập trình viên thì chúng ta phải học code và những môn bổ trợ. Để trở thành lập trình viên giỏi thì ta cần phải biết nhiều thứ khác nhau, debug cũng là một thứ mà một lập trình viên giỏi nhất định phải thành thạo.
Trước khi khi học ở trường đại học thì tôi không biết về nó nên khi đi làm thì tôi gặp rất nhiều khó khăn, vì vậy tôi viết bài này chia sẻ về debug, hy vọng sẽ giúp các bạn nhiều hơn về con đường lập trình.
Debug là một công cụ gỡ lỗi mà một ngôn ngữ lập trình nào cũng phải có, nói đến debug thì mọi người sẽ nghĩ đến chương trình bị lỗi thì sẽ sử dụng công cụ này để tìm lỗi, tuy nhiên đó chỉ là một phần đúng mà thôi. Ngoài chức năng gỡ lỗi của nó thì nó còn cho chúng ta biết những thứ khác, những thứ đó là gì thì chúng ta cùng tìm hiểu các ví dụ thực tế nhé.
2. Debug trong ngôn ngữ javascript
Để hiểu về debug thì bạn cần biết được bốn thứ quan trọng đó là: breakpoint, step over, step into, watch.
2.1 Breakpoint là gì?
Breakpoints đó là điểm dừng, bất kể bạn làm việc trên javascript hay bất kỳ một ngôn ngữ nào khác cũng đều có breakpoints, khi bạn debug thì cần đặt một điểm dừng ở trong source code, nơi mà bạn đang nghi ngờ chỗ đó phát sinh bug.
Quan sát hình bên trên, vùng khoanh màu đỏ (dòng 8) thì tôi có đặt một breakpoints, khi chương trình của tôi chạy tới dòng 8 thì tự động chương trình sẽ dừng lại và không chạy tiếp cho đến khi tôi tác động.
2.2 Step over là gì?
Step over là di chuyển xuống một dòng, sau vị trí đặt breakpoints
Quan sát hình bên trên thì ta thấy vị trí ban đầu đã di chuyển xuống dòng 9, còn breakpoints của dòng 8 đã đặt trước đó thì vẫn sẽ giữ nguyên như cũ để cho lần chạy tiếp theo.
2.3 Step into là gì?
Step into là di chuyển vị trí debug vào trong function con, bạn hãy nhìn hình bên trên sẽ thấy function getLocalStorage(). Step into sẽ di chuyển debug vào hàm này.
2.4 Watch là gì?
Watch là nơi mà hiển thị các thông tin của biến, giá trị trả về của function, để chúng ta xem và phán đoán bug, đồng thời có thể đưa ra được cách giải quyết cái bug của mình.
Quan sát hình bên trên thì tôi có thể xem được các dữ liệu của biến key truyền vào function getLocalStorage(key) là gì. Và kết quả trả về của getLocalStorage là gì.
2.5 Cách debug trong javascript
Để debug javascript thì tôi sẽ dùng công cụ developer tool của google chrome. Để mở công cụ này lên thì nhấn F12 thôi, khá là đơn giản, khi đó giao diện của bạn sẽ như thế này.
Khi mở lên thì chọn tab Source, nơi đây sẽ chứa những file html, js, css, image dự án của bạn.
2.5.1 Đặt một breakpoints
Để đặt một điểm dừng cho debug thì tôi sẽ nhấn chuột trái vào vùng khoanh màu đỏ.
2.5.2 Step over
Để di chuyển sang dòng tiếp theo thì nhấn F10, hoặc nút được khoanh màu đỏ hình ở bên dưới.
2.5.3 Step into
Để di chuyển vào trong hàm con của getLocalStorage thì nhấn F11, hoặc phấn vào nút được khoanh màu đỏ ở hình bên dưới.
2.5.4 Watch
Để xem dữ liệu của các kiến hay giá trị trả về thì bôi đen giá trị muốn xem và nhấn chuột phải tại giá trị đó và chọn “Add selected text to watches”.
Nhấn F8 để nhảy đến vị trí đặt breakpoints kế tiếp, nếu không có vị trí đặt breakpoints kế tiếp thì chương trình sẽ tiếp tục chạy.
Trên đây là những cái cơ bản nhất của debug, có thể các bạn xem xong phần này nhưng vẫn sẽ thắc mắc vì chưa hình dung được khi vào dự án thực tế thì bug sẽ như thế nào, cách giải quyết ra sao. Nếu bạn thắc mắc như vậy thì đó là điều hiển nhiên, vì bài này tôi viết chỉ ở mức cơ bản, tiếp cận về debug mà thôi, ở bài viết sau tôi sẽ viết những bài nâng cao hơn, tôi sẽ tự đặt ra những ví dụ thực tế về những cái mà tôi đã gặp phải và cách giải quyết chúng. Lúc đó bạn sẽ hiểu rõ thêm về sức mạnh của debug là gì.
Để thành công trong sự nghiệp, bạn cần nắm được những yếu tố cốt lõi mà nhà tuyển dụng muốn khai thác ở một ứng viên. Vậy bạn đã từng nghe về Tư duy cầu tiến (Growth Mindset) chưa? Đó được xem là bí quyết giúp bạn chinh phục những nhà tuyển dụng khó nhằn nhất. Cùng TopDev tìm hiểu về tư duy cầu tiến trong bài viết sau.
Tư duy cầu tiến là gì?
Tư duy cầu tiến – Growth Mindsetđược mô tả trên nền tảng về niềm tin của một cá nhân khi họ đủ nhận thức bản thân có thể học hỏi và cải thiện năng lực.
Sự tự nhận thức ấy được phản ánh qua những biểu hiện về sự nỗ lực và cách họ vượt qua những thất bại. Hoặc bao quát hơn, tư duy cầu tiến được bộc lộ thông qua thái độ của mỗi người. Tức là cách bạn đối đầu với thách thức ở những mức độ như thế nào.
Khác với những người có lối tư duy bảo thủ, người có tư duy cầu tiến luôn tiếp nhận những thất bại. Trong họ tràn đầy tinh thần học hỏi. Họ chấp nhận những sai lầm để nhận ra các bài học giá trị. Họ xem đó là từng nấc thang cao hơn, từng cơ hội lớn hơn để bản thân chinh phục và thử sức.
Đó là lý do tại sao họ luôn tự trau dồi, phát triển bản thân một cách nhanh chóng. Đơn giản, họ đón nhận thất bại bằng một niềm vui tích cực. Đồng thời, tự nhận ra những điểm yếu và sẵn sàng trải nghiệm cái mới.
Ghi điểm với nhà tuyển dụng với cách thiết lập tư duy cầu tiến hiệu quả
Ngoài chuyên môn, bạn cần thể hiện cho nhà tuyển dụng thấy tố chất về tư duy cầu tiến. Thái độ chính là tiêu chí quyết định đến sự thành công của bạn.
“I can do it!” – Từ suy nghĩ đến hành động tích cực
Mọi hành động của bạn đều có quá trình. Tất nhiên, nó sẽ chi phối mạnh mẽ khi bạn nhận thức, suy nghĩ, thể hiện năng lượng trí tuệ cảm xúc về một vấn đề nào đó. Vì thế, nếu trở nên vô vọng trước những thách thức, đó là một điều đáng tiếc.
Đừng đánh mất đi cơ hội. Hãy giữ cho mình một tư duy cầu tiến. Cụ thể là thái độ thích nghi, lắng nghe và chấp nhận đối mặt với các thử thách. Hãy bình tĩnh, ngẫm lại những gì đã diễn ra để nhận ta đâu là lỗ hỏng. Từ đó, bạn biết được những giải pháp nào sẽ phù hợp và mang lại hiệu quả cao nhất.
Bạn có biết rằng Walt Disney đã từng bị đuổi khỏi tòa soạn the Kansas City Star với lý do thiếu sáng tạo về mặt ý tưởng”. Do vậy, hãy luôn tâm niệm: “I can do it!”. – Tôi có thể làm được. Suy nghĩ ấy tạo ra một động lớn thúc đẩy bạn tiếp tục cố gắng. Thế nhưng, nếu bạn cứ duy trì những suy nghĩ bảo thủ, bạn sẽ mãi chậm chân tại chỗ, không thể có những bước tiến xa hơn.
Những người cầu tiến họ không ngại thử thách. Chắc chắn, sẽ khó tránh khỏi những nỗi sợ khác nhau phát sinh từ công việc. Lượng công việc quá lớn tạo ra áp lực đối với họ. Và để không cảm thấy mất kiểm soát trong việc giải quyết công việc thì bạn nên lập kế hoạch thực hiện mục tiêu.
Mỗi mục tiêu đề ra phải tương ứng với các đầu nhiệm vụ. Chúng cần được phân chia hợp lý theo trình tự logic. Từ đó, bạn dễ dàng xử lý công việc đồng thời đảm bảo việc thực hiện đang đi đúng quỹ đạo; tránh làm phát sinh những rủi ro.
Khi đạt hiệu quả, bạn sẽ có động lực để cố gắng hoàn thành các nhiệm vụ tiếp theo. Kế hoạch nên được cập nhật theo ngày, tháng, quý để tiện cho việc theo dõi, đánh giá cả quá trình.
Trở thành một phiên bản tốt hơn mỗi ngày
Đây là điều quan trọng bạn cần lưu tâm để rèn luyện tư duy cầu tiến.
Những cá nhân Growth Mindset họ thường đặt ra chỉ tiêu bản thân phải tiến bộ hơn mỗi ngày. Dù chỉ là 1 hay 2% nhưng mọi sự thay đổi đều có giá trị. Họ nhận ra nhiều sự khác biệt nhỏ được nảy sinh từ những cố gắng.
Nỗ lực đôi khi không phải cái bạn muốn là có được. Có những người họ phải trải qua những khó khăn; có quá trình tự nhìn nhận để tạo động lực cho bản thân cố gắng. Thế nhưng, nếu muốn rèn luyện tư duy cầu tiến, bạn cần chủ động trong việc thực hiện các nỗ lực. Dù cho bạn nghĩ rằng bạn đang đạt được giới hạn của sự hoàn hảo, bạn vẫn phải cố gắng. Hãy là một phiên bản tốt hơn mỗi ngày; không ngừng học hỏi và nâng cao những trải nghiệm!
Đúc kết những kinh nghiệm từ thực tế
Để rèn luyện tư duy cầu tiến, bạn phải góp nhặt nững kinh nghiệm từ những lần thất bại.Thất bại không đồng nghĩa với sự thua cuộc.
Bạn có thể học hỏi và trưởng thành, tiến bộ lên rất nhiều nếu ghi nhận những phản hồi. Và quá trình ngẫm lại những điểm thiếu sót của bản thân để quyết tâm thay đổi. Mỗi kinh nghiệm đều có giá trị riêng của nó. Và như đã nói từ trước, thái độ chính là sự phản ánh chân thật nhất của tư duy cầu tiến.
Với một thái độ tốt, bạn tự đánh giá lại bản thân đồng thời tiếp tục nỗ lực trau dồi. Ngược lại, với một thái độ không tích cực, thiếu sự cầu thị trong công việc, bạn nhất định sẽ không có một bước tiến lớn nào trong sự nghiệp phát triển của bản thân.
Nhà tuyển dụng họ đánh giá rất cao những ứng viên có thể chia sẻ về các trải nhiệm của bản thân. Không phải ai cũng có thể tự đánh giá và mô tả và chia sẻ những trải nghiệm ấy với người khác. Nếu bạn làm được điều đó, bạn là người sở hữu tư duy cầu tiến rồi, hãy cứ phát huy nhé!
Lời kết
Nếu xét về mặt phát triển cá nhân, Tư duy cầu tiến – Growth Mindest giúp kích thích lối tri nhận, phát triển tối đa năng lực trong tiềm năng giới hạn của bạn hoặc hơn thế. Hãy rèn luyện cho bản thân mình một tư duy cầu tiến. Nhớ rằng cầu tiến không có nghĩa là bất chấp mọi thỉ đoạn để đạt được mục đích. Một người thật sự hiểu về tư duy cầu tiến sẽ không bao giờ để mình lạc vào những phạm vị tiêu cực có thể diễn ra.