Credit https://github.com/mdecrevoisier/Windows-auditing-mindmap

Tổng công trình sư máy tính | Kiến trúc sư trưởng máy tính | Chuyên gia máy tính
An ninh thiết bị mạng
Điều tra số trên mạng
An ninh Hệ điều hành
Kiến thức cơ bản
IoT
An ninh Smart devices
updating…

Nhân đọc Tản mạn về sở hữu trí tuệ lậu ở Blog Khoa Học Máy Tính, tôi muốn chia sẻ cách làm thế nào để vẫn cập nhật được kiến thức mới mà không cần xài e-book lậu, hay tốn quá nhiều tiền để mua sách xịn. Nó chỉ vỏn vẹn có 4 bước:
Ở bài viết này ilook sẽ hướng dẫn các Phát triển Blockchain thông qua ngôn ngữ PHP. Hy vọng bài viết sẽ ít nhiều nắm bắt và thực hiện được công nghệ blockchain

Blockchain hiện nay đang là xu hướng mới, đi đến đâu cũng blockchain, và hầu hết 1 số hội thảo công nghệ thì chủ đề blockchain luôn được nhiều các bạn lập trình viên cũng như các nhà quản lý doanh nghiệp đều quan tâm đến, ở bài viết này mình sẽ hướng dẫn các bạn viết 1 blockchain trong php.
Mình sẽ lướt qua khái niệm về blockchain theo cách mình hiểu 1 chút, để bạn nào chưa biết thì có thể hiểu qua về nó và bạn nào biết rồi thì cũng có thể đóng góp ý kiến của các bạn,
Vậy, đầu tiên blockchain là gì ? mà sao đi đâu cũng thấy nhắc đến blockchain? blockchain ra đời khi nào ? Blockchain dùng để làm gì? ứng dụng vào những cái việc gì? nghe thoáng qua ở đâu nói rằng blockchain là bitcoin, hô hố, có phải không nhỉ ?
Bạn tạo 1 thư mục blockchain trong thư mục webservice của bạn nhé, và tạo luôn 1 file index.php để chúng ta viết code trong đó nhé:
Ban đầu chúng ta sẽ khởi tạo 1 class có tên là Block, Class này sẽ làm nhiệm vụ mã hóa toàn bộ dữ liệu vào thành 1 chuỗi khóa, đoạn code sẽ như sau:
Class Block{
public $index; // biến này là index key của 1 block dữ liệu, ở ví dụ này của mình, mình sẽ dùng nó là index, nhưng nếu chúng ta áp dụng thực tế, thì chúng ta có thể coi nó như 1 khóa chính, 1 transaction id, để định danh cho 1 block dữ liệu
public $previousHash; // biến này này hash của block trước block này
public $timeHash; // biến này là thời gian mã hóa của block này
public $data; // biến này là data của block này
public $hash; // biến này chính là hash của block này
public function __construct($index = 0, $previousHash = '', $timeHash = '', $data = '')
{
$this->index = $index;
$this->previousHash = $previousHash;
$this->timeHash = $timeHash;
$this->data = $data;
$this->hash = $this->execHash();
}
public function execHash()
{
if(is_array($this->data))
{
$data_content = json_encode($this->data);
}else{
$data_content = $this->data;
}
return hash('sha256', $this->index.$this->previousHash.$this->timeHash.$data_content);
}
}
Chúng ta chuyển sang tạo Class Blockchain như sau:
Class BlockChain extends Block{
public $chain = array();
public function __construct()
{
}
}
Class Blockchain này sẽ thực hiện các chức năng như tạo mới 1 block, check xem blockchain này có bị chỉnh sửa hay chưa ?
Như bên trên các bạn cũng thấy, mình khởi tạo 1 class có tên Blockchian và thừa kế lại class Block bên trên, trong class Blockchain này hiện chưa có gì ngoài biến $chain đang được khai báo public và 1 hàm __construct(), việc tiếp theo chúng ta sẽ làm là tạo 1 hàm có chức năng khởi tạo block ban đầu, block ban đầu này cũng khá quan trọng, nó là 1 block ban đầu tạo ra hash, các block sau đó sẽ lấy hashkey của block này để thực hiện việc mã hóa của mình, vậy mình sẽ tạo hàm này trong class Blockchain
public function createGenesisBlock()
{
return new Block(0,'hash_dau_tien', time(), 'data');
}
Tiếp theo chúng ta sẽ gọi hàm này trong hàm __construct để khi new Blockchain thì hàm createGenesisBlock sẽ được tự động gọi vào
Class BlockChain extends Block{
public $chain = array();
public function __construct()
{
$this->chain[] = $this->createGenesisBlock();
}
}
Tiếp theo chúng ta tạo 1 hàm có tên getLatestBlock, hàm này sẽ có nhiệm vụ get ra block cuối cùng trong blockchain, và hàm này có nội dung như sau:
private function getLatestBlock()
{
return $this->chain[(count($this->chain) - 1)];
}
Hàm này thì đơn giản rồi nên mình sẽ không giải thích thêm về hàm này và đi vào viết 1 hàm tiếp theo, hàm này vô cùng quan trọng, hàm này sẽ giúp chúng ta thêm vào block những dữ liệu mới
public function addaBlock($index, $timeHash, $data)
{
$previousHash = $this->getLatestBlock()->hash;
$this->chain[] = new Block($index, $previousHash, $timeHash, $data);
}
Ở hàm này, mình phải lấy ra được hash của block trước, lấy nó để làm gì ạ? thưa rằng bạn nhìn dòng thứ 2 trong hàm này bạn sẽ thấy Class Block cần truyền vào 1 biến có tên $previousHash, biến này khi thực hiện hash nó sẽ giống như 1 key trong hash, sau này cái $previousHash nó cũng là 1 thành phần để nói rằng block này có hợp lệ không ? block này có bị chỉnh sửa không ?
Okie, có vẻ gần hoàn chỉnh rồi, chúng ra review lại class BlockChain 1 chút nhé
Class BlockChain extends Block{
public $chain = array();
public function __construct()
{
$this->chain[] = $this->createGenesisBlock();
}
public function createGenesisBlock()
{
return new Block(0,'hash_dau_tien', time(), 'data');
}
private function getLatestBlock()
{
return $this->chain[(count($this->chain) - 1)];
}
public function addaBlock($index, $timeHash, $data)
{
$previousHash = $this->getLatestBlock()->hash;
$this->chain[] = new Block($index, $previousHash, $timeHash, $data);
}
}
Tổng cả class Block bên trên chúng ta sẽ có một code cơ bản và hoàn chỉnh
<?php
Class Block{
public $index;
public $previousHash;
public $timeHash;
public $data;
public $hash;
public function __construct($index = 0, $previousHash = '', $timeHash = '', $data = '')
{
$this->index = $index;
$this->previousHash = $previousHash;
$this->timeHash = $timeHash;
$this->data = $data;
$this->hash = $this->execHash();
}
public function execHash()
{
if(is_array($this->data))
{
$data_content = json_encode($this->data);
}else{
$data_content = $this->data;
}
return hash('sha256', $this->index.$this->previousHash.$this->timeHash.$data_content);
}
}
Class BlockChain extends Block{
public $chain = array();
public function __construct()
{
$this->chain[] = $this->createGenesisBlock();
}
public function createGenesisBlock()
{
return new Block(0,'hash_dau_tien', time(), 'data');
}
private function getLatestBlock()
{
return $this->chain[(count($this->chain) - 1)];
}
public function addaBlock($index, $timeHash, $data)
{
$previousHash = $this->getLatestBlock()->hash;
$this->chain[] = new Block($index, $previousHash, $timeHash, $data);
}
}
Chúng ta sẽ thêm đoạn này vào cuối file index.php và chạy thử nó nhé
$bl = new BlockChain();
$bl->addaBlock(1,time(), 'Data thứ 2');
$bl->addaBlock(2,time(), 'Data thứ 3');
$bl->addaBlock(3,time(), 'Data thứ 4');
Sau khi chạy, chúng ta sẽ có kết quả như sau:
BlockChain Object
(
[chain] => Array
(
[0] => Block Object
(
[index] => 0
[previousHash] => ma_chuoi_dau_tien
[timeHash] => 1530436111
[data] => data cua toi can tao
[hash] => 1067948d9484bb8bf7dcf5a625db12521e8a4f395861dd93b0025aa7714417c6
)
[1] => Block Object
(
[index] => 1
[previousHash] => 1067948d9484bb8bf7dcf5a625db12521e8a4f395861dd93b0025aa7714417c6
[timeHash] => 1530436111
[data] => Data thứ 2
[hash] => 3f4752159b07a36c2bef5feeda6f4eb25a0472e08d9f3ed629ff9b4293a1a776
)
[2] => Block Object
(
[index] => 2
[previousHash] => 3f4752159b07a36c2bef5feeda6f4eb25a0472e08d9f3ed629ff9b4293a1a776
[timeHash] => 1530436111
[data] => Array
(
[transaction_id] => 12ewe1e12e12eqwd12e1
[content] => test
)
[hash] => be72872e39785b6ccaea102166d278e74ef10b9b7af066edead2a6107e6da27a
)
[3] => Block Object
(
[index] => 3
[previousHash] => be72872e39785b6ccaea102166d278e74ef10b9b7af066edead2a6107e6da27a
[timeHash] => 1530436111
[data] => Data thứ 4
[hash] => 46af491628171e95276986c996e3f5c155642411bfefc7936fc4688e1d088f98
)
)
)
Như vậy là chúng ta đã tạo ra được blockchain với php, thật quá đơn giản phải không các bạn, ở bài sau mình sẽ hướng dẫn các bạn việc kiểm tra xem 1 trong các block trong blockchain đã bị chỉnh sửa hay chưa ?
Thêm phát kết là bitcoin chỉ là 1 loại tiền sử dụng công nghệ blockchain, chứ bitcoin không phải là blockchain, không thể lấy bitcoin làm tên gọi cho blockchain, các bạn đừng nhầm lẫn nhé, ai đang nhầm lẫn thì sửa lại luôn nhé. Hẹn gặp các bạn ở các bài tiếp theo
Roadmap để trở thành 1 lập trình viên Web trong 2020
Bên dưới đây, bạn sẽ thấy 1 set biểu đồ chứng minh các hướng đi mà bạn có thể chọn. Và những công nghệ mà bạn sẽ muốn sử dụng để trở thành 1 front-end, back-end hay 1 chuyên gia devops để trở thành 1 lập trình viên Web. Mình đã làm những biểu đồ này cho 1 giáo sư cũ của mình. Người đã muốn chia sẻ cái gì đó với các sinh viên đại học của ông để cho họ viễn cảnh, ngoài ra tôi còn chia sẻ chúng ở đây để giúp đỡ cộng đồng.
Những roadmap này bao gồm mọi thứ để học hỏi cho các hướng đi được ghi bên dưới. Khoan hãy bị choáng ngộp, lúc bắt đầu bạn không cần phải học hết tất cả nếu bạn chỉ mới khởi động. Chúng mình đang làm về các phiên bản người mới bắt đầu cho roadmap này và sẽ xuất bản sớm, chỉ ngay sau khi chúng mình đã xuất bản xong roadmap cho Back-end và DevOps 2020.
Nếu bạn nghĩ có thể cải tiến những điều này, hãy cứ đề xuất nhé.


Cách trở thành 1 Kỹ sư Phần mềm thực tập chỉ với 4 tháng tự học


Nếu bạn nghĩ bất kì roadmap nào có thể phát triển. Cứ thoải mái tranh luận các vấn đề về nó.
TopDev via GitHub và roadmap.sh
Ngành lập trình web hiện nay đã khác trước rất nhiều, nó trở nên khó khăn hơn cho những người mới bước vào ngành. Đó cũng là một trong những lý do chúng tôi quyết định làm một bài hướng dẫn từng bước qua hình ảnh về tình hình này và giải thích rõ hơn những cái bạn cần follow nếu dấn thân vào nghề, từ đó định hướng được lộ trình backend cho bản thân.
Trước đây, con đường đến với backend thật sự không có gì rõ ràng, rằng bạn nên theo cái gì, tập trung vào đâu. Chúng tôi sẽ sắp xếp lại bức tranh này từng bước rõ ràng để cho bạn một idea tốt hơn.
Để tự vẽ lộ trình backend cho bản thân, truớc hết hãy nắm vững khái niệm về backend là gì?

Bạn có thể xem full roadmap lộ trình backend trong ảnh dưới, sẽ có phần giải thích từng bước chi tiết ở bên dưới.

Trước khi bắt đầu với lộ trình backend, mặc dù chúng tôi chưa list ra các kiến thức về HTML/CSS trên roadmap trên, bạn cũng nên tự tìm hiểu và ít nhất đã nắm được cách viết HTML/CSS căn bản. FrontEnd là gì? BackEnd là gì ? và Fullstack là gì?
Có cả tá lựa chọn về ngôn ngữ dành cho bạn. Tôi có chia nhỏ nó ra các categories để bạn dễ lựa chọn hơn. Đối với những người mới thì tôi khuyên bạn nên chọn các ngôn ngữ scripting vì chúng có nhiều demand và cho phép bạn bắt kịp nhanh chóng. Nếu bạn có một ít kiến thức frontend, bạn sẽ thấy Node.js dễ hơn nhiều và có rất nhiều job về nó đang mở.
Nếu bạn đang làm backend và biết một số scripting language, tôi đề xuất không chọn một ngôn ngữ scripting language khác nữa mà chọn trong section “Functional” hoặc “Multiparadigm”. Ví dụ, nếu bạn đang làm PHP hoặc Mode.js, đừng nên chọn Python hoặc Ruby, mà hãy thử Erlang hoặc Golang. Nó sẽ giúp bạn tư duy xa hơn và open với những mảng khác hơn.
Học phải đi đôi với hành. Một khi bạn đã chọn được ngôn ngữ phù hợp và có được nền tảng căn bản về nó, hãy dùng nó ngay. Hãy tạo nên càng nhiều app nhỏ càng tốt. Dưới đây là một số gợi ý cho bạn:
Một khi đã học được những cái cơ bản của một ngôn ngữ và tại nên một vài app mẫu, hãy học cách dùng package manager ngôn ngữ đó. Các package manager sẽ giúp bạn dùng các thư viện ngoài và phân phối các thư viện cho người khác dùng.
Nếu bạn chọn PHP thì bạn có thể học về Composer, Node.js sẽ có NPM hoặc Yarn, Python có Pip và Ruby có RubyGems. Dù cho bạn chọn cái nào đi nữa, hãy cứ tiếp tục và học về package manager.
Mỗi ngôn ngữ có những tiêu chuẩn riêng và best practices (cách làm tốt nhất). Hãy tìm ra và học hỏi từ nó. Ví dụ, PHP có PHP-FIG và PSRs. Với Node.js sẽ có rất nhiều hướng dẫn phục vụ cộng đồng cũng như nhiều ngôn ngữ khác.
Hãy nhớ đọc về các best practices trong mảng bảo mật. Đọc OWASPguidelines để hiểu về nhiều vấn đề bảo mật khác nhau và cách phòng tránh nó đối với từng ngôn ngữ mà bạn chọn.
Sau những nền tảng cơ bản, tiêu chuẩn và best practice, bảo mật cũng như cách dùng package manager, bây giờ là lúc tự tạo nên một package và phân phối nó đi cho người khác dùng, nhớ follow các tiêu chuẩn và best practices đã học. Ví dụ như, nếu bạn chọn PHP, bạn có thể release nó trên Packagist, còn nếu chọn Node.js thì release trên Npm registry,…
Sau khi đã xong, bạn có thể search thêm một số project trên Github và mở một số pull request trong các projects. Dưới đây là một vài gợi ý cho bạn:
Hiện có rất nhiều kiểu test, mục tiêu đó là phải hiểu rõ các loại này là gì. Nhưng trước mắt hãy cách viết Unit Test và Integration test cho app trước đã. Đồng thời hãy tìm hiểu thêm về các phương pháp testing như mocks, stubs,…
Hãy viết thử unit test cho một số task thực tế mà bạn đã làm, đặc biệt là những cái bạn đã làm ở Bước 6.
Đồng thời nhớ tính toán thử mức độ cover của các test đã viết.
Làm thế nào để bảo toàn data trên relational database (dữ liệu quan hệ). Trước khi bạn lựa chọn tool để học, hãy tìm hiểu trước về các phương pháp database terminologies khác nhau như các key, index, normalization, tuple, v.v
Có rất nhiều sự lựa chọn, tuy nhiên nếu bạn học một cái rồi, thì những cái còn lại sẽ trở nên dễ hơn. Một trong những cái lý tưởng để bắt đầu đó là MySQL, MariaDB (khá giống nhau và là một mảnh của MySQL) và PostgreSQL. Pick MySQL.
Bây giờ bạn sẽ đem tất cả những thứ bạn đã học ra để sử dụng. Tạo nên một ứng dụng đơn giản, bất cứ idea nào, ví dụ một ứng dụng viết blog, rồi áp dụng các feature dưới đây:
Tuỳ vào project và ngôn ngữ mà bạn chọn thì bạn có thể cần hoặc không cần đến framework. Mỗi ngôn ngữ có rất nhiều lựa chọn, hãy tìm hiểu và xem xem ngôn ngữ của bạn có gì và chọn một cái liên quan.
Nếu bạn chọn PHP, tôi đề xuất bạn nên dùng Laravel hoặc Symfony hoặc đối với các framework nhỏ thì bạn có thể dùng Lumen hoặc Slim. Nếu bạn chọn Node.js thì cũng có rất nhiều lựa chọn nhưng cái mạnh nhất đến nay đó là Express.js.
Để thực hành bước này, hãy convert app và bạn đã làm ở Bước 10 để áp dụng framework mình đã chọn. Nhớ port mọi thứ kể cả các test nhé.

Đầu tiên hãy tìm hiểu nó là cái gì, chúng khác dữ liệu quan hệ chỗ nào và tại sao cần dùng đến nó. Có rất nhiều sự lựa chọn, chỉ cần tìm kiếm một chút và so sánh các feature sẽ thấy được sự khác nhau. Một số option phổ biến gồm có MongoDB, Cassandra, RethinkDB và Couchbase. Nếu phải chọn một thì bạn nên chọn MongoDB.
Hãy tìm hiểu cách ứng dụng app level caching cho ứng dụng của mình. Hiểu được cách sử dụng mà bạn đã build ở Bước 12.
Tìm hiểu về REST và học cách tạo ra các RESTful API và nhớ đọc về REST trong bài viết gốc của Roy Fielding, để cứ hễ ai bảo REST chỉ dành cho HTTP API là bạn sẽ có thể sửa lưng họ ngay.
Bạn cần phải biết chúng là gì, sử dụng thế nào và cái này khác cái kia ở chỗ nào
Cũng có nhiều lựa chọn cho bạn nhưng có 2 cái nổi bật hơn đó là RabbitMQ và Kafka. Nếu phải chọn một thì nên hãy học RabbitMQ trước.
Khi app đã bắt đầu phát triển, các query đơn giản dù cho trên dữ liệu quan hệ hay dữ liệu NoSQL sẽ không từ cắt ra và bạn sẽ phải resort riêng công cụ search. Bạn nên cân nhắc tuỳ nhu cầu, vì có rất nhiều option và mỗi option đều có những điểm đặc biệt riêng.
Docker có thể giúp bạn rất nhiều trong quá trình lập trình ứng dụng, không chỉ tạo lặp một môi trường tương tự khi produce, giữ cho hệ điều hành luôn sạch sẽ hoặc thúc đẩy code, test và deploy. Tôi sẽ cho bạn một câu hỏi để tìm hiểu và tự trả lời cho mình “Nó sẽ giúp tôi bằng cách nào?”. Cứ thế hãy tìm hiểu và học cách dùng Docker.
Nếu đã đến bước này, bạn chắc chắn đã phải tiếp xúc với nhiều server. Lúc này chủ yếu bạn sẽ tìm điểm khác nhau giữa các web server, hiểu được những giới hạn và các configuration option có sẵn cũng như cách viết app để tối ưu hoá các giới hạn này.
Mặc dù không bắt buộc, có thêm kiến thức này có thể giúp ích cho bạn rất nhiều. Tìm hiểu xem cách viết web app real-time và một số app mẫu bằng web-socket, bạn có thể dùng nó trên blog application để ứng dụng các update real-time trên blog posts listing.
Hiểu rõ nó khác chỗ nào REST và tại sao lại gọi nó là REST 2.0.
Các Biểu đồ đồ thị sẽ giúp bạn linh hoạt hơn khi xử lý data, cũng như cung cấp cho bạn nguồn lưu trữ nhanh chóng và hiệu quả để dễ thu hồi hoặc query nó. Học thêm về Neo4j or OrientDB.
Một khi bạn đã bắt tay vào học và làm, chắc chắn bạn sẽ vấp phải thêm nhiều thứ mà chúng tôi chưa liệt kê hết trên đây. Hãy luôn ở trong tâm lý mở không ngại học cái mới, vì kết quả thế nào là do bạn chọn.
Đặc biệt một điều quan trọng nữa: Hãy thực hành càng nhiều càng tốt. Ban đầu trông nó sẽ hơi “ghê” và bạn dễ cảm thấy lạc trôi nhưng điều này là hoàn toàn bình thường, và luyện tập thường xuyên bạn sẽ dần quen với nó và lên tay nhanh thôi. Hy vọng bạn đã tự hình dùng được lộ trình backend cho riêng mình.
Bài viết gốc được đăng tải tại Medium
In general software architect is like the architect in real-life. Hes’s responsible for making high-level design decisions.
The objective of this document is giving an overview about the skills required by software engineers to level up and become a software architect. Still there’s no ideal skills required to be gained, but this is just a roadmap to be followed to highlight the main skills to be gained.
There’s no standard roadmap or specific methodology to follow to become an architect. Being a good architect is getting achieved by applying and implementing more than reading.
Below is a broadway roadmap that you can follow to start being a software architect.

Let’s define the 3 categories of software architects
Solution architect is mainly the one responsible for translating requirements into code. Sometimes we can call him the “project development team lead” for a specific project. He’s responsible for the following:
Solution architect would be guided by the “Enterprise architect”.
Application architect is the one responsible for the following:
Sometimes they choose one of the development team to be the application architect.
Enterprise architect is the very highly abstracted architect responsible for the following:
Cài đặt, chạy Apache Kafka, Apache Zookeeper trên windows
Trong bài này mình sẽ thực hiện cài đặt zookeeper và apache kafka sau đó tạo topics, producer và consumer để demo.
(Xem thêm: Code ví dụ Java Kafka consumer)
(Xem thêm: Code ví dụ Java Kafka producer)
Yêu cầu:
Máy bạn đã cài đặt và thiết lập biến môi trường Java (JRE/JDK)
(Xem lại: Cài đặt và thiết lập biến môi trường cho Java)
Download Zookeeper tại đây: zookeeper-3.4.12.tar.gz | http://zookeeper.apache.org/releases.html#download
Download Kafka tại đây: kafka_2.12-1.1.0.tgz | http://kafka.apache.org/downloads.html
(Xem lại: Zookeeper là gì?)
B1: Giải nén file zookeper tải về, ở đây mình giải nén ra thư mục C:\app\zookeeper-3.4.12
B2: Đổi tên file zoo_sample.cfg trong thư mục conf thành zoo.cfg (zookeeper sẽ sử dụng file zoo.cfg để config)

B3: Mở file zoo.cfg (có thể mở bằng notepad hoặc notepadd++) và sửa dataDir=/tmp/zookeeper thành dataDir=zookeeper-3.4.12/data
B4: Tạo biến môi trường cho zookeeper với


B5. Start zookeeper bằng cách mở màn hình cmd và gõ zkserver
Kết quả: (Port mặc định của zookeeper là 2181, bạn có thể đổi nó trong file zoo.cfg)

B1. Download và giải nén kafka, ở đây mình giải nén ra thư mục: C:\app\kafka_2.12-1.1.0
B2: Mở file “server.properties” trong thư mục config và sửa “log.dirs=/tmp/kafka-logs” thành “log.dirs=C:/app/kafka_2.12-1.1.0/kafka-logs”.

Sửa”zookeeper.connect=localhost:2181” thành địa chỉ mà server zookeeper chạy. Ở đây mình chạy trên local và dùng port mặc định cho zookeeper là 2181 nên mình giữ nguyên.
B3: Start apache kafka (phải start zookeeper trước đó). Port mặc định của kafka là 9092.
Mở màn hình cmd:

Ví dụ tạo topic với name = “test” (Phải chạy kafka server trước đó). Mở màn hình cmd và chạy các lệnh:
Tạo Producer: mở màn hình cmd mới và gõ lệnh:
Tạo Consumer: mở màn hình cmd mới và gõ lệnh:
Kết quả: trên màn hình cmd của producer gõ bất kì message gì thì màn hình cmd consumer đều nhận được

(Trên windows các file kafka-topics.bat, kafka-console-consumer.bat… sẽ nằm trong folder bin/windows; còn trên linux sẽ là các file .sh ở folder bin)
Okay, Done!
References:
1 Giới thiệu
Tôi nhận được thư từ của nhiều bạn hỏi về việc nên học gì và như thế nào để có thể tìm được việc làm và làm được việc trong ngành an toàn thông tin (information security). An toàn thông tin là một ngành rộng lớn với rất nhiều lĩnh vực. Những gì tôi biết và làm được chỉ gói gọn trong một hai lĩnh vực. Có rất nhiều mảng kiến thức cơ bản mà tôi không nắm vững và cũng có nhiều kỹ năng mà tôi không thạo. Hack tài khoản Yahoo! Mail là một trong số đó. Tôi cũng không biết cách tìm địa chỉ IP của bạn chat :-(.
Xét theo năm mức ngu dốt thì tôi nằm ở mức “1OI – thiếu kiến thức” ở hầu hết các lĩnh vực trong an toàn thông tin. Cũng có lĩnh vực tôi nằm ở mức “2OI – thiếu nhận thức”. Nhiều lần đọc sách vở hoặc nói chuyện với đồng nghiệp, tôi hay nhận ra rằng có nhiều thứ tôi không biết là tôi không biết. Theo ý của anh Ngô Quang Hưng thì đây là chuyện bình thường:
Dân máy tính thường phải đọc/học rất nhiều để theo kịp sự phát triển với tốc độ ánh sáng của ngành mình. Trong quá trình này, với mỗi vấn đề X của ngành, ta sẽ chuyển dần dần từ 3OI xuống 1OI. Sau đó, nếu X là cái mà ta thật sự thích hoặc cần cho công việc thì sẽ chuyển nó lên 0OI.
Rất nhiều sinh viên và nghiên cứu sinh KHMT ở mức 3OI khi mới bắt đầu đi học. Sau đó họ tìm hiểu về quá trình nghiên cứu, quá trình tìm các vấn đề và hướng nghiên cứu mới, quá trính cập nhật kiến thức về ngành của mình, và chuyển dần các thứ lên 2OI. Để có một quá trình hiệu quả từ 3OI lên 2OI không dễ chút nào. Ví dụ đơn giản: các journals, conference nào trong ngành mình là có giá trị, làm thế nào để tìm đọc các bài trong chúng, phương pháp lọc bài đọc thế nào, vân vân.
Tôi thấy anh Hưng nói có lý, nên mục tiêu chính của bài viết này là cung cấp một quá trình hiệu quả để bớt ngu về an toàn thông tin.
2 Làm an toàn thông tin là làm gì?
Tôi muốn viết phần này vì nhiều người tưởng tôi làm bảo vệ khi tôi nói tôi làm security. Ngoài ra có lẽ là do thị trường việc làm an toàn thông tin ở Việt Nam không phong phú nên hầu hết đều nghĩ rằng làm an toàn thông tin nghĩa là đảm bảo an toàn hệ thống mạng (network/system security), trong khi thực tế đây chỉ là một trong số rất nhiều công việc trong ngành.
Trong bốn phần nhỏ tiếp theo, tôi sẽ giới thiệu bốn nhóm công việc chính trong ngành. Đối với mỗi nhóm công việc, tôi sẽ bàn một chút về triển vọng nghề nghiệp ở Việt Nam và Mỹ, hai nơi mà tôi có dịp được quan sát. Nếu bạn không biết bạn thích làm gì thì cứ chọn một công việc rồi làm thử. Các công việc này đều có liên quan nhau, nên kiến thức mà bạn học được trong quá trình thử vẫn hữu ích cho những nghề khác.
2.1 An toàn sản phẩm (product security)
Công việc chính của nhóm này là làm việc với các đội phát triển sản phẩm để đảm bảo sản phẩm làm ra an toàn cho người dùng và an toàn cho hệ thống của công ty, cụ thể là:
Tóm gọn lại thì nhóm này chuyên tìm lỗ hổng và kỹ thuật tấn công mới. Đây là công việc của tôi và tôi thấy đây là công việc thú vị nhất trong ngành :-).
Ở Mỹ thì thông thường thì chỉ có các hãng có phần mềm và dịch vụ lớn như Facebook, Google, Microsoft, Oracle, v.v. hay các tập đoàn tài chính ngân hàng lớn mới có đội ngũ tại chỗ để đảm nhiệm công việc này. Các công ty nhỏ thường chỉ thuê dịch vụ của các công ty tư vấn. IBM và Big Four đều có cung cấp dịch vụ tư vấn này. Dẫu vậy nếu được chọn lựa thì tôi sẽ chọn làm cho các công ty chuyên sâu như Matasano, iSec, Leviathan, Gotham, IOActive, Immunity, v.v.
Ở Việt Nam thì thị trường việc làm cho người làm an toàn sản phẩm có vẻ ảm đạm hơn. Cho đến nay tôi biết chỉ có một vài công ty ở Việt Nam là có nhân viên chuyên trách lĩnh vực này. Các công ty khác (nếu có quan tâm đến an toàn thông tin) thì hầu như chỉ tập trung vào an toàn vận hành. Các công ty tư vấn an toàn thông tin ở Việt Nam cũng không tư vấn an toàn sản phẩm, mà chỉ tập trung tư vấn chung chung về các quy trình và tiêu chuẩn an toàn thông tin.
2.2 An toàn vận hành (operations security)
Công việc chính của nhóm này là đảm bảo sự an toàn cho toàn bộ hệ thống thông tin của doanh nghiệp, với ba nhiệm vụ chính:
Đây là công việc khó nhất, nhưng lại ít phần thưởng nhất của ngành an toàn thông tin.
Tương tự như trên, chỉ có các hãng lớn của Mỹ mới có đội ngũ tại chỗ để phụ trách toàn bộ khối lượng công việc đồ sộ này, nhất là mảng xử lý và điều tra. Đa số các công ty chỉ tập trung vào ngăn chặn và sử dụng dịch vụ của bên thứ ba cho hai mảng còn lại. Các hãng như Mandiant, Netwitness hay HBGary cung cấp dịch vụ điều tra các vụ xâm nhập và có rất nhiều hãng khác cung cấp dịch vụ giám sát an ninh mạng.
Ở Việt Nam thì thị trường việc làm cho người làm an toàn vận hành tương đối phong phú hơn so với an toàn sản phẩm. Các công ty và tổ chức tài chính lớn đều có một vài vị trí chuyên trách về an toàn vận hành. Đa số người làm về an toàn thông tin ở Việt Nam mà tôi biết là làm trong lĩnh vực này. Dẫu vậy hầu như chưa có ai và công ty tư vấn nào làm về phản hồi và điều tra sự cố.
2.3 Phát triển công cụ (applied security)
Công việc chính của nhóm này là phát triển và cung cấp các công cụ, dịch vụ và thư viện phần mềm có liên quan đến an toàn thông tin cho các nhóm phát triển sản phẩm sử dụng lại.
Nhóm này bao gồm các kỹ sư nhiều năm kinh nghiệm và có kiến thức vững chắc về an toàn thông tin, viết mã an toàn và mật mã học. Họ phát triển các thư viện và dịch vụ dùng chung như phân tích mã tĩnh – phân tích mã động (static – dynamic code analysis), hộp cát (sandboxing), xác thực (authentication), kiểm soát truy cập (authorization), mã hóa (encryption) và quản lý khóa (key management), v.v.
Đây là dạng công việc dành cho những ai đang viết phần mềm chuyên nghiệp và muốn chuyển qua làm về an toàn thông tin. Đây cũng là công việc của những người thích làm an toàn sản phẩm nhưng muốn tập trung vào việc xây dựng sản phẩm hơn là tìm lỗ hổng.
Rõ ràng loại công việc này chỉ xuất hiện ở các công ty phần mềm lớn. Ở các công ty phần mềm nhỏ hơn thì các kỹ sư phần mềm thường phải tự cáng đáng công việc này mà ít có sự hỗ trợ từ nguồn nào khác. Ở Việt Nam thì tôi không biết có ai làm dạng công việc này không.
2.4 Tìm diệt mã độc và các nguy cơ khác (threat analysis)
Ngoài an toàn sản phẩm ra thì đây là một lĩnh vực mà tôi muốn làm. Công việc chính của nhóm này là phân tích, truy tìm nguồn gốc và tiêu diệt tận gốc mã độc và các tấn công có chủ đích (targeted attack). Mã độc ở đây có thể là virút, sâu máy tính, hay mã khai thác các lỗ hổng đã biết hoặc chưa được biết đến mà phần mềm diệt virút thông thường chưa phát hiện được. Các loại mã độc này thường được sử dụng trong các tấn công có chủ đích vào doanh nghiệp.
Tôi nghĩ rằng sau hàng loạt vụ tấn công vừa rồi thì chắc hẳn các công ty lớn với nhiều tài sản trí tuệ giá trị đều muốn có những chuyên gia trong lĩnh vực này trong đội ngũ của họ. Ngoài ra các công ty chuyên về điều tra và xử lý sự cố như Mandiant, HBGary hay Netwitness mà tôi đề cập ở trên đều đang ăn nên làm ra và lúc nào cũng cần người. Các công ty sản xuất phần mềm diệt virút dĩ nhiên cũng là một lựa chọn.
Ở Việt Nam thì tôi nghĩ hầu hết doanh nghiệp vẫn chưa thấy được nguy cơ đến từ các cuộc tấn công có chủ đích, thành ra họ sẽ không tuyển người chuyên trách vấn đề này. Tôi cũng không biết có công ty tư vấn nào ở Việt Nam chuyên về điều tra và xử lý sự cố hay không. Tôi nghĩ lựa chọn khả dĩ nhất cho những người thích mảng công việc này là các công ty phần mềm diệt virút.
Tuy nhiên cũng cần lưu ý rằng trong vài năm gần đây ở Việt Nam còn xuất hiện những loại mã độc nhắm vào đông đảo người dùng máy tính bình thường. Vấn nạn này có lẽ sẽ còn kéo dài trong nhiều năm tới và lẽ đương nhiên “phe ta” lúc nào cũng cần thêm những chiến sĩ lành nghề như anh TQN. Thành ra dẫu triển vọng nghề nghiệp không sáng sủa cho lắm, nhưng tôi rất hi vọng sẽ ngày càng nhiều người tham gia vào việc phân tích các mã độc nhắm vào người dùng máy tính ở Việt Nam. Đối với tôi họ là những người hùng thầm lặng, chiến đấu đêm ngày với các “thế lực thù địch” để bảo vệ tất cả chúng ta.
3 Học như thế nào?
Đa số những bạn viết thư cho tôi đều đang học đại học ngành CNTT và tất cả đều than rằng chương trình học quá chán, không có những thứ mà các bạn muốn học. Tôi nghĩ đây là một ngộ nhận.
Hối tiếc lớn thứ nhì trong sự nghiệp học tập mấy chục năm của tôi là đã không học nghiêm túc khi còn là sinh viên (hối tiếc lớn nhất là tôi đã không nghỉ hẳn, nhưng đó là một câu chuyện dài khác). Tôi cũng đã nghĩ rằng chương trình học ở đại học là lạc hậu và không cần thiết. Bây giờ nhìn lại thì tôi thấy nội dung và cách dạy của từng môn học thì đúng là lạc hậu (chỉ có mấy môn triết học Mác-Lênin là bắt kịp ánh sáng thời đại), nhưng toàn bộ giáo trình đại học vẫn cung cấp được một cái sườn kiến thức rất cần thiết cho một kỹ sư an toàn thông tin.
Ở đại học người ta có cách tiếp cận top-down, nghĩa là dạy từ đầu đến cuối những kiến thức nằm trong chương trình. Điều này dễ dẫn đến tình trạng là người học phải học những kiến thức mà họ không thấy cần thiết. Nếu chương trình học cũ kỹ và không có nhiều thực hành, hoặc người dạy không chỉ ra được bức tranh toàn cảnh, vị trí hiện tại của người học và bước tiếp theo họ nên làm là gì thì người học sẽ dễ cảm thấy rằng họ đang phí thời gian học những kiến thức vô bổ.
Trong khi khi đi làm thì cách tiếp cận là bottom-up, nghĩa là lao vào làm, thấy thiếu kiến thức chỗ nào thì học để bù vào chỗ đó. Lúc này tôi hoàn toàn chủ động trong việc học và tôi cũng hiểu rõ tôi cần học cái gì và tại sao. Điều thú vị là mỗi khi truy ngược lại nguồn gốc của những kiến thức tôi cần phải có, tôi thường thấy chúng nằm trong chương trình đại học.
Ví dụ như tôi muốn luyện kỹ năng dịch ngược mã phần mềm (reverse code engineering – RCE) thì tôi thấy rằng tôi cần phải có kiến thức về tổ chức và cấu trúc máy tính. Hoặc nếu tôi muốn học về mật mã học thì tôi phải học lý thuyết tính toán, mà khởi nguồn là lý thuyết automata. Nhưng tại sao trước đó tôi cũng đi làm nhưng không thấy được những lỗ hổng kiến thức này? Tôi nghĩ là do tôi làm không đủ sâu. Ví dụ như nếu bạn suốt ngày chỉ lập trình PHP thì bạn sẽ không thể hiểu được tại sao phải nắm vững tổ chức và kiến trúc máy tính. Hoặc giả như công việc của bạn là sysadmin thì cũng sẽ rất khó để bạn thấy được tại sao cần phải học lý thuyết automata.
Những gì tôi nói lan man ở trên có thể tóm gọn lại thế này:
Các lớp mà tôi liệt kê trong phần 4 đa số là của đại học Stanford. Bạn không cần phải đến tận nơi, ngồi trong lớp mới có thể học được. Tôi thấy trong nhiều trường hợp thì bạn chỉ cần đọc lecture notes, sách giáo khoa mà lớp sử dụng rồi làm bài tập đầy đủ thì vẫn sẽ tiếp thu đủ kiến thức. Một số lớp mà tôi liệt kê dưới đây được dạy miễn phí rộng rãi trên Coursera.
Bạn có thể tham khảo chương trình SCPD nếu muốn học chung với các sinh viên Stanford khác. Đây là chương trình học từ xa thông qua video. Buổi sáng lớp diễn ra thì buổi chiều bạn đã có video để xem. Thi cử như các sinh viên chính quy khác và điểm phải trên B mới được học tiếp. Đây là chương trình mà tôi theo học. Điểm thú vị là mỗi học kỳ bạn chỉ cần lấy một lớp, nhưng Stanford vẫn sẽ cho bạn xem video của tất cả các lớp khác.
Ngoài Stanford và Coursera ra, bạn cũng có thể tham khảo các lớp trên Udacity, OCW và MITx. Khi tôi đang viết những dòng này thì MIT và Harvard công bố dự án edX. Chúng ta đang sống trong một thời đại cực kỳ thú vị! Bây giờ chỉ cần bạn chịu học thì muốn học cái gì cũng có lớp và học liệu miễn phí. Nhưng mà học cái gì bây giờ?
4 Học cái gì?
Có ba món quan trọng cần phải học: lập trình, lập trình và lập trình! Để làm việc được trong ngành này, bạn phải yêu thích lập trình. Không có cách nào khác. Thề luôn!
Tôi dành khá nhiều thời gian tìm hiểu giáo trình khoa học máy tính của các trường đại học lớn trên thế giới và tôi thấy tất cả các môn học đều có phần bài tập là lập trình. Học cái gì viết phần mềm cho cái đó. Học về hệ điều hành thì phần bài tập là viết một hệ điều hành. Học về mạng thì viết phần mềm giả lập router, switch hay firewall. Cá nhân tôi cũng thấy rằng lập trình là cách tốt nhất để tiếp thu kiến thức một môn học nào đó, biến nó thành của mình. Nói cách khác, lập trình là một cách mã hóa tri thức khá hiệu quả.
Ngoài ra nhìn vào mô tả công việc ở phần 2, bạn cũng có thể thấy kỹ năng lập trình quan trọng đến dường nào, bởi hầu hết các vấn đề và giải pháp của an toàn thông tin là đến từ phần mềm. Rõ ràng muốn tìm lỗi của phần mềm thì bạn phải hiểu được phần mềm thông qua mã nguồn trực tiếp hay trung gian của nó. Rất có thể bạn sẽ không phải lập trình hàng ngày, nhưng bạn phải viết được những công cụ nhỏ hay những thư viện hỗ trợ cho công việc và các lập trình viên khác.
Vậy làm thế nào để lập trình giỏi? Câu hỏi này làm tôi nhớ đến câu chuyện cười về ông lập trình viên không thể ra khỏi phòng tắm vì trên chai dầu gội có ghi hướng dẫn sử dụng là “cho vào tay, xoa lên đầu, xả nước và lập lại”. Từ khóa trong câu chuyện này là “lập lại”: muốn giỏi lập trình thì cách tốt nhất là lập trình nhiều vô!
Nhưng mà lập trình bằng ngôn ngữ gì bây giờ? Đây là câu hỏi dễ làm cho các lập trình viên oánh nhau nhất ;-). Cá nhân tôi thấy rằng người làm an toàn thông tin bây giờ cần phải thông thạo C, x86 Assembly, Python (hoặc Ruby) và JavaScript. Tôi có nói lý do tại sao trong phần giới thiệu sách tiếp theo.
Lập trình
Hệ điều hành
Mạng máy tính
Sau khi đã có những kiến thức cơ bản ở trên, bạn có thể theo đuổi lớp CS155. Lớp này có trên Coursera với tên Computer Security. Song song với lớp CS155, bạn có thể tìm đọc các sách sau:
Tìm lỗi phầm mềm
Dịch ngược mã phần mềm
Điều tra số (digital forensics)
Mật mã hóa
Chú ý đây là những cuốn sách tập trung vào công việc hàng ngày và sở thích của tôi — nói cách khác, còn thiếu nhiều sách của các mảng công việc khác. Dẫu vậy tôi nghĩ những cuốn sách này sẽ giúp bạn có được một kiến thức nền tảng vững chắc để từ đó theo đuổi các nghề nghiệp khác nhau trong ngành an toàn thông tin. Trong thời gian tới tôi sẽ cập nhật thêm những cuốn sách mà tôi đang và sẽ đọc. Nếu bạn biết sách nào hay thì hãy giới thiệu cho tôi.
Ngoài ra trong các sách mà tôi vừa liệt kê không có cuốn sách toán (và lý thuyết khoa học máy tính) nào cả. Tôi nghĩ bạn sẽ tự có câu trả lời cho câu hỏi “Có nên học toán hay không?” khi bắt đầu học mật mã. Về hai mảng này thì tôi rất thích lớp “Great Ideas in Theoretical Computer Science” của Scott Aaronson và cuốn “A Computational Introduction to Number Theory and Algebra” của Victor Shoup. Thích đến nỗi tôi phải viết đoạn này chỉ để nhắc đến chúng ;-). Tôi cũng đã từng dành ra nhiều tháng để đánh vật với Introduction to the Theory of Computation của Michael Sipser. Nhưng thôi, tôi không muốn giới thiệu sách toán nữa vì tôi rất dốt món này!5 Bắt đầu nói nhảm và hết
Phew! Không ngờ là tôi cũng viết được cho đến đây (hi vọng là bạn vẫn đang đọc!). Tôi định viết dông dài về thái độ học tập này nọ, nhưng thôi bài đã dài và nhiều thông tin rồi, nên tôi chỉ nói ngắn gọn thế này:
Cái mà tôi vừa “vẽ” ra là một con đường. Thú thật là tôi không biết đích đến của nó là gì — tôi chỉ biết rằng hành trình mà tôi đã đi qua (và hi vọng là những chặng đường sắp tới) đã mang đến cho tôi rất nhiều niềm vui — niềm vui của một con người đi khám phá thế giới, chinh phục những thử thách, để rồi chia sẻ những câu chuyện hay ho với tất cả mọi người.
Mỗi ngày tôi đều dành thời gian đọc sách, làm bài tập, viết mã hoặc chứng minh một cái gì đó. Không ai bắt tôi phải làm những chuyện đó. Có những thứ tôi học cũng không (hoặc chưa) có liên quan gì đến công việc. Tôi học chỉ vì tôi thích và tò mò. Tôi học vì tôi muốn hiểu thêm những thứ mà tôi cho là hay ho. Tôi học vì tôi muốn đi mãi, đi mãi, đi đến tận cùng những cái mà người ta viết trong sách, để xem ở đó có gì hay không.
Hôm rồi tôi đọc một mẩu chuyện về Richard Feynman, trong đó có đoạn kể về lúc Feynman bị bệnh gần đất xa trời, ông tâm sự rằng, “[I’m going to die but I’m not as sad as you think because] when you get as old as I am, you start to realize that you’ve told most of the good stuff you know to other people anyway”. Đương nhiên những gì tôi biết làm sao mà “good” bằng những gì Feynman biết, nhưng dẫu sao thì tôi cũng sẽ học theo Feynman: có biết chuyện gì hay ho thì kể cho nhiều người khác cùng biết. Bài này là một chuyện như thế.
Happy hacking!
(cảm ơn đại ca M. đã đọc và sửa bản nháp của bài này)
Bạn trantempo hỏi một danh sách các sách nên đọc trong KHMT. Bạn Nguyên đã đưa một danh sách sơ bộ. Tôi sẽ cập nhật từ từ vào danh sách dưới đây trong một vài tuần tới để có một danh sách hoàn tất hơn. (Cần về nhà duyệt lại tủ sách). Các bạn có thể bình luận và thêm vào các quyển sách mà bạn ưa thích.
hiện nay có 3 quyển textbooks được dùng khá phổ biến, trong đó tôi thích quyển của Kleinberg và Tardos nhất. Tuy nhiên, từ quan điểm cá nhân thì tôi chưa thấy hài lòng với cả 3 vì các lý do khác nhau, mặc dù cả ba quyển đều rất tốt.
Hồi trước có quyển của Aho-Hopcroft-Ullman. Bây giờ đã khá lỗi thời, ít ai dùng.
Tiếc rằng Robert Tarjan không viết sách giáo khoa, nếu không sách về data structure của ông hẳn phải rất hay.
Hiện nay không thể dạy thuật toán cơ bản mà không dạy về NP-Completeness và các phương pháp xác suất. Do đó, các quyển sau đây cũng rất cần thiết:
Tôi xếp 3 tập của Knuth vào dạng “cao cấp hơn”, trong trường hợp bạn đang thắc mắc. Về lecture notes (dạng presentation) thì tôi thấy notes của … tôi khá tốt (từ từ đến cuối học kỳ sẽ có toàn bộ notes.)
Khi nói đến phân tích và thiết kế thuật toán cao cấp, ta thường phải xem xét các đề tài cụ thể để giới thiệu. Các quyển sách cao cấp thường được viết về một đề tài nào đó: approximation algorithms, randomized algorithms, linear programming, convex programming, approximate counting, combinatorial optimization, network flows, algorithmic game theory, vân vân. Tôi sẽ gộp chung chúng lại và giới thiệu một vài quyển tiêu biểu.
Vijay Vazirani, Approximation Algorithms, Springer-Verlag, 397 pages hardcover, ISBN: 3-540-65367-8, published 2001.
Đây là tôi hoàn toàn chưa đụng tới rất nhiều các đề tài quan trọng khác: algorithmic number theory, algorithmic coding theory, computational biology, v.v.
Chú ý: Ngoài ra, không thể nghiên cứu thuật toán hiện đại mà không có hiểu biết sâu sắc về lý thuyết độ phức tạp (computational complexity theory), lý thuyết đồ thị và toán rời rạc, lý thuyết xác suất và lý thuyết thông tin, toán tối ưu và toán ứng dụng, thậm chí cả hình học và giải tích cơ bản (cần cho computational geometry), hay lý thuyết số (cần cho các thuật toán cryptography). Tôi sẽ giới thiệu vài quyển về các đề tài này trong vài ngày tới.
Combinatorics rất rộng, liên quan mật thiết đến rất nhiều nhánh khác nhau của toán học và khoa học máy tính. Dưới đây tôi chỉ liệt kê một sanh sách các sách tôi đã đọc và thấy hữu dụng trong nghiên cứu và trong phát triển tư duy toán học cho KHMT. Nghĩa là không kể những thứ hữu dụng mà tôi không biết gì cả như Additive Combinatorics của bác Terry Tao và bác Vũ Hà Văn.
3.1 Toán rời rạc phổ thông. Hiển nhiên sinh viên học KHMT phải biết toán rời rạc. Tuy nhiên, tôi cực kỳ khó chịu với loại toán rời rạc thường được dạy ở bậc đại học nói chung, vì hai lý do: (1) lớp toán rời rạc kiểu này không chuẩn bị đủ kiến thức cho sinh viên học thêm lên, (2) và nó cho sinh viên một bức tranh bèm nhèm về toán rời rạc, dễ làm sinh viên hiểu không đúng về tầm mức của toán rời rạc. Dĩ nhiên tôi hiểu rằng chương trình đại học thì có giới hạn, còn bể kiến thức thì vô cùng, do đó cái “khó chịu” này của tôi không có cơ sở, Chỉ nhân đây càm ràm để “xả stress” là chính.
Có bốn quyển sách “phải đọc” về toán rời rạc cho sinh viên học KHMT (và cả sinh viên toán):
3.2 Lý thuyết đồ thị (bao gồm cả algebraic graph theory). Không có nhánh nào của KHMT mà lại không cần kiến thức cơ bản về lý thuyết đồ thị. Sách mở đầu của lý thuyết đồ thị thì có cực kỳ nhiều. Tôi vẫn thường giới thiệu quyển của West cho sinh viên vì thấy nó vừa phải và phù hợp với dân máy tính. Quyển bài tập của Lovasz ở trên có vài chương về lý thuyết đồ thị rất hay. Tôi quan tâm đến algebraic graph theory nó là công cụ chính để phân tích các expander graphs (dùng cực kỳ nhiều trong complexity theory, algorithm design, randomized algorithms, coding theory, networking, v.v.)
Tommy R. Jensen and Bjarne Toft, Graph Coloring Problems, Wiley-Interscience; 1st edition (December 1994). Đây là tham khảo kinh điển về các bài toán tô màu đồ thị, dùng cực nhiều trong KHMT.
Norman Biggs, Algebraic Graph Theory, Cambridge University Press. Quyển sách be bé này giới thiệu algebraic graph theory rất tốt. Đủ để dùng làm nhiều thứ, bao gồm hiểu các thứ liên quan đến expanders.
3.2 Phương pháp xác suất (bao gồm random graphs). Phương pháp xác suất là một trong những công cụ chính của theoretical computer science, với ứng dụng ở khắp mọi nơi. Trong complexity theory & algorithms ta dùng phương pháp xác suất phân tích và thiết kế PCP, randomized (approximation) algorithms, derandomization, pseudo-random number generation, v.v. Trong mạng máy tính ta có randomized routing, randomized MAC protocols, blocking analysis of switches and routers, v.v. Trong cơ sở dữ liệu gần đây phát triển mạnh probabilistic databases, v.v.
Tôi sẽ giới thiệu sách về xác suất và thống kê trong một đề mục riêng. Phần dưới đây chỉ nói riêng về phương pháp xác suất theo nghĩa của Erdos.
Quyển của Mitzenmacher và Upfal đã giới thiệu trong phần giải thuật.
3.4. Enumerative combinatorics.
Dennis Stanton and Dennis White, Constructive combinatorics, Springer; 1 edition (May 15, 1986). Quyển này có lẽ ít người biết nhưng tôi thấy rất hay cho dân học máy tính. Nó viết về enumerative combinatorics từ góc nhìn thuật toán và bijective proofs. Tôi đã lấy lớp của cả hai vị Dennis. Bác Stanton là người thầy có ảnh hưởng lớn nhất đến triết lý giáo dục của tôi.
3.5 Algebraic combinatorics. Tư tưởng của nhánh này rất gần, theo một nghĩa nhất định, với các phương pháp đại số dùng trong coding theory và complexity theory hiện đại. Nó lại liên quan mật thiết đến giải tích của các hàm vuông góc. Tôi làm M.S. Thesis Toán trong nhánh này. Mặc dù bây giờ không làm về nó nữa, nhắc lại vẫn còn thấy “nhiệt huyết” bừng bừng . Ngoài ra, nhánh này cũng là anh em cột chèo với algebraic graph theory, rất cần thiết trong cả complexity theory lẫn một số bài toán trong mạng máy tính! Đó là chưa kể liên minh sống còn với representation theory cũng lại được dùng trong KHMT (như trong loạt bài về nhân ma trận tôi đang viết dở).
William Fulton, Young Tableaux: With Applications to Representation Theory and Geometry, Cambridge University Press (December 28, 1996).
3.6 Extremal set theory, extremal set systems, và design theory. Những thứ này thì dùng làm gì trong KHMT? Một vài ví dụ nhỏ: chúng liên quan mật thiết với lý thuyết thử nhóm (group testing) được dùng trong DNA library screening (bio-computing), trong thiết kế MAC protocols và thử lỗi của mạng quang (networking), và thiết kế thuật toán nói chung. Design theory lại cũng liên quan chặt chẽ với coding theory (sẽ giới thiệu sách sau) dùng trong communications và trong complexity theory.
Sách cơ bản:[1] Manning & Schutze, Foundation of Statistical NLP – (có online nếu có access vào MIT library)[2] Jurasky & Martin, Speech&Language Procesing: An Introduction to Natural Language Processing, Computational Linguistics, and Speech Recognition, 2nd edition.
Tham khảo thêm:[3] James Allen, Natural Language Understanding[4] Fred Jelinek, Statistical Method for Speech Recognition[5] Xudong Huang et al, Spoken Language Processing
Lộ trình tự đọc & học trong 1 hoặc 2 học kì theo thứ tự sau
——–Chương 1+2+3+4 – [1]: Introduction / Mathematical Foundations/ Linguistic Essential / Corpus-based WorkChương 7 – [2]: Phonetics
——–Chương 6 – [1]: Statistical Inference: n-gram Models over Sparse DataChương 4 – [2]: N-grams
——–Chương 8 – [5]: Hidden Markov ModelsChương 2 – [4]: Hidden Markov ModelsChương 4 – [2]: Word Classes and Part-of-Speech TaggingChương 6 – [2]: Hidden Markov and Maximum Entropy Models
——–Chương 3 – [3]: Grammar and ParsingChương 12 – [2]: Formal Grammars of EnglishChương 11 – [1]: Probabilistic Context Free GrammarChương 12 – [1]: Probabilistic ParsingChương 13 – [2]: Parsing with Context-Free GrammarsChương 14 – [2]: Statistical Parsing
——–Chương 3 – [2]: Words and Transducers
——–Chương 22 – [2]: Information Extraction
——–Chương 25 – [2]: Machine Translation
——–Chương 15 – [1]: Topics in Information Retrieval
——–Chương 16 – [1]: Text Categorization
——–
Lộ trình này giới thiệu chuyên sâu về phương pháp thống kê NLP, mô hình n-gram , mô hình Markov ẩn, & kĩ thuật phân tích câu (parsing). Sau đó là giới thiệu sơ qua một số topics mà NLP đóng vai trò quan trọng như Trích chọn Thông Tin (Information Extraction), Dịch tự động (Machine Translation), Khai Thác Thông Tin (Information Retrieval), & Phân Loại Văn Bản (Text Categorization). Về cơ bản sau khi xong lộ trình này là đủ để bắt tay vào chuyên sâu các vấn đề trong NLP. Rất nhiều topics của NLP không đề cập trong lộ trình này ví dụ như: Các máy Hữu hạn trạng thái (Finite-state Machines), Các kĩ thuật học máy (Machine Learning techniques), Nhận dạng tiếng nói (Speech Recognition), Tổng hợp tiếng nói (Speech Synthesis), Hệ thống Hỏi-Đáp (Q&A systems).
Chuyển qua machine learning và statistics… What? Statistics là cả một chuyên ngành riêng biệt sao phải học? Có lần một người bạn tôi hỏi David Blackwell, khi cậu ta mới chập chững vào PhD program. Rằng, có cái gì hay ho tôi nên theo đuổi trong statistics? Blackwell trả lời, nên học machine learning và nonparametric statistics. Tôi gộp cả ML và Stats vì tôi coi hai ngành này là một, dẫu về truyền thống và định hướng hiện tại thì có những sự khác biệt nhất định. Có rất nhiều sách hay trong ngành, nhưng chỉ giới thiệu một số mà tôi quen thuộc hơn cả. Như vậy còn một số sách hay mà chưa được list, xin bạn đọc bổ sung qua comments. Những quyển đánh dấu sao (*) có thể dùng làm sách nhập môn tốt. Ngoài ra, (+) cũng là những quyển sách tôi ưa thích.
5.1. Sách giới thiệu với hương vị machine learning
Quyển này từng là quyển sách đầu tay cho dân ML, nhưng nay nó đã lạc hậu về nội dung.
5.2. Sách tập trung vào các dạng mô hình học thống kê
A. Các mô hình tương đối khái quát
B. Các mô hình chuyên sâu và/hoặc hẹp hơn:
Tập trung nhiều vào lý thuyết về classification.
C. Các mô hình cho spatial data:
Giới thiệu cách sử dụng RKHS trong regression.
(Các mô hình hierrchical Bayesian models).
D. Các mô hình về sequential decision-making (such as reinforcement learning, online learning, etc…):
Giới thiệu về RL một cách nhẹ nhàng.
Xây dựng lý thuyết RL một cách chặt chẽ hơn.
Cesa-Bianchi and Lugosi, Prediction, Learning, and Games, Cambridge Univ Press, 2006.
E. Các dạng mô hình/topics khác
Ngoài ra, một số dạng mô hình cụ thể cũng có rất nhiều sách tham khảo, như mô hình về time series, mô hình về finance (stochastic calculus), mô hình linear/generalized linear/mixed linear các kiểu, mô hình state-space. Một số topics thú vị, như về active learning/ experiment design, concentration of measures,….Tuy nhiên scope hoặc hơi xa hoặc hơi sâu so với danh sách trên.
5.3. Phương pháp thống kê tổng quát
Phần lớn dân làm machine learning/statistics sẽ đi vào các dạng mô hình cụ thể, mỗi loại thích hợp cho một ứng dụng nào đó. Các mô hình đó giải quyết câu hỏi “how” khi cần học một mô hình (hay khái niệm). Để biết “why” thì cần đọc một số quyển sách về general statistical methodogy. Thực ra, một số quyển sách mang tính lý thuyết trong machine learning, như Vapnik, Devroye-Gyorfi-Lugosi, hoặc Anthony-Bartlett cũng có thể được xếp vào đây, nhưng focus của chúng còn hẹp so với các tác phẩm của các nhà thông kế.
Trường phái frequentist:
Hai quyển sách trên của Lehmann (và các đồng tác giả ở các editions sau) được coi là bible của classical (frequentist) statistics.
Trường phái Bayesian:
5.4. Bayesian computation (Markov chain Monte Carlo)
5.5 Sách về information and communication theory
Thực ra tất cả các sách về information theory có thể xếp vào mục “asymptotic theory”. Tất nhiên xuất phát điểm thì hoàn toàn khác: đó là từ các vấn đề trong communication và data compression.
Viết rất rõ ràng.
Free on-line!
5.6 Asymptotic theory
Mọi lý thuyết sâu sắc trong xác suất và thống kê đều phải đi về asymptotics! Tại sao? vì asymptotics là cách duy nhất (?) chúng ta có thể nói được một cách chắc chắn về tính chất của các hiện tượng không chắc chắn (uncertain phenomena).
Le Cam là một trong những nhà thống kê lý thuyết sâu sắc nhất của thế kỷ vừa rồi, nhưng quyển này khá khó nhằn.
Sẽ tiếp tục cập nhật! Không biết bao giờ mới xong.