Bàn về Nodejs, hiệu năng (performance) và những hiểu nhầm thường gặp phải

Tuần trước mình có đọc được một post như sau trên Facebook Group Nodejs Vietnam:

link : https://www.facebook.com/groups/vnnodejs/permalink/1173532239334629/

Tại sao NodeJS lại nhanh?
Tiếp tục đọc “Bàn về Nodejs, hiệu năng (performance) và những hiểu nhầm thường gặp phải”

[Giới thiệu .NET core và ASP.NET core]Phần 2:Phân biệt .NET Framework, .NET Core và Mono

Sau phần 1 thì chắc bạn cũng đã quen thuộc với các thao tác cơ bản của .NET core và viết được một số chương trình đơn giản. Bạn có thể tìm thêm tài liệu về các API của .NET tại https://docs.microsoft.com/en-us/dotnet . Tuy nhiên để tiến hành xây dựng các ứng dụng .NET phức tạp hơn, chúng ta cần nắm rõ một vài khái niệm cơ bản.

Một trong những điểm mạnh của hệ sinh thái .NET là sự hỗ trợ rất tốt của các công cụ như Visual Studio. Tuy nhiên đây cũng là điểm yếu vì nó ngăn cản rất nhiều lập trình viên tiếp xúc với những lý thuyết căn bản của Framework. Trong bài viết này chúng ta sẽ tìm hiểu xem .NET là gì, và các nền tảng .NET Framework, .NET core, và Mono khác nhau như thế nào.
Tiếp tục đọc “[Giới thiệu .NET core và ASP.NET core]Phần 2:Phân biệt .NET Framework, .NET Core và Mono”

[Giới thiệu .NET core và ASP.NET core]Phần 1: Làm quen và thiết lập môi trường

Hồi tháng 10 năm ngoái mình đã có 1 bài viết giới thiệu về ASP.NET 5 chạy trên Linux/Ubuntu. Vào thời điểm đó thì .NET core vẫn ở trong giai đoạn phát triển và chỉ được chính thức ra mắt vào cuối tháng 6/2016 , chứng kiến rất nhiều thay đổi so với phiên bản cũ.

Điều khiến mình ngạc nhiên là bài viết đó nhận được rất nhiều lượt xem, điều này chứng tó số lượng người quan tâm đến việc chạy các ứng dụng .NET trên những nền tảng ngoài Windows là không hề nhỏ. Đó cũng là lý do khiến mình thực hiện blog series này nhằm chia sẻ kiến thức về nền tảng .NET của tương lai, cũng như ghi lại những trải nghiệm của mình trong quá trình khám phá framework mới này.
Tiếp tục đọc “[Giới thiệu .NET core và ASP.NET core]Phần 1: Làm quen và thiết lập môi trường”

Is this a good time to be a .NET developer?

Yes!!!

It’s been a pretty exciting year for .NET developers (and all people who are looking to learn .NET). And no doubt there are more to come. This article aims to sum up all the hot news about .NET and why it’s an exciting time to be a .NET dev.

1. .NET on the server: Open and cross-platform.

 

So .NET Core is open source and cross platform. The Core CLR is open source, the CoreFX(which corresponds to the BCL in the .NET Framework) is also open source, and they run everywhere(Windows, Linux, Mac…) In case you’re confused, .NET Core is kind of the new .NET Framework which aims to be cross platform( .NET Framework is a Windows-only thing). image_60140ec0-ce46-4dbf-a14f-4210eab7f42c

So with .NET Core, the new ASP.NET Core web framework is also open source and cross platform. What that means is that you can now write a .NET web server on any OS (Windows, OSX, Linux), and deploy it in your platform of choice (Windows server, Linux server, CentOS…)

2. .NET on client-side: Open, and cross-platform

Last March, Microsoft bought Xamarin. And then they made Xamarin free. And then they open-sourced the entire Xamarin Mono runtime, and put it under MIT license. What does that mean? It means we can now write mobile Android/iOS/Windows applications in C#, using a shared library. This is important, because the fewer code bases you have to maintain, the more efficient you can deliver your software.

o92a3235

3. Developer-friendly .NET

The .NET compiler, Roslyn, is also open source, and designed to become a “compiler platform”. That enabled scenarios for writing .NET applications on non-Windows environments, like OSX or Linux. You can now use text editors like Visual Studio Code, Sublime, Atom, even Vim and Emacs, and write .NET apps with Roslyn support for intellisense.

Jetbrains, the company behind ReSharper and IntelliJ IDEA, announced last year that they are developing a cross platform .NET IDE, code name Rider( powered by IntelliJ, which is kinda awkward) . You can now write .NET everywhere, and run .NET everywhere.

screen-shot-2016-03-03-at-00-04-59

Also, the new .NET tooling will include a command-line interface (called the .NET CLI). For those developers who are more comfortable working in the terminal, this is great news. For example, on Ubuntu you can “apt-get install dotnet”, and then “dotnet run” your application.b3b377ce-8280-4629-a9ea-ed26a06401b0

4. Dotnet: going native

While getting a lot of new cross platform capability, there’s a new .NET tool you can used called .NET native, which is a tool that can compile your .NET application ahead-of-time to machine code.

Typically when you build your .NET app, your C# (or VB, F#) code is not compiled directly to machine code. Instead they’re compiled to an intermediate language called MSIL. This allows your C# application to be managed by the .NET runtime(called the CLR), and run on different platforms (thanks to not having to contain platform-specific machine code). Your code will be compiled to machine code the first time it’s invoked, by a component that exists in the .NET CLR called the JIT compiler. This JIT compiler, as its name implies, are more optimized for generating code quickly, instead of producing high quality code. Because .NET native compiles everything ahead-of-time, the compiler has more time to optimize your code. The result is, well, more performance.

.NET native usage is now only for UWP applications, but it is by no means restricted to that scenario. It’s early days and options are still being evaluated, but hopefully we can soon native-compile any .NET applications. When that happens, .NET will enter the world of Golang, to be natively compiled, garbage collected languages, while still maintain its awesome features like reflections and generics. Pretty awesome, huh?

5. Moving towards standards: the .NET Foundation

With more and more platforms getting to use .NET, one thing that .NET people are working towards is a standard library for writing .NET apps on any platform. This is called the .NET platform standard. It’s a long story, but in short: A library compatible with the .NET platform standard (for a particular version) can be used on any platform compatible with the .NET platform standard(of that version). What that means is that we’ll soon have a standard set of APIs to write .NET apps everywhere, which means that theoretically, I can even run a web server in my UWP app!!! We’ll see how this goes.

Together with that, an organization called the .NET foundation is also established to enable supports for .NET software projects. tsg

The Foundation’s members include big names, joined by Redhat, Unity, and Jetbrains last April. The above picture says it all.

5. What’s next: .NET on the web, why not?

We know that Microsoft, Google, Mozilla and more have been working on a standard for a browser bytecode : the WebAssembly. Those companies previewed the technology in March. In case you haven’t heard, WebAssembly is binary format for the web that aims to be more efficient than Javascript.

Now, we have Miguel de Icaza, the guy behind Xamarin, in an answer in his Reddit AMA session, said :

The major challenge to support WebAssembly is for the WebAssembly spec to be completed 🙂

We are about to wrap up a major re-architecting of the Mono engine, in large part to support Apple’s bitcode.

This re-architecting basically makes porting Mono to WebAssembly a very simple project. There is still serious work involved, but it is a well understood problem with known solutions.

So basically it will soon be possible, in theory, for us to write C#, and then have it compiled directly to WebAssembly which the browser can just pickup and run, without even having to come through JavaScript. For those who prefer not to write JavaScript(like me), this is really awesome.

So, Exciting time to be a .NET Developer?

YES!!!

Tìm hiểu về Linq trong C#(phần 2 – IEnumerable và những hàm Linq cơ bản)

Ở phần 1, chúng ta đã bàn về Functional programing (FP). Nếu như đây là lần đầu bạn tiếp xúc với khái niệm này và cảm thấy nó khó hiểu thì cũng đừng sợ, vì ai cũng giống bạn cả thôi. FP là một khái niệm quan trọng và cũng là một trong những cơ sở để Linq trong .NET được xây dựng. Vì vậy trong quá trình tìm hiểu về Linq, bạn cũng sẽ hiểu rõ được hơn về FP.

Tiếp tục đọc “Tìm hiểu về Linq trong C#(phần 2 – IEnumerable và những hàm Linq cơ bản)”

Tìm hiểu về Linq trong C#(phần 1 – Functional programming)

Nếu bạn là một lập trình viên .NET (hoặc Mono), và bạn đã từng học C# thì nhiều khả năng là đã dùng qua Linq rồi (hoặc đã dùng rồi mà chưa biết tên gọi là Linq). Linq cho phép bạn viết những biểu thức như

var bar = foo.Where(f => f.foo < 3).OrderBy(f => f.bar).ThenBy(f => f.foobar).Take(3);

hoặc

var list =from product in db where product.Code == 3 select product;

Đây là những đoạn code đẹp và dễ hiểu mà hiếm có ở một ngôn ngữ nào khác ngoài C# (hay VB). Điều đáng buồn là hiện nay, hầu hết các tài liệu nói về Linq bằng tiếng Việt đều chỉ tập trung nói về việc dùng cú pháp Linq để truy cập Database, hoặc thực hiện một vài thao tác đơn giản đối với các mảng dữ liệu, mà thiếu đi những tài liệu nói rõ về bản chất của Linq, vốn mạnh mẽ hơn rất nhiều so với những ứng dụng nhỏ nêu trên.

Linq được thiết kế nhằm giúp lập trình viên thao tác với các nguồn dữ liệu bằng một cú pháp mang tính hàm hóa (functional) cao (điều này sẽ được giải thích kĩ hơn sau). Linq là một trong những điểm tạo nên vẻ đẹp của C# mà ít ngôn ngữ nào có được. Vậy nên việc hiểu rõ bản chất của Linq sẽ giúp các bạn nắm bắt được bất cứ ứng dụng nào, từ việc xử lý mảng, đến truy xuất dữ liệu thông qua Linq to Sql. Việc hiểu rõ Linq cũng giúp các bạn nắm bắt được những khái niệm về lập trình hàm (Functional programming), nhằm tận dụng được hết sức mạnh mà C# và .NET mang lại.

Series bài viết này sẽ viết về các vấn đề mang tính học thuật và bản chất của Linq. Bạn sẽ không học được cách dùng Linq để truy xuất Database ở đây – những ứng dụng đó sẽ chỉ được điểm qua để hỗ trợ cho bài viết mà thôi. Vấn đề chính là chúng ta nắm bắt được Linq là gì, và làm thế nào Linq lại cho phép người dùng viết những đoạn code gọn vào đẹp như vậy.

Linq trong .NET được dùng trên 2 interface chủ yếu: IEnumerable<T>IObservable<T> . Các bài viết trong series này sẽ chủ yếu viết về IEnumerable<T> . IObservable<T> sẽ được đề cập đến sau dành cho những ai thích tìm hiểu thêm về thư viện Reactive Extensions.

Thế nào là lập trình hàm (Functional programming) ?

Để hiểu rõ về Linq, trước hết chúng ta cần biết sơ qua về lập trình hàm (Functional programming, từ giờ sẽ gọi tắt là FP). Tại sao? Vì Linq được thiết kế để sử dụng theo phong cách FP.

Cách tốt nhất để hiểu về khái niệm FP là tìm hiểu tại sao người ta lại nghĩ ra khái niệm này, và nó nhằm giải quyết vấn đề gì. Hãy hồi tưởng lại về ngày đầu tiên bạn đi học lập trình, bạn nhận được một bài tập lập trình dạng “Hello World” đơn giản mà thầy giáo cho, và sung sướng khi thực hiện được nó. Rồi càng ngày, các bài tập mà bạn phải thực hiện càng phức tạp, càng khiến bạn phải viết nhiều code và thao tác với nhiều cấu trúc dữ liệu khác nhau. Điều này làm nảy sinh 3 vấn đề cơ bản. Thứ nhất, bạn muốn sử dụng một đoạn logic nhiều lần, với nhiều đối tượng dữ liệu khác nhau. Để làm được điều này, bạn phân tách chương trình của mình thành những tiến trình (procedure) khác nhau. Nếu như những tiến trình này (hãy gọi chúng là tiến trình A, B chẳng hạn) cùng hoạt động trên một cấu trúc dữ liệu nào đó và cùng thay đổi cấu trúc đó, điều đó có nghĩa là trong suốt quá trình hoạt động, A và B luôn luôn phải biết xem tiến trình còn lại hoạt động thế nào. Hãy thử lấy một ví dụ đơn giản nhất: hiện lên 1 thông báo khi phần mềm gặp lỗi:

private int Calculate(){
    try{
        this.Result = this.A1 + this.A2 * this.B1 / this.B2;
        return this.Result;
    }catch(Exception ex){
        ShowErrorMessage(ex);
        HandleError();
        return -1;
    }
}

private void ShowErrorMessage(Exception ex){
    this.Error = ex;
    MessageBox.Show(ex.Message);
}
private void HandleError(){
    HandleErrorBasedOnCode(this.Error.Code);
}

Thoạt nhìn đoạn code trên có vẻ đơn giản và hoạt động chính xác. Tuy nhiên hãy thử nghĩ kĩ xem: bạn luôn phải nhớ rõ rằng chỉ được phép gọi HandleError() sau khi đã gọi ShowErrorMessage(), nếu không method HandleError() sẽ hoạt động sai. Khi làm việc với một project lớn, bạn sẽ không thể nào nhớ hết được các tiểu tiết như thế này, mà bắt buộc phải đọc đi đọc lại cùng một đoạn code, và kể cả như vậy thì lỗi vẫn có thể xảy ra. Tệ hại hơn nữa, khi bạn làm việc chung với những người khác, họ sẽ khó có thể đoán được rằng method ShowErrorMessage() làm những gì, mà bắt buộc phải đi sâu vào đọc code của bạn để hiểu.

Vấn đề thứ hai, đó là việc các tiến trình A, B thay đổi cấu trúc dữ liệu chung  khiến code của bạn trở nên khó hiểu, ngay cả với chính bản thân người viết. Trong ví dụ trên, không ai nghĩ rằng method Calculate() ngoài việc tính toán, còn có thể thay đổi một vài thuộc tính của class. Sự thay đổi này được gọi là tác dụng phụ (side-effects) trong hàm

Vấn đề thứ 3, đó là khi các tiến trình kể trên hoạt động không độc lập, sẽ rất khó để bạn có thể Test và Debug. Việc test method Calculate() kể trên sẽ rất khó khăn, do nhiều thuộc tính cần phải được thiết lập đúng trước khi Calculate() được gọi.

Tất nhiên, đoạn code trên cố tính được tạo ra nhằm mục đích ví dụ (mặc dù trên thực tế, vẫn có những người đoạn code dạng như vậy được đưa vào sử dụng). Nhưng nếu bạn đã từng lập trình, ắt hẳn đôi khi lâm vào những tình huống tương tự.

Câu hỏi là: Thế thì FP giúp gì được tôi để giải quyết những tình huống như vậy ?

Câu trả lời: FP đưa ra khái niệm hàm “thuần” (pure function). Một hàm “thuần” là một hàm toán học thuần túy, có nghĩa là nó nhận các giá trị đầu vào, trả về giá trị đầu ra, không có trạng thái ẩn và không thay đổi bất cứ cấu trúc dữ liệu nào. Cụm từ “không có trạng thái ẩn” có nghĩa rằng hàm của bạn chỉ được sử dụng đầu vào, cộng với các phép tin học cố định ( cộng trừ nhân chia, vòng lặp…) để tạo ra đầu ra. Điều này có nghĩa rằng với cùng một tập hợp đầu vào, bạn có thực hiện hàm đó bao nhiêu lần thì giá trị trả về chỉ là duy nhất.

Chúng ta hãy thử xem xem, bằng những khái niệm trên, đoạn code phía trên có thể  được cải thiện ra sao:

private void Calculate(){
    try{
        this.Result = CalculateResult(this.A1, this.A2, this.A3, this.A4);
    }catch(Exception ex){
        ShowErrorMessage(ex.Message);
        HandleError(ex.Code);
    }
}

private static int CalculateResult(int A1,int A2,int B1,int B2){
    return A1 + A2 * B1 / B2;
}

private void ShowErrorMessage(string message){
    MessageBox.Show(message);
}
private void HandleError(int code){
    HandleErrorBasedOnCode(code);
}

Giờ thì đoạn code của chúng ta đã khá hơn nhiều: hàm Calculate trở thành 1 hàm void, hay nói cách khác là 1 Action, hàm ý rằng đây là một tiến trình nào đó. Các hàm CalculateResult, ShowErrorMessage, HandleError chỉ đơn thuần nhận và trả giá trị mà không thay đổi bất cứ thuộc tính gì. Đoạn code trên còn có một lợi ích ngầm: Khi bạn muốn thay đổi logic tính toán, nhằm mục đích tối ưu hóa hoặc thay đổi về logic chương trình, bạn chỉ cần chỉnh sửa logic đó trong hàm CalculateResult. Điều này khiến cho hàm của bạn có tính tái sử dụng cao(hay còn gọi là được module hóa)

Những phần mềm ngày nay có độ phức tạp ngày càng cao, do đó mà FP càng ngày càng trở thành một xu thế. Có những ngôn ngữ được thiết kế để lập trình dưới 100% dưới dạng FP (Haskell, F#…) C# là ngôn ngữ hướng đối tượng, nhưng cung cấp rất nhiều những tính năng giúp lập trình hàm. Ví dụ như, trong C#, có một kiểu dữ liệu để miêu tả 1 hàm: Func<>. Một Func<int, bool> có nghĩa là một hàm nhận argument dạng int, và trả về boolean. Đối với những tiến trình không có giá trị trả về (hay còn gọi là hàm void), C# hiển thị dưới dạng Action<>. 

Chúng ta hãy thử xem có thể thay đổi method Calculate kể trên bằng những kiểu dữ liệu này như thế nào

private void Calculate(Func<int,int,int,int,int> calculator,
                   Action<Exception> onError){
    try{
        this.Result = calculator(this.A1, this.A2, this.A3, this.A4);
    }catch(Exception ex){
        onError(ex);
    }
}

private static int CalculateResult(int A1,int A2,int B1,int B2){
    return A1 + A2 * B1 / B2;
}

private void ShowErrorMessage(string message){
    MessageBox.Show(message);
}
private void HandleError(int code){
    HandleErrorBasedOnCode(code);
}

//call method Calculate like this
Calculate(CalculateResult, ex=>{
    ShowErrorMessage(ex.Message);
    HandleError(ex.Code);
});

Mức độ module hóa của đoạn code được nâng lên một “tầm cao mới”. Giờ đây method Calculate không còn bắt buộc sử dụng hàm CalculateResult để tính toán nữa, mà có thể dùng bất cứ hàm nào được cung cấp khi được gọi. Kĩ thuật này được gọi là phân tách (Decoupling). Nó cho phép method Calculate() được sử dụng rộng rãi hơn.

Tóm lại: Vậy thì những điều này liên quan gì đến Linq?

Nếu bạn chưa biết gì về FP trước khi đọc bài viết này thì xin chúc mừng. Bạn đã có thêm nhiều kiến thức bổ ích. Tuy nhiên chủ đề chính của chúng ta vẫn là Linq.

Sở dĩ mình dành hẳn một bài dài giới thiệu về FP vì nó là cơ sở để các kĩ sư của Microsoft thiết kế nên Linq. Linq là một thư viện nhằm giúp thao tác với các tập hợp, hay nói rộng hơn, là các nhóm dữ liệu. Do đó một trong những tiêu chí đầu tiên của Linq là việc bảo toàn tính nguyên vẹn của data: Tất cả các hàm trong Linq không biến đổi cấu trúc dữ liệu hiện có, mà chỉ trả về cấu trúc mới. Nếu bạn đã nghiên cứu đủ sâu, bạn sẽ thấy rằng việc các chức năng phần mềm đều có thể quy về việc thao tác và sử dụng những tập hợp dữ liệu. Do đó, những hàm trong Linq có thể nói là những hàm mạnh mẽ nhất mà bạn có thể học được, và điều này không thể thực hiện được nếu không có những khái niệm của Functional Programming.

Visual Studio 2015 và C# 6

*( Lưu ý: bấm vào hình để xem rõ hơn)

Update: Thông tin tác giả:

Tên: Hoàng Đức Huy
SDT: 01207526940
Địa chỉ thư: Đào Thị Xuyến, phòng Giám sát hoạt động, Vietcombank, 198 Trần Quang Khải, Hà Nội

Visual Studio 2015 được ra mắt hồi tháng 7/2015 vừa qua. Trong phiên bản mới này, Microsoft đã trang bị thêm cho bộ IDE rất nhiều công cụ và tính năng mới. Một trong những điểm mới của VS2015 là việc đi kèm theo .NET Framework 4.6 và C# 6. Trong blog này, chúng ta điểm qua những điểm mới nổi bật của C# phiên bản 6.0 và hỗ trợ lập trình từ Visual Studio 2015.

Tiếp tục đọc “Visual Studio 2015 và C# 6”

Typescript 1.6 and async/await

One of the best features in C# that is difficult to find in other languages is the ability to write asynchronous code without having to do callbacks. This makes the code flow much more “natural” and sometimes, easier to debug. For example, imagine the following code in NodeJS:

function RequestHandler(){
    DatabaseCall1(function(){
        NetworkCall1(function(){
            DatabaseCall2(function(){
                NetworkCall2(function(){
                     Response.Return();
                });
            });
        });
    });
}

Obviously that code block is not nice at all. Such a pattern is often called “the pyramid of doom“, making the code looks more complicated that it really is.
In C#, asynchronous programming is implemented so that developers could write codes which are much more “natural”, especially when executing asynchronous functions sequentially:

public async Task RequestHandler(){
    await DatabaseCall1();
    await NetworkCall1();
    await DatabaseCall2();
    await NetworkCall2();
    Response.Return();
}

Async/await is a planned feature for javascript (expected to be in ES7). Given the current state of javascript when ES6 has not been fully implemented yet, it would take quite a few years for this feature to be brought to life.

Tiếp tục đọc “Typescript 1.6 and async/await”