Home Blog Page 131

Chương trình C đầu tiên “Say goodbye”

Chương trình C đầu tiên “Say goodbye”

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Chào các bạn, lại là tôi Xuân Quỳnh đây. Trong bài trước, bạn đã biết ém hàng để tấn công em C rồi. Còn bài này ta sẽ nói say goodbye với em ấy 😀 thật ra thì thế này, bọn con gái nế bạn nói chuyện sến súa nhiều, làm quen bằng mấy câu như “bạn ơi cho tớ làm quen nhé..” thì có mùa quit nó mới để ý tới bạn. Hãy làm gì khác biết  khác với những đối thủ của mình, hãy làm cho nàng cảm thấy đặc biệt, họ sẽ chú ý tới bạn. “Em ơi anh nhìn em quen quen. Có phải em là bạn của A không?” “Em ơi, hình như hôm trước anh thấy em đi học bên khu XXX, em học lớp à? Trông em rất  là xinh này” Đấy, mở lời bằng những thứ làm con gái tò mò đi, đảm bảo em ấy sẽ đáp lại. Mà thôi, tôi lại chém gió rồi, tôi đang FA này =))

  13 kênh dạy lập trình căn bản bằng tiếng Việt ai cũng có thể học

  6 sự thật phũ phàng không phải ai trong ngành lập trình cũng biết

OK, bài trước tôi nhắc lại là bàn đã có gcc trên window để chơi với ẻm này rồi. Bây giờ tôi cần bạn dùng notepad để code vài dòng code. Bạn sẽ không IDE(Dev-C hay visual C..), nói không với nó, bạn sẽ hiểu cách C hoạt động như nào, C là gì, mông má ra sao, sinh nở như nào? vân vân mây mây.

Tôi sẽ chứng minh cho bạn thấy chỉ cần notepad và trình build gcc thôi là bạn cũng build ra được file exe. Bạn hãy mở notepad lên bằng cách nhấn nút cửa sổ ghì chặt và nhấn thêm nút R rồi nhấn notepad và ENTER cái rụp. bạn gõ code như sau rồi nhấn CTRL+S để save như hình:

void main() { }

Chương trình C đầu tiên “Say goodbye”

Bạn chọn All files và đặt đuôi là c nhé. NHỚ NHÉ, là đuôi C và chọn all file nhằm đảm bảo nó không phải là là goodbyec.c.txt như nhiều bạn làm không chuẩn là ra như vậy đó. Tiện đây tôi chỉ cho bạn cách hiển thị đuôi file, dân code mà. Mình phải khác cái em học kinh tế ở đây, phải xem được file đuôi là gì. Chỉ cần làm như này:

Chương trình C đầu tiên “Say goodbye”

Chương trình C đầu tiên “Say goodbye”

Vậy là bạn đã bắt đầu đẹp trai ra rồi đó. OK, uống ngụm nước, làm điếu thuốc rồi chơi tiếp nào. Bây giờ bạn quay lại với em cmd để nghịch với thằng C này. Tôi đã lưu cái file vừa tạo vào đường dẫn F:\C_project\goodbyec.c

Bạn muốn lưu đâu thì tùy, nhưng khuyến khích không nên lưu ra desktop nhé. Bây giờ bạn bật cmd lên và gõ như này:

cd /d  <đường dẫn thư mục chứa file code C>

Ví dụ tôi là:

cd /d F:\C_project\

Bạn nhớ dấu cách giữa cd và /d nhé. Cái /d là để trỏ đường dẫn tuyệt đối, không có nó thì bạn không vô được cửa nhà nàng C đâu :))

Rồi ok tôi có cái màn hình này, tôi gõ tiếp dir để chắc chắn là có em code C nằm trong đó, chờ chén:

Chương trình C đầu tiên “Say goodbye”

Đấy, em ấy đấy!

Rồi bây giờ tôi tiến hành cởi hết xiêm y em ấy này. Tôi gõ gcc goodbyec.c -o goodbyec và tôi ENTER thì nó thù lù ra file exe như hình:

Chương trình C đầu tiên “Say goodbye”

Ở 1 là đoạn code tôi gõ. Ở đây bạn cần lưu ý gcc là tham số bắt buộc để build code C, tiếp theo tham số goodbyec.c là tên chương trình tôi đặt(MẸO: Bạn chỉ cần nhấn good rồi Tab là nó ra đầy đủ tên). Còn -o là tham số chỉ định build ra file output, đằng sau nó là tên file output(exe) sẽ sinh ra. Bạn nhìn vào dòng 2 tôi vạch đó. Không tin thì bạn vào chính thư mục đó kiểm tra thử.

Rồi bây giờ muốn chạy chương trình như nào? Bạn vào cmd và bạn đang ở thư mục đó, bạn chỉ cần gõ tên em ấy là goodbyec.exe là nó chạy ầm ầm à. À mà nó chả in ra gì đâu. Chương trình tôi viết chả có gì chạy cả, mỗi 1 hàm main trống không. Đây có lẽ là chương trình c không thể đơn giản hơn. main chính là trái tim của em C, nơi em ấy thổn thức, sinh ra mọi thứ trong đó. Bạn muốn làm gì cũng phải đưa vào trong main, trong 2 cái cặp dấu {} đó nhé. Và main là duy nhất, nếu có 2 main thì chương trình kiểu gì nó cũng báo lỗi :)) Không tin cứ thử xem. Đúng kiểu em ấy chỉ yêu có 1 người thôi đó. :v

Rồi qua bài này bạn đã biết à hóa ra IDE nó cũng thực ra là nhấn nút Run(F5 trên visual hay F11 trên dev-c) về bản chất cũng là câu lệnh gõ trên mà thôi.

Thấy hấp dẫn chưa? Đấy, cơ bản nó đơn giản thế đấy. Các bài tiếp theo tôi sẽ yêu cầu bạn chơi với dòng lệnh, only dòng lệnh cho tới lúc nào bạn không còn sợ nó, bạn gõ toành toạch như 1 thằng hacker thì bạn bè nó nhìn bạn ghê lắm đó nha 😀

Happy!

Bài viết gốc được đăng tải tại quynhlaptrinhc.wordpress.com
Có thể bạn quan tâm:
Xem thêm Việc làm Developer hấp dẫn trên TopDev

Ghi chú về 3 module bundler rollup, parcel, webpack

3 module

Bài viết được sự cho phép của tác giả Lưu Bình An

bundler của JS là công cụ dùng để đưa tất cả file đã import vào thành 1 file duy nhất. Nó còn có thể *minify` kết quả cuối cùng nếu bạn muốn.

JS bundler có 3 ông lớn ở thời điểm hiện tại

  • Parcel
  • Rollup
  • Webpack
  Cách Sử Dụng Go Modules
  Angular - Tự xây dựng module "lazy load images"

Đánh giá trên việc config có dễ hay không

Parcel số 1, gần như không phải làm gì

Webpack và Rollup yêu cầu phải có file config riêng.

Rollup có sẵn polyfill cho import/export, webpack chưa có

Rollup hỗ trợ relative path, webpack phải dùng path.resolve hoặc path.join

Config webpack phức tạp nhất, được cái hỗ trợ nhiều third-party

Loại bỏ code không sử dụng

Loại bỏ code không sử dụng, còn gọi dead code, Tree shaking rất cần thiết để nâng cao hiệu năng.

Parcel vẫn là số 1. Hỗ trợ tree-shaking cả ES6 và CommonJS

Rollup đứng thứ 2.

Webpack thì phải thủ công config để có tree-shaking.

Rollup và webpack tập trung tree-shaking với ES6.

Code splitting

Webpack số 1, đúng kiểu làm ít hưởng nhiều. Có 3 lựa chọn

  • Sử dụng config entry
  • Sử dụng plugin CommonsChunkPlugin
  • Dynamic import

Rollup và Parcel hỗ trợ splitting ngay từ đầu, nhưng đang vướng nhiều issue bị report.

Webpack vẫn là lựa chọn hàng đầu.

Live reload

Parcel gặp một số vấn đề với HTTP logging, Hooks và middleware

Rollup phải cài thêm rollup-plugin-serverollup-plugin-livereload chứ không có sẵn.

Webpack cài thêm webpack-dev-server.

Khả năng tùy chỉnh của webpack sẽ cao hơn Rollup và Parcel.

Module transform

Các bundler chỉ hỗ trợ file JS, với các file khác chúng ta cần thêm plugin

Ghi chú về 3 module bundler rollup, parcel, webpack

Parcel hỗ trợ sẵn tất cả những kiểu file quen thuộc, không cần đụng đến config. Không những vậy, khi gặp các file config .babelrc.postcssrc.posthtml nó sẽ tự handle

Webpack và Rollup cần thêm plugin và config mới có transform và transpiler.

Kết

  • Nhanh gọn lẹ, app đơn giản, chọn Parcel
  • Làm thư viện, hạn chế third-party, dùng Rollup
  • App phức tạp, nhiều third-party, dùng webpack.

Ghi chú từ Rollup vs. Parcel vs. webpack: Which Is the Best Bundler?

Bài viết gốc được đăng tải tại vuilaptrinh.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Top những nguồn tư vấn về mức lương tốt nhất

mức lương
mức lương

Đáp ứng nhu cầu giải đáp về mức lương phù hợp, nhiều trang web hướng nghiệp ra đời. Tuy nhiên, liệu bạn đã tìm đúng cho mình các nguồn tư vấn uy tín hay chưa? Cùng TopDev điểm qua top những trang web nổi bật giúp bạn giải đáp các thắc mắc về mức lương.

Trang web quản lý nghề nghiệp của bạn Businessweek có một loạt các bài báo và các mục đề dọc theo phía bên phải, giống như bài viết từ Harvard Business Review. Nói chung, nó giống như các bước tiếp theo từ các trang web About.com với rất nhiều lời khuyên tổng quát.

Các nền tảng trang web về mức lương

1. Salary.com

Salary.com được biết đến là một nền tảng thông minh tích hợp công cụ tính lương nhanh chóng. Chỉ cần một số thông tin cơ bản về bản thân, bạn dễ dàng hoàn tất tìm kiếm và xác định được các chỉ số của mức lương.

Xem thêm các việc làm về tuyển dụng Data Scientist 

2. Glassdoor.com

Điểm nhấn quan trọng từ Glassdoor là sở hữu một động cơ tìm kiếm việc làm tốt hơn được tích hợp vào trang web của họ. Từ nền tảng này, bạn có thể đọc về mỗi công ty, quá trình phỏng vấn của mình. Đồng thời những nhận xét của các ứng cử viên khác cũng được phân tích rõ.

Tính lương gross sang net chuẩn, trải nghiệm ngay!

3. Indeed.com

Indeed.com là trang web dễ sử dụng và khá thú vị. Mọi người đều nắm bắt nhanh vì tính linh động và cập nhật nhanh các thông tin mới nhất. Bạn sẽ dễ dàng tra cứu được những thông tin để tính lương nhanh chóng và thuận tiện.

Nguồn tra cứu khác

Ngoài các nền tảng là các nền tảng trang web, chúng ta có thể tra cứu các thông về lương thông qua các trang mạng xã hội

Xem thêm các việc làm NTQ Solution tuyển dụng

4. Facebook

Nhiều người Facebook chỉ đơn thuần là post bài, đang các dòng trạng thái cá nhân,… Thực tế cho thấy facebook là nguồn tìm kiếm thông tin về mức lương hiệu quả. Dù là mạng xã hội nhưng nhiều nhà tuyển dụng cũng đề cập chi tiết các mức lương một cách rõ ràng. Đồng thời việc tuyển dụng các vị trí như freelancer IT, Senior Developer cũng nhận được sự quan tâm lớn. Vì thế, không quá để nói facebook là kênh social phù hợp để tra cứu về lương; thu hút tuyen dung it.

5. LinkedIn.com

mức lương
mức lương

LinkedIn luôn được biết đến là mạng xã hội phổ biến và chuyên nghiệp nhất. Nhiều nhà tuyển dụng đã chia sẻ về các kiến, nhu cầu tuyển dụng của mình trên nền tảng này. Không những thế, các thông tin về mức lương cũng được đề cập chính xác, luôn cập nhật các vị trí tuyển dụng mới nhất để đáp ứng nhu cầu tìm việc của ứng viên. Đây thật sự là một nền tảng hiệu quả phục vụ cho việc khai thác thông tin về mức lương đáng tin cậy.

Có thể bạn quan tâm:

Xem thêm tuyển dụng it lương cao hàng đầu tại TopDev

Truyền dữ liệu vào Vue.js component

Truyền dữ liệu vào Vue.js component

Bài viết được sự cho phép của tác giả Kien Dang Chung

Điểm lại một số vấn đề của bài trước, component trong Vue có thể được tạo ra với phương thức Vue.component() với đầu vào là một đối tượng chứa các tùy chọn như data, template… Trong template có thể sử dụng dữ liệu đã được khai báo trong data của component và không thể sử dụng được các dữ liệu được đăng ký trong data của Vue instance cũng như của các component khác một cách trực tiếp.

  3 phút làm quen với Vue.js
  10 kinh nghiệm khi làm việc với các dự án lớn viết bằng Vue.js

1. Phạm vi dữ liệu của component

Chúng ta cùng xem xét một ví dụ tạo ra một Hello component và component này sẽ lấy dữ liệu tên người dùng để hiển thị câu chào.

<!DOCTYPE html>
<html>
<head>
    <title>Phạm vi dữ liệu Component Vue.js - Example 1 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <template id="hello-template">
        <h1>{{ message }} {{ userName }}</h1>
    </template>
    <div class="container" id="app">
        <hello-component></hello-component>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('hello-component',{
            data: function () {
                return {
                    message: 'Xin chào'
                }
            },
            template: '#hello-template'
        })
        new Vue({
            el: '#app',
            data: {
                userName: 'Allaravel'
            }
        });
    </script>
</body>
</html>

Chúng ta kỳ vọng rằng màn hình sẽ hiển thị câu chào “Xin chào Allaravel” nhưng không nó chỉ hiển thị “Xin chào” mà không in ra tên. Mở tab console lên xem có lỗi gì không?

Phạm vi vue component

Chúng ta thấy đấy lỗi thông báo như sau: “Thuộc tính userName không được khai báo nhưng vẫn tham chiếu đến khi render”. Như vậy trong template chỉ được tham chiếu đến các thuộc tính dữ liệu được khai báo trong data của component? Đúng vậy, template chỉ có thể tham chiếu đến các thuộc tính trực tiếp nếu thuộc tính đó của component. Với các thuộc tính, dữ liệu ở phạm vi ngoài component chúng ta phải sử dụng đến một cách khác sẽ được giới thiệu trong phần tiếp theo.

2. Truyền dữ liệu vào một component

Nếu các bạn đã đọc phần cơ bản về component, bạn đã quen với cách đặt vấn đề là component là một khối mã nguồn bao gồm cả HTML, Javascript, CSS giống như function trong các ngôn ngữ lập trình. Vậy nó cũng cần có các tham số để có thể truyền dữ liệu từ ngoài vào trong khối mã nguồn đó. Vue.component() làm việc này thông qua thuộc tính props. Truyền dữ liệu vào một component bao gồm 2 bước như sau:

  • Bước 1: Khai báo các thuộc tính có thể tham chiếu trong template với tùy chọn props.
  • Bước 2: Truyền dữ liệu cho thuộc tính khai báo với v-bind khi sử dụng component.

Ví dụ Hello component ở phần đầu sẽ được hoàn thiện lại như sau:

<!DOCTYPE html>
<html>
<head>
    <title>Truyền dữ liệu vào Component Vue.js với props - Example 1 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <template id="hello-template">
        <h1>{{ message }} {{ userName }}</h1>
    </template>
    <div class="container" id="app">
        <hello-component v-bind:user-name="userName"></hello-component>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('hello-component',{
            data: function () {
                return {
                    message: 'Xin chào'
                }
            },
            props: ['userName'],
            template: '#hello-template'
        })
        new Vue({
            el: '#app',
            data: {
                userName: 'Allaravel'
            }
        });
    </script>
</body>
</html>

Code điều chỉnh này chỉ khác một chút so với ví dụ đầu tiên: Thay đổi thứ nhất: Khai báo thuộc tính tham chiếu đến từ bên ngoài trong tùy chọn props

props: ['userName']

Thay đổi thứ hai: Truyền dữ liệu vào thuộc tính user-name khi sử dụng hello-component

<hello-component v-bind:user-name="userName"></hello-component>

Bạn đang có một thắc mắc nhỏ, tại sao là v-bind:user-name mà không phải v-bind:userName? Do các thuộc tính trong HTML là không phân biệt hoa thường (case insensitive), như vậy trình duyệt sẽ thông dịch các ký tự viết hoa cũng như các ký tự viết thường. Do đó, khi bạn sử dụng các template với các thành phần DOM, các prop có tên kiểu camelCase cần được chuyển sang tương đương với dạng kebab-cased. Xem thêm Các chuẩn đặt tên trong lập trình.

Chú ý, khi thuộc tính ở ngoài component thay đổi, thì nó ngay lập tức sẽ cập nhật trong component, tuy nhiên không thể từ trong component mà thay đổi được giá trị thuộc tính ở ngoài này. Luồng dữ liệu như vậy gọi là one-way-down binding.

3. Các dạng dữ liệu có thể truyền vào một component

Trong ngôn ngữ HTML, khi muốn truyền một giá trị cho thuộc tính của thẻ HTML nào đó ta chỉ việc dùng cú pháp:

<html-tag property="value">

Với framework Vue.js chúng ta có thể sử dụng cả cách thông thường như trên hoặc sử dụng v-bind, hai cách có một số điểm khác nhau.

<html-tag v-bind:property-a="propertyB">
Chú ý: v-bind:property có thể viết ngắn gọn thành :property
<html-tag :property-a="propertyB">

Chắc bạn còn nhớ v-bind được sử dụng để gán một biểu thức Javascript vào một thuộc tính của thẻ HTML. Do vậy, khi bạn sử dụng v-bind:my-number=”78″ thì 78 được hiểu như là một biểu thức Javascript hơn là một chuỗi. Với cách truyền giá trị kiểu HTML thì giá trị truyền vào sẽ là một chuỗi thông thường.

3.1 Truyền một số vào component

<blog-post v-bind:likes="42"></blog-post>
<blog-post v-bind:likes="post.likes"></blog-post>

3.2 Truyền dữ liệu boolean vào component

<blog-post favorited></blog-post>

<base-input v-bind:favorited="false">

<base-input v-bind:favorited="post.currentUserFavorited">

3.3 Truyền mảng vào component

<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

<blog-post v-bind:comment-ids="post.commentIds"></blog-post>

3.4 Truyền một đối tượng vào component

<blog-post v-bind:comments="{ id: 1, title: 'My Journey with Vue' }"></blog-post>

<blog-post v-bind:post="post"></blog-post>

3.5 Truyền một thuộc tính của một đối tượng vào component

post: {
  id: 1,
  title: 'My Journey with Vue'
}
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

4. Component bên trong một component khác

Truyền dữ liệu vào Vue.js component

Cái hay nhất của component là có thể sử dụng lại trong một component khác, như vậy các ứng dụng chỉ đơn giản là các component được lắp ghép với nhau. Chúng ta cùng xem một ví dụ tiếp theo:

<!DOCTYPE html>
<html>
<head>
    <title>Component trong component - Example 3 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <template id="hello-template">
        <div class="row">
            <div class="col-md-12">
                <h1>{{ message }} {{ userName }}</h1>
            </div>
        </div>
    </template>
    <template id="form-template">
        <div class="row">
            <div class="col-md-3">
                <label for="name">Tên bạn là gì?</label>
            </div>
            <div class="col-md-9">
                <input class="form-control" v-model="userName" type="text">
            </div>
        </div>
    </template>
    <template id="greeting-template">
        <div>
            <form-component :user-name="userName"></form-component>
            <hello-component :user-name="userName"></hello-component>
        </div>
    </template>
    <div class="container" id="app">
        <greeting-component></hello-component>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('hello-component',{
            data: function () {
                return {
                    message: 'Xin chào'
                }
            },
            props: ['userName'],
            template: '#hello-template'
        })
        Vue.component('form-component', {
            template: '#form-template',
            props: ['userName']
        });
        Vue.component('greeting-component', {
            template: '#greeting-template',
            data: function () {
                return {
                    userName: 'Allaravel'
                }
            }
        });
        new Vue({
            el: '#app'
        });
    </script>
</body>
</html>

Trong ví dụ này chúng ta có 3 component: hello-component để hiển thị lời chào, form-component để nhập vào tên người dùng và greeting-component sử dụng hai component trước đó tạo thành một component mới. Chúng ta cũng gặp lại cú pháp truyền dữ liệu từ ngoài vào trong component, nó cũng được áp dụng khi truyền dữ liệu từ component cha vào component con.

[jsfiddle url=”https://jsfiddle.net/allaravel/nh94gv5t/” height=”300px” include=”result,html,js” font-color=”39464E” menu-background-color=”FFFFFF” code-background-color=”f3f5f6″ accent-color=”1C90F3″]

Mọi thứ hiển thị bình thường nhưng khi bạn thử thay đổi ô nhập liệu tên người dùng, bạn sẽ nhận được một lỗi từ Vue.js:

Lỗi thay đổi giá trị component cha

Đại ý lỗi này là tránh thay đổi giá trị được truyền vào một cách trực tiếp, thay vào đó sử dụng một thuộc tính được khai báo trong data hoặc computed dựa trên giá trị truyền vào. Giá trị bị thay đổi ở đây là userName. Thay đổi lại code trên theo gợi ý core Vue.js đưa ra:

<template id="form-template">
    <div class="row">
        <div class="col-md-3">
            <label for="name">Tên bạn là gì?</label>
        </div>
        <div class="col-md-9">
            <input class="form-control" v-model="name" type="text">
        </div>
    </div>
</template>
Vue.component('form-component', {
    data: function (){
        return {
            name: this.userName
        }
    },
    template: '#form-template',
    props: ['userName']
});

Trong form-component chúng ta không sử dụng trực tiếp thuộc tính userName nữa mà khai báo một thuộc tính khác là name trong data và khởi tạo nó bằng giá trị của userName được truyền vào. Như vậy, khi bạn thay đổi tên người dùng trong ô nhập liệu, nó chỉ tác động đến thuộc tính name cục bộ. Với lời chào chúng ta muốn sẽ loại bỏ ký tự trống ở hai đầu chuỗi tên người dùng và viết hoa tên người dùng, tạo ra một thuộc tính computed để làm việc này (Tại sao dùng computed, xem lại bài viết Cơ bản về computed trong Vue.js):

<template id="hello-template">
    <div class="row">
        <div class="col-md-12">
            <h1>{{ message }} {{ uperCaseUser }}</h1>
        </div>
    </div>
</template>
Vue.component('hello-component',{
    data: function (){
        return {
            message: 'Xin chào'
        }
    },
    computed: {
        uperCaseUser: function (){
            return this.userName.trim().toUpperCase()
        }
    },
    props: ['userName'],
    template: '#hello-template'
})

Tuy nhiên, code sửa đổi vẫn chưa đáp ứng được yêu cầu, chúng ta muốn khi thay đổi tên người dùng thì tên đó phải được cập nhật vào lời chào.

Truyền dữ liệu vào Vue.js component

Tức là phần code trên mới chỉ đáp ứng được luồng dữ liệu truyền dữ liệu từ component cha vào component con (chiều 1), còn chiều ngược (chiều 2) lại hiện chưa thực hiện được do khi truyền từ cha vào con chỉ theo một chiều (one-way data binding).

5. Kết luận

Các khái niệm trong component đã dần được giới thiệu đến các bạn, chúng ta đã đi được nửa chặng đường tìm hiểu về component và tôi luôn muốn bạn nhớ vài điều: component là một code block chứa HTML, Javascript, CSS nó giống như “function” trong ngôn ngữ lập trình thông thường và nó cũng có thể có tham số để truyền dữ liệu vào. Ví dụ về component trong component còn dở dang với chiều ngược lại của đường đi dữ liệu nhưng bài viết cũng khá dài, nghỉ ngơi và nhớ dành thời gian xem bài kết tiếp nhé.

Bài viết gốc được đăng tải tại allaravel.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

HAPROXY là gì, setup 1 load balancer đơn giản

HAPROXY là gì, setup 1 load balancer đơn giản

Bài viết được sự cho phép của tác giả Nguyễn Hữu Đồng

Hế nhô các bạn, lại là mình đây, nhân dịp hôm nay mình có tìm hiểu qua về HAPROXY nên mình muốn viết vài dòng để chia sẻ về haproxy cũng như lí do chúng ta cần haproxy cho dự án.

HAPROXY là một proxy server, load blancer, system monitoring, được sinh ra để làm nhiệm vụ của một front end web service. Vậy tại sao chúng ta lại cần đến nó. Trước khi khi mình làm việc với dự án nhỏ, web app của mình chỉ cần viết bằng NodeJS dùng Pm2 để có thể chạy multithread sau đó dùng Nginx để serve static file, làm proxy cho nodejs vậy là xong, chưa có khi nào chết cả, chưa bao giờ quá tải vì cơ bản đó cũng chỉ là một app nhỏ. Và nếu chết cũng chẳng sao 😀 chết thì restart lại thôi kk.

  10 Công cụ Go-To Tech dành riêng cho các Software Developer

  20 trường hợp sử dụng lệnh Docker cho developer

Giờ đây khi bước qua một công ty mới, mình sẵp đối mặt với những vấn đề mới, khi lượng request lên tới hàng ngìn request per second thì việc scale hệ thống như thế nào để có thể đáp ứng được lượng request đó là một vấn đề cần phải giải quyết êm gọn.

Về mặt cơ bản, khi lượng request nhiều lên, chúng ta sẽ có thể lựa chọn hai laị hình scale cho hệ thống đó là scale ngang và scale dọc, scale dọc tức là nâng cấp HDD lên SSD dung lượng cao, nâng cấp RAM, Vi xử lí… những đâu phải cứ nâng cấp hoài vậy được đâu, lúc đầu khi cầu hình thấp thì rất dễ nâng cấp lên cấu hình cao, nhưng khi cấu hình đã cao muốn nâng cấp lên cấu hình cao hơn thì rất khó, thứ nhất không phải linh kiện lúc nào cũng có sẵn, và giá cả cũng không phải rẻ. Scale theo chiều ngang tức là dùng thêm nhiều hệ thống tương tự như hệ thống hiện tại để chia nhau xử lí request.

Và thường khi scale chúng ta sẽ kết hợp cả hai kiểu scale sao cho hợp lí nhất và ít chi phí nhất.

Đến đây khi các hệ thống hoạt động cùng với nhau, nảy sinh ra vấn đề làm sao để giao request này cho hệ thống kia xử lí, từ đây mình xin viết gọn một hệ thống sẽ là một node. node x tưng ứng hệ hệ thống x.

Haproxy sinh ra để giải quyết vấn đề này, haproxy sẽ làm vai trò của một proxy server, theo dõi tình trạng các node và sẽ gửi request đến các node.

Nếu còn chưa hiểu về khái niệm proxy các bạn có thể tìm hiểu tại đây.

Cài đặt và sử dụng Haproxy rất dễ dàng. Trên MacOS chỉ cần mở terminal lên rồi chạy hai lệnh sau. Haproxy server của bạn đã sẵn sàng để chạy.

Để chạy được HAPROXY, chúng ta cần phải cấu hình cho nó. Về cơ bản haproxy có thể nhận các thông số cấu hình theo độ ưu tiên như sau

  • argument -> proxies setting -> global setting và theo mặc định thì những gì được setup trong global setting sẽ được bổ sung vào proxies setting.

Chi tiết hơn các bạn xem trong file dưới đây. Mình sẽ giải thích từng phần có nhiệm vụ như thế nào.

global
    log 127.0.0.1   local0
    log 127.0.0.1   local1 debug
    maxconn 4096

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    retries 3
    option redispatch
    maxconn 2000
    timeout connect      5000
    timeout client      50000
    timeout server      50000


frontend haproxy
  bind *:8012
  stats enable
  stats uri /stats
  stats refresh 10s
  stats admin if TRUE
  stats auth dongnguyen:029
  default_backend go-web-server

backend go-web-server
        balance roundrobin
        server node1 0.0.0.0:6000 check
        server node2 0.0.0.0:7000 check
        server node3 0.0.0.0:5000 check
        option httpchk GET /whatever
  • Global session : những tham số thiết lập ở đây sẽ mặc định được sử dụng trong proxies session, hoàn toàn có thể overwrite nó trong proxies session
  • Proxies Session : tên gọi chung cho cả “default session, front end session, back end session”. Vì haproxy là một server proxy nên hẳn nó sẽ phải có cái gì đó là front end. Có thể là chính là http request từ client hoặc cũng có thể là một front-end web server như Nginx.

Ở file trên mình setup Global session có những key là log và maxconn, setup hai key này với giá trị như trên sẽ chỉ cho haproxy ghi 2 loại log vào system log server được lắng nghe mặc định trên cổng 514. Và ở loại log thứ 2 ghi ở level debug, các bạn có thể xem các loại log và level log tại đây.

Phần default session, mình setup mặc định sẽ dùng log được được setup trong Global session, proxy mode là http, ngoài http thì các bạn có thể chọn tcp, khi chọn tcp thì một kết nối đầy đủ sẽ được tạo ra giữa client và server, đây là mode mặc định, còn khi chọn http thì request sẽ được phân tích, những request nào không đáp ứng được chuẩn “RFC-compliant” . Timeout client,timeout server, timeout connect nếu khi một request được tạo ra nếu trong vòng x miliseconds mà không thực hiện được thì haproxy sẽ bỏ qua request đó.

“Front end session” ở đây mình có hai 2 front-end, cái thứ nhất là tool của haproxy giúp mình có thể xem được tình trạng các node, số request đã được các nodejs thực hiện. Trong front-end thứ hai do mình dùng nginx làm front-end web server cho haproxy nên mình sẽ để tên là nginx, mình dùng “back-end” có tên là “nodes” để handle request. Mình cho haproxy lắng nghe request từ front-end nginx trên cổng 9090, và từ nginx mình chỉ cần proxy_pass qua port này là xong.

Tiếp theo đến phần “back-end”, ở đây mình khai bao 3 nodes tương đương với 3 hệ thống cùng chạy song song, mỗi node sẽ lắng nghe trên port khác nhau, mình khai báo haproxy check tình trạng của server trước khi thêm node vào danh sách node để pass_proxy. Một lưu ý là nếu để mặc định thì khi check status server haproxy sẽ gửi request với method “options” đến server của chúng ta và nếu nó nhận đc status code =200 thì có nghĩa là node của chúng ta đang hoạt động, bạn cũng có thể thay đổi mặc định bằng cách set

option httpchk <method> <uri>

ví dụ mình muốn haproxy gửi một method get để check vào url “/check”

thì mình sẽ ghi “ option httpchk get /check”

Và cuối cùng là thuật toán mà từ đó Haproxy có thể dùng để xác định nên gửi request vào node nào. Thuật toán “roundrobin” có nghĩa là haproxy sẽ gửi request theo vòng tròn, 1–2–3–1–2… cứ như vậy ngoài ra còn vài thuật toán nữa các bạn có thể xem tại đây.

Hiện tại mình đang có 3 node chạy song song đang lắng nghe request trên cổng 5000,6000 và 7000. Và để khởi chạy HAPROXY mình chỉ cần RUN

haproxy -f path/to/file/config

Như trong trường hợp của mình do mình mình sẽ chạy

haproxy -f haproxy.cfg

Để xem HAPROXY của mình đang có hoạt động không, do mình đa khai báo front-end stats của haproxy đang lắng nghe trên cổng 6789, nên để xem haproxy status, monitoring mình chỉ cần đến “http://localhost:6789/stats

Để check xem server có phân chia request tới 3 con server mình đang chạy hai không mình tiến hành gửi ba request tới và đây là kết quả.

Tèn tèn vậy là mình vừa setup một load balancer đơn giản với 3 node chạy song song, trong thực tế thì các bạn sẽ phải làm rất nhiều thứ như làm sao để chia sẻ tài nguyên, ví dụ như database, đồng bộ log giữa ba server. Mình sẽ chia sẻ thêm nhiều hơn trong tương lai khi mình được làm việc trực tiếp với nó.

Cảm ơn các bạn đã đọc bài viết của mình. Bye bye các bạn ^_^.

Bài viết gốc được đăng tải tại medium.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

“Luộc bài” đã giúp tôi trở thành 1 QA

“Luộc bài” đã giúp tôi trở thành 1 QA

Bài viết được sự cho phép của vntesters.com

Chia sẻ của bạn Nguyễn Dương Hải về quá trình trở thành một QA chuyên nghiệp. Từ chỗ không biết QA là gì đến yêu nó và gắn bó với nó lúc nào không hay.

Nhìn lại bản thân

Trước tiên mình xin nói là mình chẳng tự hào gì về chuyện này :D. Nhưng sau 6 năm làm việc như 1 QA, mình muốn thẳng thắng nhìn lại bản thân mình. Rất nhiều người từng hỏi “Sao bạn học CNTT không làm Dev mà làm QA?”. Mình chưa bao giờ dám trả lời lý do thực sự vì sao mình lại chọn nghề này. Và mình thấy bây giờ là lúc thích hợp.

  "Ở Việt Nam, cơ hội để thực sự làm về Trí tuệ nhân tạo còn quá ít, trong khi những thứ mang hình thù và dáng dấp AI thì quá nhiều"

Nhất quỷ nhì ma thứ ba học trò

Lúc ở trường đại học, có những nhóm thường hay học theo kiểu chia nhau ra làm bài tập. Tức là mình sẽ làm đồ án của môn này, bạn tập trung làm đồ án của môn kia rồi chuyền tay nhau bài giải. Thầy cô cũng biết chuyện này, nên rất nghiêm trong việc xử phạt những đứa chép bài nhau. Mình nhớ có một môn “Lý thuyết đồ thị”, mình làm bài tập và share cho bạn. Cuối cùng cả 2 bị 0 điểm. Bạn mình copy “hiền” quá :(. Lúc ấy mình không thể fail môn đó được nên phải nói nó confirm với cô rằng nó chép bài mình rồi xin cô. Cuối cùng mình 9.5 nó thì vẫn 0 điểm. Nói chung mình là đồ HÈN!

“Luộc bài” cũng cần kỹ năng

Lúc mình chép bài của thằng khác, mình siêu cẩn thận. Thay vì những đứa khác, thường là mang về đổi tên hàm, tên class, mang hàm qua file khác rồi xong. Mình là vô coi thiệt kỹ luôn. Thiệt là mình dở lắm, học đại học mấy năm mà khả năng thích ứng ngôn ngữ mới của mình dở ẹt. Cái đồ án nào mà nói dùng kỹ thuật abc, xyz là mắt mình hoa lên. Còn nữa, project thời đại học mà, bạn mình đặt tên hàm, biến thì thôi rồi! Nhìn vô cái tên mà nhiều lúc nghĩ “Cái này làm cái quái gì vậy??”. Nhìn vô code thôi nhiều lúc cũng thua luôn!

Để bù đắp cho vụ đó, mình mở source code của bạn lên xong rồi DEBUG. Mình input giá trị cho 1 hàm rồi xong debug từng dòng một. Coi tất cả value của những biến trong đó, để coi coi là cái hàm này thực ra là nó làm cái quỷ gì. Rồi xem coi kết thúc hàm này thì nó đi tới hàm nào.

Tốn time dã man nhưng mà mình toàn học bằng kiểu đó. Không có project của bạn lúc đầu chắc mình chẳng bao giờ biết làm gì hết. Riết rồi, cái nó viết nhiều khi nó không hiểu nó viết cái gì nhưng mà mình thì hiểu =)).

Dấu ấn riêng trong code

Rồi, sau khi hiểu rồi thì mình bắt đầu đến màn “cooking” :D. Lúc đầu thì theo kiểu là nó viết kiểu “For” thì mình viết lại thành “While”, tên biến tên hàm cũng đổi. Rồi mình cũng cố gắng thu ngắn code của nó lại. Nhờ lúc debug, thì nếu mình có tìm thấy lỗi, thì 2 đứa cùng sửa.

Cái quan trọng là, mình đọc rất kỹ đề bài của cô và nghĩ ra rất nhiều input, nên cái code của mình sau khi sửa, nhiều khi nhìn “chuối” hơn ( gượng ép đổi code style) nhưng mà nó cover nhiều case hơn. Mình nhớ hồi đó làm toàn bằng If, Else, code như 1 cái nùi giẻ trong đó @@! Cuối cùng thì, cái bài đó gốc là của bạn mình nhưng mà qua tay mình nó có hình ảnh của mình trong đó :).

Tìm tuyển dụng QA QC đãi ngộ tốt trên TopDev

Hướng đến tương lai

Đến khi mình ra trường, mình tự nhìn lại mình: Khả năng học ngôn ngữ kém, coding style kém, kiến thức xây dựng hệ thống gần như là 0, nhưng mình có tư duy logic rất chi tiết và khả năng tìm lỗi / Case chưa cover rất cao. Sau khi học course về Testing trong trường mình có cảm giác là mình sẽ phù hợp và mình xinh việc làm intern tester rồi trở thành QA như bây giờ :).

Cảm ơn bạn vì bạn đã chịu khó nghe câu chuyện của mình đến lúc này :). Qua câu chuyện này, mình muốn nói với bạn rằng, bạn tập trung làm việc gì thì cuối cùng bạn sẽ được trả lại bằng 1 skill tương ứng, và học CNTT không có nghĩa là bạn chỉ có con đường làm Developer. Hãy tự mình tìm con đường mình thích và cố gắng đạt được nó các bạn nha!

Bài viết gốc được đăng tải tại vntesters.com

Có thể bạn quan tâm:

Truy cập ngay việc làm IT đãi ngộ tốt trên TopDev

Phân biệt debounce và throttle

Phân biệt debounce và throttle

Bài viết được sự cho phép của tác giả Lưu Bình An

debounce

Được sử dụng để delay việc thực thi một hàm nào đó. Ví dụ khi user nhập vào ô search, chúng ta không thực thi ngay câu lệnh tìm kiếm mà đợi một khoảng thời gian sau khi user đã ngừng việc nhập.

Phân biệt debounce và throttle

Có thể hình dung cái thang máy, cửa chuẩn bị đóng, nếu có người đưa chân vào nó sẽ không chạy liền, mà cho người đó vào rồi mới chạy.

  Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web
  Lập trình đa luồng trong Java (Java Multi-threading)

throttle

Trong khoản thời gian đã chỉ định, chỉ thực thi hàm 1 lần duy nhất, bỏ qua mọi lần gọi khác. Ví dụ như user click liên tục vào nút search để gọi API, chúng ta chỉ thực thì đúng lần đầu, các lần click tiếp theo chúng ta cho qua và không gọi API.

Một ví dụ khác làm infinite-scroll, khi user đã load đến vị trí gần cuối trang, chúng ta sẽ đi lấy thêm dữ liệu, chúng không đợi đến khi user đã đến cuối trang. debounce sẽ không hữu ích vì nói chỉ cho thực thi khi user stop việc scroll. throttle sinh ra cho việc này.

Rất hữu dụng khi cần gắn các sự kiện vào DOM. Vì chúng ta có thể hạn chế bớt số lần thực thi không cần thiết.

Ví dụ với sự kiện scroll, nếu chúng ta bắt onScroll để thực thi một hành động, số lần thực thi sẽ rất lớn. Đây là vấn đề vào năm 2011 của Twitter, user khi scroll trên điện thoại sẽ chậm và tệ nhất là memory leak luôn.

Nên sử dụng thư viện có sẵn nếu cần, như lodash, đừng tự viết lại.

requestAnimationFrame

Là một API của trình duyệt, tương tự như _.throttle(doSomething, 16)

Sinh ra để đáp ứng chạy cho thật mượt (đảm bảo 60fps).

Khi sử dụng cần tự viết việc start/cancel

IE9 không hỗ trợ

Ghi chú từ Debouncing and Throttling Explained Through Examples

Bài viết gốc được đăng tải tại vuilaptrinh.com

Có thể bạn quan tâm:

Xem thêm tuyển it không yêu cầu kinh nghiệm trên TopDev

Freelancer IT liệu có tồn tại sự tự do trong nghề?

freelancer IT
freelancer IT

Freelancer IT là nghề không những đòi hỏi kinh nghiệm, kỹ năng mà còn sự tâm huyết với nghề. Tuy nhiên, liệu bạn có biết được sự tự do của nghề freelancer IT thật sự có tồn tại hay không? Cùng TopDev tìm ra câu trả lời thông qua bài viết sau.

Nếu là một freelancer IT uy tín, bạn dễ dàng nhận được những hợp đồng lớn. Đồng thời, bạn sẽ kiếm được thu nhập “khủng” trong thời gian ngắn.

Freelancer IT có thể thỏa sức tung hoành theo nhịp độ làm việc của bản thân. Bạn không bị chi phối bởi thời gian như làm việc inhouse; môi trường được thoải mái lựa chọn. Song, mỗi freelancer it cần đảm bảo tiến độ và hiệu suất công việc theo hợp đồng công việc.

Thế nhưng, tính tự do của nghề freelancer IT liệu có tồn tại thực sự? Thực tế cho thấy, những rủi ro của nghề này thật sự là một vấn đề lớn đấy!

Freelancer IT chịu trách nhiệm toàn bộ quá trình

Nếu làm teamwork trong một dự án, bạn phải cộng tác với nhiều đối tượng khác nhau; chia sẻ các nhiệm vụ để cùng nhau thực hiện thì freelancer IT lại khác.

Xem thêm các việc làm NTQ Solution tuyển dụng

freelancer IT
Mọi quy trình cần được đảm bảo tính trách nhiệm

Bạn là một nhân tố làm việc độc lập dựa trên nguyên liệu là các nguồn dữ liệu được các khách hàng cung cấp. Đó là lý do khiến các áp lực trở nên lớn hơn.

Bạn phải chịu trách nhiệm trực tiếp cho những chiến lược, kế hoạch, từng bước đi thực hiện nhiệm vụ. Nếu thiếu tính kỷ luật và chuyên nghiệp sẽ dẫn đến những hậu quả nghiêm trọng.

Những rủi ro tiềm ẩn

Trách nhiệm luôn đi kèm với những rủi ro tồn đọng. Chúng có thể phát sinh bất cứ lúc nào. Và bạn không thể trốn chạy hay bỏ cuộc mà chỉ có các đối diện và giải quyết chúng.

Hãy nhìn vào thực tế để bình tĩnh giải quyết các sự cố có thể xảy ra trong nghề IT tự do. đơn xin nghỉ việc

Freelancer IT but NoFree – Tự do nhưng ràng buộc

Ưu điểm lớn nhất dễ nhận thấy khi nhắc đến freelancer là tự do. Thế nhưng, bề nổi ấy không thể khỏa lấp được những nỗi niềm riêng của các freelancer it. Bạn quên mất tính áp lực của một người làm IT tự do.

Xem thêm các việc làm về tuyển dụng Data Scientist 

freelancer IT
Sự ràng buộc luôn luôn tồn tại

Nếu xét trên phương diện về tự do, những người làm việc it tự do dường như luôn phải chật vật trong mê cung deadline cùng những đòi hỏi từ khách hàng. Nhiều lúc nó đáng sợ đến mức các freelancer it quyết định thay đổi vị trí freelancer hoặc thực hiện các dự án phát triển nghề nghiệp khác.

Tính khốc liệt và sự cạnh tranh ngầm giữa các Freelancer IT

Rất ít người thành công với nghề freelancer. Không phải ai cũng đáp ứng được những đòi hỏi của nghề này. Ngay cả những freelancer dày dạn kinh nghiệm; nhiều khi cũng cảm thấy mệt mỏi sau quãng thời gian “lăn lộn” với nghề được cho là “tay làm hàm nhai, tay quai miệng trễ”.

Không những thế, khi freelancer it trở thành xu hướng, thì môi trường làm việc trở nên cạnh tranh và khắc nghiệt hơn. Do vậy, nhiều người làm IT tự do dù có thâm niên lâu năm vẫn luôn tìm kiếm một công việc khác. Điều này giúp họ phải cân bằng công việc này với một công việc khác. Yêu thích, đam mê nhưng mọi thứ phải an toàn, cơ hội phát triển tốt thì mới có thể tiến xa.

Xem thêm việc làm ngành cntt hàng đầu tại TopDev

Các trường hợp kiểm thử OTP

Các trường hợp kiểm thử OTP

Bài viết được sự cho phép của tác giả Vân Anh

Quay trở lại với chuỗi bài “How to” – làm như thế nào,  bên cạnh các bài viết liên quan đến Selenium và những thứ linh tinh trong đời sống thường ngày của mình, mình bổ sung chuỗi bài viết này để luyện tập các kỹ năng của bản thân liên quan đến chuyên môn kiểm thử, rèn luyện lối tư duy, dịch và diễn giải cho dễ hiểu nhất từ các bài toán cụ thể trong thực tế.

  04 Điều Cần Chú Ý Cho Người Mới Làm Automation Test
  Biện hộ: Vì sao các Developer không test phần mềm của họ?

Những bài toán thực tế – có thể là bạn sẽ gặp rất nhiều nhưng như mình đã nói đâu đó trong các bài viết trước đây, gặp nhiều thậm chí cảm thấy rất quen thuộc, tuy nhiên nếu chỉ nghĩ mà không ghi lại hoặc lưu trữ đâu đó thì trước sau gì cũng bị gió thổi bay, không thì cũng tự bốc hơi mà thôi, chưa kể đến việc thiếu sót mà trong suy nghĩ bạn khó có thể nhận ra. Rồi kể cả việc có kiến thức kỹ năng, nhưng không được luyện tập nó cũng sẽ tự mai một đi.

Các trường hợp kiểm thử OTP

Chứng minh dễ thấy nhất là việc các anh chàng tay chân cơ bắp, bụng sáu múi vô cùng hấp dẫn, nhưng nếu không tập tành đều đặn thì cái việc cơ bị xịt đi là điều hết sức bình thường nha=)) muốn to thì lại phải tập tiếp. Nói chung, làm gì cũng cần phải có sự luyện tập kiên trì và đều đặn nhá. Quá chuẩn luôn không cần nhiều dẫn chứng nữa.

Ùi, lại lan man rồi, hôm nay mình sẽ đưa ra bài toán về OTP, và cùng nhau suy nghĩ các trường hợp có thể dùng để kiểm thử cái tính năng này nhé!

Nói lại sơ qua về OTP trước đã.

OTP là gì?

OTP là viết tắt của từ One Time Password dịch nôm na sang tiếng Việt là mật khẩu sử dụng một lần. Mã OTP được ra đời để đảm bảo bạn là “người thật” đang thực hiện giao dịch tại thời gian thực. Nó thường dùng được dùng làm lớp thứ 2 để xác minh giao dịch trong giao dịch ngân hàng, xác minh đăng nhập trên tài khoản email, mạng xã hội,…

Ví dụ đơn giản như việc bạn thực hiện chuyển khoản tài khoản ngân hàng, đến bước xác nhận thực hiện giao dịch, phía ngân hàng sẽ gửi cho bạn 1 mã về tin nhắn theo số điện thoại bạn đăng ký, bạn phải nhập đúng mã trong tin nhắn đó thì việc chuyển khoản mới được thực hiện. Việc này để đảm bảo rằng “chính bản thân bạn” là người chuyển tiền đi chứ không phải là một kẻ giả mạo nào đó vô tình hay cố ý tấn công tài khoản của bạn (trừ việc bạn làm lộ hết tất tật các thông tin -.-). Hay ví vụ khác khi bạn thay đổi mật khẩu của Gmail, Facebook bạn cũng sẽ nhận được một mã yêu cầu xác thực trước khi đổi được mật khẩu. OK. Hiểu OTP rồi nhé.

Thông tin thêm quan trọng, bạn có thể nhận được mã xác thực này thông qua tin nhắn SMS, qua cuộc gọi tự động, qua ứng dụng được cài đặt trên smartphone như Smart OTP, Smart Token, hay qua các thiết bị cứng như Token Card…

Chi tiết hơn về OTP các bạn có thể search thêm Google nhé, nói ngắn gọn thế thôi. 😀 bây giờ đi vào tiết mục chính.

Các trường hợp kiểm thử OTP

* Quá trình sinh mã OTP

1. Kiểm tra các OTP cần phải được sinh ra và gửi đi sau một khoảng thời gian nhất định nào đó – khoảng thời gian này cần phải đáp ứng yêu cầu nha. Chứ lâu quá phiên đăng nhập hết hạn rồi mới gửi được thì toi! Hoặc thời gian từ khi có yêu cầu cho đến lúc nhận được mã quá lâu thì cần xem xét đến độ trễ của đường truyền để tìm giải pháp thích hợp, tránh để hacker xấu lợi dụng bắt ngang tín hiệu 🙂

2. Trong một phiên xác thực, kiểm tra xem số lượng OTP tối đa được sinh ra và gửi đi là bao nhiêu? – Cái này để tránh trường hợp spam hệ thống, vét cạn. 😀

3. Kiểm tra xem các loại ký tự mà OTP hỗ trợ là dạng nào: có loại OTP chỉ là một dãy các số, hoặc chỉ là một cụm chữ cái ngẫu nhiên hay có thể bao gồm cả số lẫn chữ tùy theo yêu cầu thiết kế hệ thống.

4. Kiểm tra để xem xem các mẫu OTP được gửi có dễ đoán hay không? – Cái này cũng tùy thuộc vào việc sử dụng thuật toán nào để sinh mã OTP, nhưng mình cũng có thể kiểm tra liên tục nhiều lần để xem có thể đoán được quy luật sinh mã của hệ thống, mã sinh ra các dãy số có quá đơn giản, dễ suy luận mã tiếp theo hay có vấn đề gì khác hay không?

* Chức năng gửi mã OTP

5. Kiểm tra để đảm bảo được chỉ có điện thoại hoặc email được đăng ký của giao dịch mới nhận được OTP này. Ví dụ ông A thực hiện giao dịch nhưng mà ông B nhận được tin nhắn thì có phải là chết không! :v

6. Kiểm tra chức năng gửi lại OTP xem hoạt động của nó như thế nào? Có đáp ứng được yêu cầu chức năng hay không? Khi nhấn gửi lại liên tục thì hệ thống có đáp ứng hay xử lý như thế nào?

* Việc kích hoạt, sử dụng mã OTP

7. Kiểm tra xem thời gian hết hạn của một OTP là bao lâu? Thường thì sẽ là 30s hoặc 60s gì đó đó. 😀  – Nếu như OTP tồn tại quá lâu, cộng với độ trễ khi dữ liệu đồng bộ tới máy chủ các hacker có thể lợi dụng điểm này để giải mã thuật toán OTP và đánh cắp thông tin.

8. Kiểm tra với trường hợp có một OTP đã bị hết hạn cho phiên giao dịch, thì nó có thể sử dụng để xác thực được nữa hay không? Nếu có thì nhất định là fail rồi :)) – Mật khẩu sử dụng 1 lần mà sử dụng nhiều lần vẫn được thì đúng là có gì đó sai sai :v

9. Kiểm tra với trường hợp OTP đã được sử dụng, thì nó có sử dụng được sử dụng được cho lần sau nữa hay không? – Thường thì sẽ không thể sử dụng cho lần sau được. Vì mình đã gặp trường hợp có 1 OTP thì trong ngày đó mình có thể sử dụng đăng nhập và sử dụng nhiều lần được. -.- không biết có phải lỗi hay là cố tình thế 😀

10. Kiểm tra trong trường hợp khi yêu cầu gửi lại mã OTP mới, thì OTP cũ – dù chưa sử dụng để kích hoạt thì có sử dụng được nữa hay không? Tất nhiên phải không sử dụng được nữa thì mới đúng.

11. Kiểm tra trường hợp khi nhập chưa đủ số lượng ký tự yêu cầu của OTP, người dùng có thể thực hiện thao tác tiếp theo không? Ví dụ nhập được 3 ký tự thì nhấn nút Thực hiện/Next, thao tác có được thực thi không?

12. Kiểm tra xem người dùng có thể nhập vào sai OTP tối đa bao nhiêu lần?

13. Kiểm tra với trường hợp nhập sai, hoặc nhập sai OTP quá nhiều lần thì hệ thống sẽ xử lý như thế nào? Hệ thống khoá tạm thời tài khoản người dùng hay hủy giao dịch đang thực hiện hay không? Hay có thông báo xử lý nào đến người dùng hay không?

14. Kiểm tra sau khi giao dịch trước đó bị hủy, hay tài khoản bị khóa tạm thời, sau đó người dùng có thể gửi yêu cầu để hệ thống gửi OTP tiếp nữa hay không?

15. Kiểm tra với trường hợp người dùng cung cấp số điện thoại và email không hợp lệ, sau đó gửi yêu cầu cung cấp OTP, thì hệ thống có phản hồi hay không? và nếu có sẽ phản hồi như thế nào? Nếu không thì làm sao để nhận biết được?

16. Kiểm tra đường dẫn của các hướng dẫn và trợ giúp cho người dùng về OTP của hệ thống có hoạt động bình thường và đúng hay không?

17. Kiểm tra đối với trường hợp người dùng không nhận được thông tin mã OTP, hoặc quá hạn thời gian sử dụng mã OTP đó thì sẽ có hướng dẫn hoặc chỉ dẫn nào để lấy được mã khác hay không?. Nếu có thì kiểm tra xem hoạt động của nó như thế nào? Thường thì sẽ có chức năng cho phép người dùng gửi yêu cầu lấy mã khác khi mã hết hạn hoặc vì một lý do nào đó mà không nhận được mã OTP tương ứng.

Trên đây là 17 ý tất tần tật mà mình nghiên cứu tìm hiểu được, các bạn có ý kiến hay bổ sung gì thì đừng ngần ngại để lại bình luận phía dưới cho mình nhé! Cũng đừng quên chăm chỉ luyện tập nữa nha! 😀

Bài viết gốc được đăng tải tại vananhtooo.wordpress.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Con đường trở thành Business Analyst của Tester

Con đường trở thành Business Analyst của Tester

Bài viết được sự cho phép của vntesters.com

Chia sẻ của bạn Nguyễn Dương Hải về quá trình trở thành một BA từ QC.

Trong một năm trở lại đây, nó là câu hỏi mà mình luôn tìm kiếm và khám phá. Mình có background 6 năm là QC, và chuyển từ QC sang BA dường như là một thách thức rất lớn, không chỉ đơn giản vì nó khó khăn cho bạn, mà còn là cách đánh giá của người khác về bạn nữa. QC có những lợi điểm khi chuyển thành BA, nhưng cũng có không ít nhược điểm, đặc biệt là về mặt mindset, thậm chí là so với một fresher. Hôm nay, mình viết bài này để chia sẻ về việc mình đã rèn luyện những skill cần thiết cho một BA khi vẫn còn là một QC như thế nào. Khi đã có được skill và mindset, vấn để chỉ còn là bạn có muốn follow theo con đường đó hay không.

Việc làm testertìm việc Business Analyst lương cao

1/ Đừng chỉ làm, hãy tìm hiểu lý do và lợi ích

Như là một QC, mình ngày ngày có nhiệm vụ là dựa vào requirement để viết ra test case bao phủ nó, để đảm bảo sản phẩm làm ra đạt ‘chất lượng’. Như là QC, mình từng coi requirement là tuyệt đối, sản phẩm sẽ hoàn hảo nếu làm giống requirement. Nhưng sự thật là, kể cả mình khi dùng product mình làm ra cũng gặp vấn đề, đừng nói gì end user. Hơn nữa, có những feature mình làm mà chẳng User nào dùng, hoặc được một thời gian thì client nói nên đập đi làm lại!! Mình bắt đầu đặt câu hỏi “Tại sao chúng ta lại làm ra flow này?”, “Nó giúp ích gì cho user?”. Ngắn gọn hơn, mình bắt đầu muốn tham gia vào việc làm ra requirement.

Cách đây hơn 6 năm, ở công ty cũ của mình, khi mình nói là muốn join vào meeting của BA và client, đã có người cười vào mặt mình ^^. Sau đó, mình cứ đợi đến khi BA và team meeting với client là mình mở cửa phòng họp đi vô. Mọi người khá ngạc nhiên nhưng không nói gì vì nói thì client sẽ nghe ^^. Sau đó, mình nhận nhiều feedback về việc tự tiện này và khuyên mình nên quay lại với task của mình. Mình vẫn phải đảm bảo task QC được hoàn thành trong khi spend extra time cho việc này. Ngoài ra, bạn cũng phải vô cùng ý tứ. Thời gian đầu, mình chỉ ngồi im và nghe, rồi dùng kiến thức đó để hỏi BA sau này. Sau này, mình mạnh dạn hơn, khi mình chắc chắn cái mình nói sẽ có value thì hãy nói, và đó là tiền đề để team chấp nhận mình hơn trong những buổi nghe và discuss về requirement.

Những meeting này là kinh nghiệm vô giá. Bạn được nghe ý tưởng từ đầu, cũng giống như bạn là Developer và bạn nhìn thấy những dòng code system đầu tiên vậy. Nó sẽ giúp bạn hiểu về requirement rất nhiều. Không! Không phải là requirement, mà là nhu cầu của khác hàng. Bạn cũng sẽ học được cách nói chuyện và giải thích khách hàng của BA. Tuy nhiên, hãy để ý vị trí của bạn. BA sẽ là người mặc định được nói chuyện với client và đề ra giải pháp. Đừng có thái độ lấn quyền khi bạn chưa chắc bạn đang nói gì. Mình từng NHIỀU lần sai phạm và nó sẽ trả giá đắt đó!

Với khả năng gà vịt của bạn lúc đầu, chắc chắn là sẽ không hiểu hết. Hãy đem thắc mắc của mình, suy nghĩ câu chữ và ý tưởng cho thật kỹ, và đem tới hỏi BA. Lúc đầu, sẽ có rất nhiều câu hỏi stupid và những câu không đáng hỏi ( quá chi tiết, đợi document ra sẽ có). Hãy nhận lỗi và improve. Mình cũng phải cám ơn 2 chị BA ở Pyco Group đã rất kiên nhẫn với mình.

Chưa hết, hãy theo dõi calendar và lịch trình trao đổi với client của BA. Một trong những điều quan trọng nhất của BA là phải biết lấy requirement từ đúng người, đúng thời điểm. Bằng việc tìm hiểu BA lấy được requirement, confirmation này từ ai sẽ là một điều quan trọng sau này cho bạn.

Dần dà, bạn sẽ biết cách nghe và hiểu được cái client muốn là gì. Bạn cũng sẽ biết cách và thời điểm để đặt câu hỏi. Đó sẽ là tiền đề cho những phát triển sau này trong BA skill set.

2/ Nói chuyện với End User

Đây là cái mình học được ở Atlassian Viet Nam. NIHITO – Nothing Important Happen Inside The Office. Mặc dù theo mình thì có rất nhiều cái thú vị ở office, nhưng ngoài kia, khi bạn nói chuyện với end user, sẽ là một trải nghiệm hoàn toàn khác. Chỉ khi bạn thật sự ra ngoài và lắng nghe end user kể về pain point của họ, bạn mới hiểu là product của bạn cần làm gì, để giải quyết điều gì. Việc tìm đúng end user, người sẽ là target của bạn cũng sẽ là một challenge thú vị. Nó sẽ giải quyết rất nhiều yếu điểm trong giải pháp của chúng ta. Có bao giờ bạn ngồi trong phòng họp, bạn, BA, PM,… tranh cãi rất nhiều về việc nên làm feature này thế nào cho tốt, nhưng chưa có ai thực sự có evidence nào để back up cho ý kiến của họ. Đã có ai từng tới để hỏi end user về vấn đề này?

Ở một số công ty lớn, việc làm những buổi UX testing hay UX research/ interview sẽ được handled bởi PO, hoặc 1 role riêng là UX researcher. Tuy nhiên, QC sẽ là một assistant tốt. Lý do là vì:

  • Bạn có good knowledge về product. Bạn có thể giúp cho test user nắm được một số điểm chính trong hệ thống nếu họ bị stuck. Một mình PO sẽ không làm xuể chuyện này
  • Như là QC, bạn có con mắt quan sát tốt. Bạn sẽ dễ nhận ra user nào đang cảm thấy thích feature và user nào đang khó chịu với nó. PO thường mang QC vào phòng quan sát để theo dõi và discuss reason với họ về hành vi của end user.
  • Bạn có những góc nhìn rất thú vị về product. Thường thì PO, hay BA sẽ nhìn product dựa trên happy case là chủ yếu. Còn bạn, với thâm niên của QC, bạn sẽ có khuynh hướng focus vào unhappy case hơn. Tuy nhiên, hãy nhớ chỉ raise lên unhappy case khi mà bạn tin rằng use case này sẽ có ảnh hưởng lớn đến user khi gặp lỗi, làm họ muốn leave. Hãy tập control và loại bỏ những case không quá quan trọng đi

Ở công ty nhỏ, làm product nhỏ, bạn có thể chỉ đơn giản là mang product của bạn, khéo léo hỏi 1 vài đồng nghiệp không làm product này xem họ thấy thế nào về product? Mình từng tổ chức rất nhiều session như vậy, chỉ cần mời được khoảng 5 người là bạn đã có những feedback giá trị về feature của bạn rồi.

Hãy tập lắng nghe complain của mọi người nhiều hơn, và try your best để advice họ ^^, kể cả trong văn phòng và ngoài đời. Bạn sẽ dễ dàng nhận ra là sau này, khi bạn nói chuyện, lời nói của bạn sẽ có xu hướng tập trung để giải quyết vấn đề nhiều hơn là than vãn ^^. Những kinh nghiệm ngoài đời sống cũng sẽ giúp ích rất nhiều. Đừng tự thu mình lại chỉ trong văn phòng làm việc, và cũng đừng suy nghĩ theo hướng ‘mọi việc đã vậy rồi, không sửa dược đâu’

Nói tóm lại, gặp mặt và nói chuyện với end user sẽ giúp bạn có những thông tin và kinh nghiệm vô cùng giá trị để tư vấn, làm cho sản phẩm tốt hơn. Nó cũng sẽ giúp bạn rèn luyện thói quen “speak with evidences”, điều rất quan trọng sau này khi bạn muốn thuyết phục client hay team member của bạn về một feature.

3/ Nâng cao việc communicate với member trong team

Đây là cái mà QC chúng ta thường hay làm, và thường hay làm sai. Mình không biết các bạn thế nào, nhưng có một thời gian mình chỉ đem process, requirement, và rule để đi nói chuyện với bộ phận khác, đặc biệt là với developer. “Bug! Nó sai với requirement!”, “Bản build này fail rồi! Nó có 3 lỗi critical nè!”,…. Như là QC, mình sẽ không bàn đúng sai ở đây. Tuy nhiên, cách tiếp cận đó bạn sẽ không còn dùng được nữa khi là BA. Requirement có thể nói là do bạn tạo ra (hoặc bạn và PO), nhiệm vụ của bạn là thuyết phục client và team member tin rằng đó là approach đúng bằng bằng chứng và lý lẽ. Get được user’s feedback sẽ là một backup quan trọng cho bạn. Chuyển tư duy và cách communicate là một việc quan trọng để trở thành BA.

Hơn thế nữa, dù là QC hay BA, bạn cần phải biết về technical. Đặc biệt là BA, vì giải pháp phải khả thi mới là giải pháp tốt. Giải pháp là vô nghĩa nếu team bạn không thể làm ra nó được, hoặc nó không phù hợp với system hiện tại được. Bạn cần làm việc kỹ hơn với Developer để hiểu rõ system và công nghệ của chúng ta có yếu điểm gì, có thể làm được gì. Hơn thế nữa, sẽ luôn luôn có những thắc mắc từ client về cách làm của Developer và ngược lại. Bạn sẽ là người đứng giữa để giải quyết những khúc mắc đó. Hãy join với Developer khi họ nói về building system, database,… để thu thập thêm kiến thức và học cách chuyển tải nó thành ngôn ngữ cho non-tech member

4/ Quality không phải là quan trọng nhất nữa. Hãy làm quen!

Như mình có đề cập một chút ở phần 2/. Khi là QC, bạn chỉ cần quan tâm về quality. Tuy nhiên, nếu muốn trở thành BA, bạn phải hiểu rằng một product tốt là một product balance được về Cost, Scope và Quality. Đôi khi BA sẽ đi đến quyết định release một feature với những flow chính đảm bảo chỉ để bắt kịp với xu thế thị trường, hoặc bạn chưa biết là User phản ứng thế nào nên bạn chỉ release ra với mục đích lấy thêm feedback. Bạn sẽ phải tập làm quen và chấp nhận với những mindset đó.

  Business Analyst (BA) là gì? Học gì để trở thành một BA
  Con đường trở thành Business Analyst của Tester

5/ Hãy tập handle vài task của BA

Sẽ rất fun, mình hứa với bạn đấy ^^! Đây là những công việc hồi đó mình chịu làm extra cho team:

  • Update requirement: Tới hỏi BA “Cái flow này thì sao chị?”, thì BA nói “Uh, em nghĩ đúng rồi đó. Chị bận quá! Em giúp chị update được không?”. Hãy cố gắng nhận những task nhỏ, đã có ví dụ về structure từ trước để add vào requirement. Thường là requirement cho Edge cases. Nó sẽ giúp bạn hiểu hơn về cách làm ra document.
  • Làm culi hỏi việc cho Developer: Developer hay có suy nghĩ là mình làm gì cũng được, miễn sao thằng QC này cho mình pass là được, nên thay vì là làm đúng theo cái BA muốn, thì chuyển nó thành làm đúng theo cái QC muốn. Điều này dẫn đến việc Dev sẽ hỏi bạn về expect của bạn, thay vì là BA. Đương nhiên, như là QC bạn sẽ cần hỏi BA về những quyết định của mình. Dần dà, thậm chí có một số những quyết định nhỏ bạn có thể tự quyết định, và nói lại với BA update document sau
  • Tập vẽ User flow: Theo mình thấy, User flow là thứ ngôn ngữ đơn giản và chung nhất mà tech và non-tech có thể hiểu được. Mình hay dùng cái này để nói chuyện với mấy anh Dev. Rồi về sau nó có thể được add vào text requirement luôn. Đôi khi chỉ đơn giản là người ta chụp cái hình bạn vẽ nguệch ngoạc trên bảng thôi ^^.
  • Handle một số job về database: Database testing sẽ tốt. Ngoài ra, hồi xưa, client của mình thỉnh thoảng còn có nhu cầu kêu team mình export ra data cho người ta theo kiểu “Trong tuần này có bao nhiêu thằng User tăng 10 fan vậy?” Nếu không quá bận, QC có thể làm nó được. Hiểu về database system sẽ là một điều rất tốt cho vị trí BA sau này.

Sau này, bạn sẽ thấy có những công ty yêu cầu bạn biết vẽ rất nhiều loại diagram, và có hiểu biết về cả database structure nữa. Những công việc kia sẽ là hành trang quý báu cho bạn khi bước tiếp như là BA.

Lời kết

Mình hy vọng qua bài viết này các bạn QC nói riêng cũng như các bạn đang muốn chập chững bắt đầu công việc BA nói chung sẽ có những bước đi đầu tiên hiệu quả cho việc trở thành BA của bạn. Đương nhiên, để trở thành một BA thực thụ và chuyên nghiệp sau này sẽ còn nhiều điều bạn phải học, và tất cả những điều mình nói ở trên bạn sẽ phải làm cho thật nhuần nhuyễn. Chúc bạn thành công trên con đường trở thành BA!

Bài viết gốc được đăng tải tại vntesters.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Các tính chất chính của một hệ thống phân tán

Các tính chất của hệ thống phân tán

Bài viết được sự cho phép của tác giả Edward Thiên Hoàng

Cùng với Algorithm thì System Design là một phần rất quan trọng trong phỏng vấn và tuyển dụng, nhất là bạn ứng tuyển với vị trí từ Senior trở lên. Và để cùng tôi chuyển bị tốt cho đợt phỏng vấn tuyển dụng sắp tới, ta hãy cùng nhau tìm hiểu về những điều cơ bản và sơ lược nhất về thiết kế hệ thống nhé. Nói trước đây là một bài viết siêu dài, mời các bạn hãy ngồi xuống thư giãn và làm ly trà sữa cho tăng mood 😋 và bật nhạc thư giãn 🎼 trước khi đọc bài nhé.

  Giải mã bí ẩn "system load" trên Linux
  System Admin là gì? Mô tả công việc vị trí System Administrator

Các tính chất chính của một hệ thống phân tán

Hệ thống phân tán (distributed system) là hệ thống phần mềm mà các thành phần cấu tạo nên nó nằm ở trên các máy tính khác nhau được kết nối thành mạng lưới (network). Các máy tính này phối hợp hoạt động với nhau để hoàn thành một nhiệm vụ chung bằng cách trao đổi qua lại các thông điệp (message)

Nói nôm na là hệ thống phân tán là việc hệ thống bạn có nhiều quá trình xử lý độc lập trên nhiều nhiều server vật lý khác nhau.

Với các hệ thống doanh nghiệp lớn (enterprise) đòi hỏi sự linh hoạt trong mở rộng bảo trì thì distributed system là một lựa chọn hoàn hảo.Và các tính chất chính để hình thành một hệ thống phân tán là: Khả năng mở rộng(Scalability), Độ tin cậy (Reliability), Tính khả dụng (Availability), Hiệu suất (Efficiency) và Tình mở rộng và khả năng bảo trì (Manageability).

1. KHẢ NĂNG MỞ RỘNG (SCALABILITY)

Scalability là khả năng mở rộng (scaling) của hệ thống (system), quy trình (process) hay mạng lưới (network), với nhu cầu gia tăng về số lượng công việc tăng theo thời gian của mô hình kinh doanh (business model).

Mô hình kinh doanh có thể mở rộng quy mô vì nhiều lý do như gia tăng khối lượng dữ liệu lưu trữ (data storage) hay khối lượng công việc (process/request) , ví dụ: số lượng truy cập hay đặt hàng của một hệ thống thương mại điện tử. Và yêu cầu của sự mở rộng phải đạt được nhu cầu này mà không làm giảm hiệu suất, nói chung Scalability là đáp ứng được sử mở rộng hay giảm theo kích thước của hệ thống theo thời gian.

Có hai dạng scaling là mở rộng theo chiều ngang (vertical scaling) và mở rộng theo chiều dọc (horizontal scaling).
– Vertical scaling: là cách mở rộng server hiện tại bằng cách nâng cấp độ mạnh (power) bằng cách nâng cấp CPU, Ram, Storage, v.V… Vertical-scaling thường bị giới hạn bởi vượt quá khả năng về cấu hình vật lý hiện đại hay độ trễ khi “chẳng may” Server bị downtime để nâng cấp hay deploy hệ thống.
– Horizontal scaling: là cách mở rộng bằng cách thêm nhiều Node/Server vào một mạng lưới đang có, làm tăng khả năng chịu tải có hệ thống. Cách làm này rẻ và dễ làm hơn so với Vertical-scaling, đặc biệt là rất dễ dàng downsize cũng như upsize hệ thống

– Horizontal scaling: là cách mở rộng bằng cách thêm nhiều Node/Server vào một mạng lưới đang có, làm tăng khả năng chịu tải có hệ thống. Cách làm này rẻ và dễ làm hơn so với Vertical-scaling, đặc biệt là rất dễ dàng downsize cũng như upsize hệ thống

Các tính chất chính của một hệ thống phân tán

Một ví dụ của Horizontal-scaling là MongoDB và Cassandra, cả hai đều cung cấp sẵn những phương pháp để scale hệ thống bằng cách thêm nhiều node vào hoặc xóa bớt các node mà không hề có độ trễ (zero downtime). Và một ví dụ khác về Vertical-scaling là MySQL, nó có thể dễ dàng chuyển đổi một Server đang chạy sang một Server mới lớn hơn khỏe hơn, nhưng quá trình có downtime.

2. ĐỘ TIN CẬY (RELIABILITY)

Reliability có thể giải thích dân dã rằng đó là độ “lì” 💪 của hệ thống có nghĩa là hệ thống sẽ tiếp tục cung cấp dịch vụ của mình ngay khi có một hoặc nhiều thành phần (phần mềm/phần cứng) của hệ thống bị lỗi. Reliability là thành phần chính trong bất cứ một hệ thống phân tán (distributed system) nào, bởi vì trong một hệ thống như vậy, mọi hỏng hóc của một thành phần nào đó sẽ được thay thế một thành phần đang khỏe mạnh khác, đảm bảo luôn hoàn thành nhiệm vụ yêu cầu.

Ví dụ của độ tin cậy là, một trang thương mại điện tử hay hệ thống ngân hàng (banking) mọi thông tin về giao dịch (transaction) của người dùng sẽ không bao giờ bị hủy do lỗi server đang chạy giao dịch đó, mỗi server bị lỗi sẽ phải được thay thế ngay bởi một bản sao chứa đầy đủ thông tin của server đó.

Để đạt được độ tin cậy, hệ thống phải có chế độ back-up real time của từng thành phần trong hệ thống, đây cũng là một thách thức về mặt kỹ thuật cũng như chi phí của dự án.

3. TÍNH SẴN SÀNG (AVAILABILITY)

Tính sẵn sàng là thời gian một hệ thống vẫn hoạt động bình thường trong một khoảng thời gian cụ thể, đây là thước đo đơn giản về tỷ lệ phần trăm thời gian mà hệ thống hoạt động liên tục trong một khoảng thời gian bình thường. Ví dụ như một chiếc xe hơi có thể chạy trong nhiều tháng mà không cần bảo trì bảo dưỡng, thì có thể nói là chiếc xe đó có tính availability cao. Nếu chiếc xe hơi đó ngừng hoạt động để đem tới gara để bảo trì, nó được coi là không availability trong thời gian đó.

Sự khác nhau của độ tin cậy (reliability) và tính sẵn sàng (availability):
Nếu hệ thống có tính reliability thì nó chắc chắn sẽ có availability, tuy nhiên hệ thống có tính availability không có nghĩa là nó có tính reliability. Nói một cách khác thì reliability có nghĩa là nó có tính high availability, tuy nhiên vẫn có thể đạt được tính availability với một hệ thống không có tính reliability bằng cách giảm thiểu tối đa thời gian bảo trì, sửa chữa. Hãy lấy một ví dụ, một hệ thống eCommerce có tỷ lệ availability lên đến 99,99% trong hai năm đầu tiên nó bắt đầu, nhưng hệ thống có một lỗi tiềm ẩn về bảo mật mà trong quá trình kiểm thử (testing) không phát hiện ra, khách hàng không hề biết về điều đó và họ vẫn rất hạnh phúc (happy) với hệ thống, cho đến một ngày đẹp trời vào bỗng nhiên lỗi tiềm ẩn đó bị khai thác dẫn đến hệ thống giảm tính sẵn sàng trong một thời gian dài hơn bình thường cho đến khi lỗi được “hot fix” ngay lập tức.

Kỳ thực mà nói một hệ thống có độ tin cậy cao (high reliability) gần như rất khó đạt được trong thực tế, mà hầu như chúng ta chỉ hướng tới một hệ thống có tính sẵn sàng cao (high availability) mà thôi.

4. HIỆU SUẤT (EFFICIENCY)

Hiệu suất của một hệ thống phân tán là khả năng chịu tải (high load) và thời gian phản hồi (low latency). Có nghĩa là một hệ thống có khả năng chịu được nhiều request đồng thời với độ trễ thấp là một hệ thống có hiệu suất cao. Thông thường nó được đo đếm bằng số lượng request nó nhận được và phản hồi trong một khoảng thời gian, thường được tính bằng giây. Ví dụ một hệ thống eCommerce có hiệu suất là chịu được 5k lượt đặt hàng trên một giây — 5k order / second, hay 500k lượt người cùng truy cập vào cùng một thời điểm.

5. TÍNH MỞ RỘNG VÀ KHẢ NĂNG BẢO TRÌ (MANAGEABILITY)

Một tính chất quan trọng khác của một distributed system đó là khả năng dễ dàng mở rộng và bảo trì của hệ thống, nói cách khác là tốc độ của hệ thống khi thực hiện sửa chữa (repair) hay bảo trì (maintain) khi cần, nếu thời gian trên càng cao thì tính availability càng thấp. Để đạt được điều này, hệ thống cần phải dễ dàng phát hiện lỗi hoặc lỗi tiềm tàng nếu có, khả năng hiểu nhanh được nguyên nhân lỗi (root cause), dễ dàng thực hiện các thay đổi cần thiết để điều chỉnh, hoặc đơn giản chỉ là dễ dàng mở rộng khi cần.

Việc sớm phát hiện cũng như giải quyết vấn đề sớm sẽ làm giảm downtime từ đó tăng tính sẵn sàng của hệ thống đi lên. Ví dụ những ứng dụng doanh nghiệp (enterprise system) có khả năng tự phát hiện lỗi sau đó cô lập và báo cáo nhanh cho người vận hành hệ thống.

Theo medium

Bài viết gốc được đăng tải tại edwardthienhoang.wordpress.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Chuẩn bị môi trường cài đặt để chạy code C trên window

Chuẩn bị môi trường cài đặt để chạy code C trên window

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

OK chào bạn!

Đây là bài đầu tiên, tôi sẽ trình bày cho các bạn nắm được một số kiến thức cơ bản sau:

  •  Cài đặt được môi trình lập trình C trên window
  • Code C bằng notepad thay vì các IDE khác.
  Bí thuật đơn giản hóa code của bạn
  "Code dễ đọc" là như thế nào?

Chúng ta sẽ học từ từ, từng câu chữ tôi sẽ cố gắng làm sáng tỏ vấn đề cho bạn. Những phần nào bạn cảm thấy bối rối, hãy ngừng lại, hít một hơi dài, ra ban công ngắm em hàng xóm đang phơi đồ và vào đây ta lại tiếp tục. Nào let go!

1. Thế nào là window, linux?

Hẳn có bạn sẽ chưa biết nhiều về linux đâu, còn window thì có thể bạn biết nhiều rồi. Cái thời mới dùng máy tính để chơi LOL, bạn đã xài win xp, window 7, window 8 chứ chắc hẳn có bạn chưa chơi LOL trên linux đâu nhỉ :))

Mình chém thế thôi chứ Linux không support game nhiều, mà nó chủ yếu hỗ trợ việc học tập là chính. Nếu bạn muốn có một môi trường trong lành, không game(vì muốn chơi cũng lằng nhằng mới cài được), dùng toàn dòng lệnh hại não hơn thằng window, thì hãy dùng linux và lập trình. Đặc biệt lập trình C mà chơi với linux thì giống như là nằm ngủ mà có gấu ôm ấy, phê cực kỳ!

Bạn có 2 chọn lựa để chơi với linux, 1 là bạn cài thẳng hệ điều hành của nó lên. Tôi nói linux là nhân hệ điều hành, giống như 1 bộ não vậy. Có nhiều hệ điều hành nhân linux, bạn có thể cài ubuntu, kali linux… Còn nếu bạn ghét phải cài nhiều hệ điều hành trên 1 máy, tôi sẽ giúp bạn cài môi trường hao hao linux trên window cho bạn để bạn code C. Bạn sẽ dùng dòng lệnh để build chương trình, mới đầu thì hơi hoảng khi phải làm quen với em C trên linux. Nhưng không sao, bạn đẹp trai bạn có quyền tán!

OK vậy là bạn đã hiểu láng máng về linux rồi, bây giờ tôi sẽ giới thiệu môi trường build C trên linux và window khác nhau như nào. Tưởng tượng từng đoạn text bạn code ra, nó giống như con bò bạn cho vào cái máy, thì cái máy đó nó sẽ nhào trộn, cho mắm muối, gia vị, nén lại thành từng thỏi xúc xích cho bạn ăn. Xúc xích bò thì ngon lắm :)) Cái máy đó nó sản xuất cho các bạn thích ăn xúc xích to bằng ngón tay thì khác, còn bạn nào muốn thỏi xúc xích to bằng quả chuối nó lại khác. Việc bạn chế biến bằng máy cũng giống như bạn dùng hệ biên dịch để build vậy. Tôi chém rồi :)) Rõ ràng window ví như muốn ăn to bằng ngón tay còn linux bạn muốn nó to bằng quả chuối. Vậy ở 2 môi trường này cần 2 hệ biên dịch code C khác nhau đúng không nào? Vậy window dùng gì để build code C, còn linux dùng gì để build code C? Bạn sẽ biết ngay sau đây.

2. Biên dịch code C trên Linux khác với Window như nào?

GNU C/C++ compiler là cái máy chế biến C/C++ cho linux, còn MinGW thì là cái máy chế biến C/C++ cho window. Cái xúc xích thành phẩm của bạn ở đây có thể là 1 file exe thực thi như các bạn hay thấy. Hoặc có thể là file dll, file .o, file .lib… Nhiều thể loại lắm, bạn cứ từ từ mà xem em C của chúng ta có rất nhiều tài năng, toàn thứ hay ho không. Bạn sẽ tán em C bằng cách tán từ trong ruột tán ra, đảm bảo chén sạch từ trên xuống dưới nhé. OK, vậy bây giờ chúng ta cần tải cái máy MinGW  này về và cài vào máy window của chúng ta. Bạn thích dùng win 7, win 8 hay 10 đều thoải mái nhé. Chúng ta chỉ quan tâm hệ điều hành của bạn đang ở dạng x64 hay x86 mà thôi. Thế 2 thằng này là cái gì? Ồ bạn chỉ hiểu nôm na thằng x64 nhiều thanh ghi hơn nên tốc độ nhanh hơn, còn x86 thì chậm hơn xíu, kiến trúc khác nhau nên bộ cài cũng khác nhau nốt. Vậy để kiểm tra hệ điều hành của bạn đang ở 64 hay 86 thì làm như nào? Đơn giản lắm, bạn hãy ngó xuống bàn phím máy tính, tìm cái nút hình cửa sổ, ghì chặt nút đó và nhấn thêm nút R, bạn sẽ thấy 1 ô hiển thị lên, bạn nhập cmd và nhấn ENTER cái tạch! Như 1 hacker, màn hình đen sì console nổi lên. Bạn gõ tiếp systeminfo vào và ENTER tạch cái tiếp.

Bạn sẽ thấy thông tin na ná như sau:

Chuẩn bị môi trường cài đặt để chạy code C trên window

Máy của mình nó hiện lên x64 thì mình là hệ 64bit. Còn máy bạn có thể x86 thì là 32 bit lắm :))

Rồi mời bạn nhổ 1 sợi lông chân và tiếp tục đọc cho tỉnh táo!

Nãy giờ tôi hù bạn tí thôi. Tôi đã chuẩn bị 1 bộ build để bạn chả cần quan tâm máy bạn là x86 hay x64 nữa, nó hỗ trợ cho cả 2 luôn. Bạn chọn vào link sau để tải về:

Nhấp vào đây để tải về

Bạn chỉ cần giải nén file zip ra là được. Ví dụ mình giải nén ở ổ G như này:

G:\Setup_program\MinGW

Bây giờ vẫn chưa xong. Bạn sẽ phải ghi tên cái thằng MinGW này cho hệ điều hành nó hiểu. Đơn giản như sau.

Bạn nhấn nút cửa sổ trên bàn phím, sau đó nó sẽ ra ô search. Bạn gõ tiếp enviroment rồi nhấn Enter.  Hoặc nếu tìm không ra thì vào theo cách:

Control Panel-> <strong>Environment Variables -> System Variables-> Path</strong>

Màn hình trên window 8 của mình như này:

Chuẩn bị môi trường cài đặt để chạy code C trên window

Sau đó, bạn vào mục path thêm dòng này, nhớ đặt ; đằng trước để ngăn cách:

<Thư mục giải nén  MinGW của bạn>\bin

ví dụ của mình:

G:\Setup_program\MinGW\bin

Tới đây bạn check lại 1 lần nữa xem nó ok ngon lành cành đào chưa bằng cách sử dụng CMD như mình đã hướng dẫn. bật cmd và chạy lệnh:

gcc

Nếu như nó hiển thị ra thông báo như này là ok:

Chuẩn bị môi trường cài đặt để chạy code C trên window

Bạn thở phào nhẹ nhõm chưa? =))

Vậy là bạn đã bày binh bố trận để chiến em C này rồi. Việc còn lại là chuẩn bị hoa lá kèn, quà cáp và xơ múi em ấy một ngày không xa.

Trong bài tiếp mình sẽ hướng dẫn bạn code những dòng đầu tiên :))

happy!

Bài viết gốc được đăng tải tại quynhlaptrinhc.wordpress.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Hướng dẫn tạo Copyright Header trên từng file .cs trong Visual Studio

Hướng dẫn tạo Copyright Header trên từng file .cs trong Visual Studio

Bài viết được sự cho phép của tác giả Nguyễn Thảo

Xin chào các bạn, bài viết hôm nay mình sẻ hướng dẫn các bạn cách tạo Copyright header trên file .cs trong Visual Studio.

[C#] Add copyright header visual studio

Dưới đây là hình ảnh mình đã thêm copyright thông tin của mình vào file C#.

  Những Visual Studio Code Extensions không thể bỏ qua khi lập trình Angular v2+
  Sử dụng Machine Learning để visualize customer preferences

Hướng dẫn tạo Copyright Header trên từng file .cs trong Visual Studio

Bây giờ, mình sẽ hướng dẫn các bạn cách thêm

Bước 1:

Các bạn tạo mới cho mình một file .editorConfig, File này các bạn tạo theo template của mình như hình bên dưới.

Hướng dẫn tạo Copyright Header trên từng file .cs trong Visual Studio

Và bây giờ bạn tìm đến dòng có chữ file_header_template và chúng ta sẽ thêm thông tin copyright của mình ở đây như hình bên dưới:

Hướng dẫn tạo Copyright Header trên từng file .cs trong Visual Studio

[*.{cs,vb}]
file_header_template = Copyright (c) ThaoMeo 2000. All rights reserved.\nLicensed under the laptrinhvb.net license.\nEmail: nguyenthao.laptrinhvb@gmail.com.\nTel: 0933.913.122
C#

Các bạn xuống dòng bằng dấu “\n” nhé.

Bây giờ, các bạn lưu lại là xong.

Và bây giờ khi các bạn tạo mới file .cs nào thì thông tin copyright header này đều có xuất hiện.

Còn ở class nào chưa có thêm thông tin, các bạn chọn ngay dòng đầu tiên và nhấn phím (Ctrl + .) => chọn Add header file như hình dưới đây.

Hướng dẫn tạo Copyright Header trên từng file .cs trong Visual Studio

Vậy là xong!

Chúc các bạn thành công. <3

Bài viết gốc được đăng tải tại laptrinhvb.net

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

40 phím tắt dành cho người dùng Windows

40 phím tắt dành cho người dùng Windows

Bài viết được sự cho phép của tác giả Nguyễn Trần Chung

40 PHÍM TẮT DÀNH CHO NGƯỜI DÙNG WINDOWS (Giúp bạn tiết kiệm 60% thời gian làm việc trên máy tính)

Ctrl + C: Sao chép đối tượng đã chọn

Ctrl + X: Cắt (Cut) đối tượng đã chọn

Ctrl + V: Dán (Paste) đối tượng đã chọn

Ctrl + Z: Quay lại thời điểm trước đó (Undo)

Ctrl + A: Chọn tất cả.

  Tổng hợp phím tắt Sublime Text
  Expressjs là gì? Framework mạnh mẽ Nodejs Express

Ctrl + một phím di chuyển (trái/phải/lên/xuống): Chọn nhiều tập tin/thư mục rời rạc.

Ctrl + Shift + một phím di chuyển (trái/phải/lên/xuống): Chọn nhiều tập tin/thư mục liên tục.

Ctrl + Shift + dùng chuột kéo đi: Tạo shortcut cho tập tin/thư mục đã chọn.

Ctrl + phím di chuyển sang phải: Đưa trỏ chuột tới cuối từ đang đứng sau nó.

Ctrl + phím di chuyển sang trái: Đưa trỏ chuột lên ký tự đầu tiên của từ trước nó.

Ctrl + phím di chuyển xuống: Đưa trỏ chuột đến đầu đoạn văn tiếp theo.

Ctrl + phím di chuyển lên: Đưa con trỏ chuột đến đầu đoạn văn trước đó.

Ctrl + Esc: Mở Start Menu, thay thế phím Windows.

Ctrl + Tab: Di chuyển qua lại giữa các thẻ của trình duyệt theo thứ tự từ trái sang phải.

Ctrl + Shift + Tab: Di chuyển qua lại giữa các thẻ của trình duyệt theo thứ tự từ phải sang trái.

Ctrl + F4: Đóng cửa số hiện hành của trong chương trình đang thực thi.

Ctrl + Alt + Tab: Sử dụng các phím mũi tên để chuyển đổi giữa các ứng dụng đang mở.

Ctrl + Shift + Esc: Mở Task Manager

Ctrl + Esc: Mở Start menu

Alt + Enter: Mở cửa sổ Properties của tập tin/thư mục đang chọn.

Alt + F4: Đóng một chương trình.

Alt + Tab: Chuyển đổi qua lại giữa các chương trình đang chạy

Alt + Esc: Chọn có thứ tự một cửa sổ khác đang hoạt động để làm việc.

Alt + nhấn chuột: Di chuyển nhanh đến một phần của văn bảng từ mục lục.

Alt + F8: Hiển thị mật khẩu trên màn hình đăng nhập.

Alt + phím mũi tên trái: Quay lại trang trước.

Alt + phím mũi tên phải: Đi về trang phía sau.

Alt + phím cách: Mở menu shortcut cho cửa sổ hiện hành.

Backspace: Trở lại danh mục trước đó, tương tự Undo.

Shift: Giữ phím này khi vừa cho đĩa vào ổ đĩa quang để không cho tính năng “autorun” của đĩa CD/DVD tự động kích hoạt.

Shift + Delete: Xóa vĩnh viễn tập tin/thư mục mà không cho vào thùng rác.

Shift + F10: Mở menu shortcut cho đối tượng đã chọn

Enter: Xác nhận dữ liệu đã nhập thay cho các nút của chương trình, như OK,…

F1: Mở phần trợ giúp của một phần mềm.

F2: Đổi tên đối tượng đã chọn

F3: Mở tính năng tìm kiếm tập tin/thư mục trong My Computer.

F4: Mở danh sách địa chỉ trong mục Address của My Computer.

F5: Làm tươi các biểu tượng trong cửa sổ hiện hành.

F6: Di chuyển xung quanh các phần tử của màn hình trên một cửa sổ hay trên desktop

F10: Truy cập vào thanh Menu của ứng dụng hiện hành

Tab: Di chuyển giữa các thành phần trên cửa sổ.

Với phím Windows:

Windows: Mở hoặc đóng menu Start

Windows + Break: Mở cửa sổ System Properties.

Windows + D: Ẩn/hiện màn hình desktop.

Windows + M: Thu nhỏ cửa sổ hiện hành xuống thanh taskbar.

Windows + E: Mở File Explorer để xem các ổ đĩa, thư mục.

Windows + F: Tìm kiếm chung.

Ctrl + Windows + F: Tìm kiếm dữ liệu trong My Computer.

Windows + F1: Xem thông tin hướng dẫn của hệ điều hành/

Windows + L: Khóa màn hình máy tính

Windows + R: Mở cửa sổ Run.

Windows + U: Mở Ease of Access Center trong Control Panel.

Windows + A: Mở Action center

Windows + C: Mở Cortana trong chế độ nghe

Windows + Alt + D: Hiển thị, ẩn ngày giờ trên máy tính.

Windows + I: Mở Settings

Windows + P: Chọn chế độ hiển thị trình bày (khi kết nối với máy chiếu, màn hình ngoài)

Bài viết gốc được đăng tải tại chungnguyen.xyz

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Unit Test – Những bước chân đầu tiên

Unit Test – Những bước chân đầu tiên

Bài viết được sự cho phép của BBT Tạp chí Lập trình

Giới thiệu

Chất lượng công việc là một trong những yếu tố quan trọng xác định thành công của bạn tại nơi làm việc. Có nhiều cách để làm điều này trong lĩnh vực công nghệ phần mềm. Nhưng có một cách dễ dàng và hiệu quả là áp dụng kiểm thử. Lý do đơn giản là khả năng viết mã đạt chất lượng thường quan trọng hơn nhiều so với việc viết một khối lượng lớn mã khó bảo trì và tồn tại nhiều lỗi.

  04 Điều Cần Chú Ý Cho Người Mới Làm Automation Test
  Hiệu quả của testing với TDD trong Laravel

Unit Test (Kiểm thử đơn vị) là kỹ thuật kiểm thử những khối thành phần nhỏ nhất trong phần mềm (thường là các hàm hoặc phương thức). Đây là một trong những cấp độ kiểm thử đơn giản và có thể bắt đầu sớm trong vòng đời phát triển phần mềm. Thậm chí, bạn có thể viết unit test trước khi viết mã. Tuy nhiên, đây không phải là một thuật ngữ mới trong lĩnh vực phần mềm. Khái niệm unit test xuất hiện lần đầu trong ngôn ngữ lập trình Smalltalk vào những năm 1970. Đến nay, unit test gần như đã trở thành một chuẩn mực trong ngành bởi mục đích của nó là phục vụ yêu cầu nâng cao chất lượng sản phẩm phần mềm.

“Hành trình vạn dặm bắt đầu từ một bước chân.” – Lão Tử

Với nhiều lập trình viên, dù mới vào nghề hay đã gạo cội, thì unit test là một trong những kỹ năng không thể thiếu khi làm việc. Nếu bạn chưa từng nghe qua hoặc chưa có điều kiện thực hành thì cùng bước những bước chân đầu tiên qua bài viết này nhé!

Bài viết này có gì

Với bài viết này, bạn học được những nội dung sau:

  • Một số khái niệm cơ bản trong hoạt động testing và unit testing
  • Sử dụng JUnit trong dự án Java nói chung
  • Kết hợp Mockito và JUnit để thực hiện việc kiểm thử trong một số tình huống thực tế
  • Case Study và những bài học khi thực hiện kiểm thử

Lợi ích của Unit Testing

  • Tách rời việc kiểm thử với mã nguồn; không cần viết mã vào phương thức main() để có thể kiểm tra phương thức có hoạt động đúng đắn hay không.
  • Duy trì một bộ kiểm thử liên tục được cập nhật.
  • Đảm bảo mã mới không ảnh hưởng và gây lỗi tới những chức năng hiện có (qua việc thực hiện chạy lại toàn bộ bộ test đã viết từ trước).

Thuật ngữ

Để đọc hiểu nội dung hướng dẫn này, bạn cần biết đến một số thuật ngữ thường được sử dụng trong các hoạt động kiểm thử.

Test case

Test case là các trường hợp cần kiểm thử với đầu vào và đầu ra được xác định cụ thể. Một test case thường có hai thành phần dưới đây:

  • Expected value: Giá trị mà chúng ta mong đợi khối lệnh trả về
  • Actual value: Giá trị thực tế mà khối lệnh trả về

Sau khi thực hiện khối lệnh cần kiểm thử, chúng ta sẽ nhận được actual value. Lấy giá trị đó so sánh với expected value. Nếu hai giá trị này trùng khớp nhau thì kết quả của test case là PASS. Ngược lại, kết quả là FAIL.

Application (hoặc Code) Under Test

Application Under Test (AUT) là thuật ngữ thường được dùng để chỉ đến hệ thống/ứng dụng đang được kiểm thử. Với hoạt động unit test, các đơn vị kiểm thử của chúng ta là những thành phần nhỏ nhất trong hệ thống nên có thể dùng các thuật ngữ khác phù hợp hơn như Code Under Test (CUT).

Mock và Stub

Đây là các thành phần bên ngoài được mô phỏng hoặc giả lập trong ngữ cảnh của hoạt động kiểm thử. Thông thường, để AUT hoạt động đúng chức năng thì sẽ cần đến những thành phần bên ngoài như Web Service, Database,… Ở cấp độ unit test, chúng ta cần phải tách rời các thành phần phụ thuộc này để có thể dễ dàng thực thi test case. Phần này sẽ được giải thích rõ hơn trong mục Sử dụng Mockito (Mocking framework).

Lưu ý: Ngoài thuật ngữ mock và stub, thỉnh thoảng bạn sẽ gặp các từ khác như Spy và Fake.

Thiết kế test case

Trong phần này, chúng ta sẽ tìm hiểu các loại test case, cấu trúc thường gặp ở một test case và xem xét một số yếu tố tạo nên một test case tốt. Dựa vào các đặc tính đó, chúng ta sẽ tìm hiểu những nguyên tắc để có thể thiết kế và thực hiện được các test case tốt.

Phân loại test case

  1. Positive test case: Là những trường hợp kiểm thử đảm bảo người dùng có thể thực hiện được thao tác với dữ liệu hợp lệ.
  2. Negative test case: Là những trường hợp kiểm thử tìm cách gây lỗi cho ứng dụng bằng cách sử dụng các dữ liệu không hợp lệ.

Hãy làm rõ các loại test case trên qua một ví dụ đơn giản như sau. Giả sử, chúng ta đang thiết kế ứng dụng đặt phòng khách sạn và có một yêu cầu là:

Hệ thống cho phép khách hàng có thể đặt phòng mới với thời gian xác định.

Với yêu cầu trên, chúng ta có một số trường hợp cần kiểm thử như sau:

  • Trường hợp positive là đảm bảo có thể thêm phòng với các dữ liệu hợp lệ như mã phòng cần đặt, thời gian hợp lệ, mã khách hàng hợp lệ, giá tiền được tính với số ngày đặt,…
  • Còn các trường hợp negative sẽ cố gắng thực hiện thao tác đặt phòng với những dữ liệu không hợp lệ như:
  • Đặt phòng mới mà không có mã phòng
  • Đặt phòng mới với thời gian không hợp lệ (thời gian ở quá khứ)
  • Đặt phòng mới với mã khách hàng không tồn tại trong cơ sở dữ liệu
  • Đặt phòng mới với giá tiền âm (nhỏ hơn 0).
  • … và nhiều trường hợp khác

Hy vọng qua ví dụ trên, bạn có thể phân loại được các test case và tự xác định được các test case cho yêu cầu phần mềm mà bạn đang thực hiện.

Cấu trúc một test case

Các trúc mã mà chúng ta nên tuân thủ trong một test case là cấu trúc AAA. Cấu trúc này gồm 3 thành phần:

  • Arrange – Chuẩn bị dữ liệu đầu vào và các điều kiện khác để thực thi test case.
  • Act – Thực hiện việc gọi phương thức/hàm với đầu vào đã được chuẩn bị ở Arrange và nhận về kết quả thực tế.
  • Assert – So sánh giá trị mong đợi và giá trị thực tế nhận được ở bước Act. Kết quả của test case sẽ là một trong hai trạng thái sau:
  • PASS: nếu kết quả mong đợi và kết quả thực tế khớp nhau
  • FAIL: nếu kết quả mong đợi khác với kết quả thực tế

Đôi khi bạn sẽ bắt gặp một số bài viết dùng từ cấu trúc Given-When-Then. Về bản chất, cũng chính là cấu trúc AAA như trên.

Thành phần cố định (Fixtures)

Là những thành phần được lặp đi lặp lại qua mỗi test case và có thể chia sẻ các thao tác chung giữa các test case. Ví dụ: thiết lập cấu hình hoặc chuẩn bị dữ liệu trước khi bộ test được thực thi, và dọn dẹp bộ nhớ sau khi hoàn thành. Thành phần cố định phải được đặt lên trên cùng của bộ kiểm thử.

Có bốn loại thành phần cố định chính:

Setup

Là thành phần được thực thi trước khi test case thực thi. Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi unit test), chúng ta thường gặp những phương thức/hàm, hoặc annotion có tên là BeforeEach. Thành phần này chính là Setup.

One-Time Setup

Là thành phần được thực thi đầu tiên (trước cả khi cả setup và test case được thực thi). Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi unit test), chúng ta thưsờng gặp những phương thức/hàm, hoặc annotion có tên là BeforeAll. Thành phần này chính là One-Time Setup.

Teardown

Là thành phần được thực thi sau khi test case được thực thi. Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi unit test), chúng ta thường gặp những phương thức/hàm, hoặc annotion có tên là AfterEach. Thành phần này chính là Teardown.

One-Time Teardown

Là thành phần được thực thi sau cùng (sau khi tất cả test case và teardown được thực thi). Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi unit test), chúng ta thường gặp những phương thức/hàm, hoặc annotion có tên là AfterAll. Thành phần này chính là One-Time Teardown.

Đặc tính của một unit test tốt

Một ca kiểm thử tốt sẽ có những đặc tính sau đây:

  • Dễ viết – Có thể bao quát được nhiều trường hợp kiểm thử mà không mất quá nhiều công sức.
  • Dễ đọc – Có thể mô tả được chính xác hành vi hoặc chức năng được kiểm thử.
  • Tự động hoá – Có thể thực thi lặp lại nhiều lần.
  • Dễ thực thi và thực thi nhanh.
  • Đồng nhất – Luôn trả về cùng kết quả sau mỗi lần chạy (nếu không thay đổi mã nguồn bên trong).
  • Cô lập – Có thể thực thi độc lập mà không phụ thuộc vào các thành phần khác trong hệ thống. Bạn có thể tham khảo mục “Sử dụng Mockito” để làm rõ hơn ý này.
  • Khi kết quả kiểm thử thất bại (FAILED), có thể dễ dàng tìm ra giá trị mong đợi và nhanh chóng xác định được vấn đề.

Quy ước đặt tên

Tên lớp chứa mã kiểm thử

Tên lớp chứa mã kiểm thử thường sử dụng hậu tố “Tests” sau tên lớp được kiểm thử. Ví dụ: tên lớp là StockService thì tên lớp chứa mã kiểm thử sẽ là StockServiceTests.

Tên phương thức kiểm thử (test case)

Theo nguyên tắc, tên phương thức kiểm thử phải giải thích nhiệm vụ rõ ràng. Có thể tham khảo một số quy ướt đặt tên cho phương thức như sau:

  1. Sử dụng từ should. Ví dụ: favouriteStocksShouldbeSaved, todayPriceShouldBeShowed.
@Test
public void favouriteStocksShouldbeSaved() {}
  1. Viết theo mẫu Given[Đầu-Vào]When[Hành-Vi]Then[Kết-Quả-Mong-Đợi]. Ví dụ:
@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
  1. Viết theo mẫu when[hành-vi]_then[Kết-quả]
@Test
public void whenEnterValidUsernameAndPassword_thenLoginSuccessfully() {}

Gợi ý viết kiểm thử tốt

  1. Mỗi test case nên là một phương thức độc lập, có thể thực thi mà không phụ thuộc vào bất kỳ test case nào khác.
  2. Thứ tự thực hiện của mỗi test case không nên ảnh hưởng đến kết quả thực thi (mặc dù có thể).
  3. Khi phát hiện bug trong chương trình, hãy viết ngay kiểm thử cho trường hợp xảy ra bug đó để có thể kiểm tra lại sau này.
  4. Tên phương thức kiểm thử phải rõ ràng. Vì vậy không phải do dự nếu tên phương thức quá dài. Ví dụ TestDivisionWhenNumPositiveDenomNegative tốt hơn DivisionTest3.
  5. Hãy kiểm thử những trường hợp ném ra ngoại lệ (nếu có). Ví dụ WhenDivisionByZeroShouldThrowException.
  6. Hãy kiểm thử các trường hợp negative để làm rõ hình thức phản hồi khi đầu vào là dữ liệu không hợp lệ.

Sử dụng JUnit

Hiện nay, JUnit được tích hợp và hỗ trợ ở phần lớn các IDE hiện tại cho Java (như Eclipse, IntelliJ, NetBeans,…). Việc sử dụng JUnit trong các dự án Java không khó. Các bạn có thể tìm hiểu cách cài đặt thư viện cho dự án của mình qua những hướng dẫn trên mạng.

Trong mục này, chúng ta sẽ cùng lượt qua những tính năng được hỗ trợ trong JUnit 5 – phiên bản mới nhất hiện nay.

Ví dụ đầu tiên

Dưới đây là ví dụ giúp bạn có cái nhìn tổng quan về một kiểm thử được viết với JUnit5:

import com.codegym.Calculator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculatorTests {
    private final Calculator calculator = new Calculator();
    @Test
    void shouldReturn2When1Plus1() {
        assertEquals(2, calculator.add(1, 1));
    }
}

Giải thích ví dụ:

  • @Test là annotation đánh dấu phương thức shouldReturn2When1Plus1() là một test case. Hãy chú ý rằng tên của phương thức test được viết rất rõ là nên trả về kết quả 2 khi 1 cộng 1.
  • Ở phần thân của phương thức chứa một dòng mã kiểm tra kết quả của phương thức add() với đầu vào là hai số có giá trị lần lượt là 1 và 1.
  • So sánh giá trị thực tế trả về của phương add() với giá trị mong đợi là 2.
  • Sau khi chạy test case này, kết quả sẽ là PASS nếu phương thức add(1, 1)) trả về kết quả đúng bằng 2.

Các mục tiếp theo sẽ cung cấp thêm chi tiết về một số tính năng cơ bản được hỗ trợ trong JUnit5.

Các annotation trong JUnit

Sơ đồ dưới đây thể hiện thứ tự thực hiện các phương thức khi được đánh dấu với annotion tương ứng:

Làm website tin tức một mình ? Nên hay Không ?

Các annotaion @BeforeAll, @BeforeEach,@AfterEach, @AfterAll là những thành phần cố định, thực hiện các chức năng lặp đi lặp lại. Annotation @Test được dùng để xác định một test case.

Assertions

Assertions là lớp chứa các phương thức hỗ trợ đánh giá các điều kiện trong kiểm thử.

So với phiên bản trước, JUnit 5 vẫn giữ các phương thức cũ và thêm một số phương thức mới tận dụng những tích năng của Java 8.

Dưới đây là danh sách những phương thức assertion có trong JUnit5.

assertTrue và assertFalse

Phương thức assertTrue được dùng để kiểm tra kết quả của điều kiện có bằng true hay không. Ví dụ:

@Test
public void whenAssertingConditions_thenVerified() {
    assertTrue(10 > 5, "10 lớn hơn 5");
}

Ngược lại, phương thức assertFalse được dùng để kiểm tra kết quả của điều kiện có bằng false hay không.

@Test
public void whenAssertingConditions_thenVerified() {
    assertTrue(5 > 10, "5 không lớn hơn 10");
}

assertEquals và assertNotEquals

Phương thức assertEquals được dùng để kiểm tra giá trị mong đợi và thực tế có bằng nhau hay không. Ví dụ:

assertEquals và assertNotEquals
Phương thức assertEquals được dùng để kiểm tra giá trị mong đợi và thực tế có bằng nhau hay không. Ví dụ:

Ngược lại, Phương thức assertNotEquals được dùng để kiểm tra giá trị mong đợi và thực tế có bằng nhau hay không. Chúng ta cập nhật lại ví dụ ở trên:

@Test
public void whenAssertingConditions_thenVerified() {

          // thay thế phương thức toUpperCase() thành toLowerCase()

          String actual = new String("CodeGym").toLowerCase();
          String expected = "CODEGYM";
          assertNotEquals(expected, actual);
}

Với trường hợp các giá trị chúng ta đang so sánh thuộc kiểu Object, assertEquals và assertNotEquals sẽ gọi phương thức equals để so sánh giá trị.

Có một điểm cần lưu ý nếu giá trị là kiểu số thực (float hoặc double). Trên thực tế, có nhiều trường hợp mà giá trị số thực mong đợi và thực tế có thể chênh lệch với nhau trong khoảng chấp nhận được. Với tình huống này, phương thức assertEquals và assertNotEquals hỗ trợ tham số thứ ba là delta (bên cạnh expected và actual). Chúng ta cùng xem qua ví dụ dưới đây:

@Test
public void whenAssertingConditions_thenVerified() {
    float actual = 12 / 3.0001f;
    float expected = 4;
    assertEquals(expected, actual, 0.001f);
}

Kết quả của phép chia 12 cho 3.001 thì sẽ là một số thực 3.9998667. Kết quả của ca kiểm thử ví dụ trên là PASSED vì chúng ta đã cho phép mức chênh lệch tối đa là 0.001.

assertArrayEquals

Phương thức assertArrayEquals có thể xác nhận mảng mong đợi và thực tế có bằng nhau hay không. Chúng ta cùng xem xét ví dụ dưới đây:

public void whenAssertingArraysEquality_thenEqual() {
    char[] expected = { 'C', 'o', 'd', 'e', 'G', 'y', 'm' };
    char[] actual = "CodeGym".toCharArray();
    assertArrayEquals(expected, actual, "Mảng phải giống nhau");
}

assertSame và assertNotSame

Khu chúng ta muốn xác nhận giá trị mong đợi và thực tế tham chiếu đến cùng một đối tượng hay không, chúng ta phải dùng assertSame hoặc assertNotSame:

@Test
public void whenAssertingSameObject_thenVerified() {
    String actual = new String("CodeGym");
    String expected = "CodeGym";
    assertSame(expected, actual);
}

Kết quả của phương thức test trên là FAILED vì hai biến actual và expected đang tham chiếu đến hai đối tượng khác nhau trong bộ nhớ.

Chúng ta nên lưu ý về sự khác nhau giữa assertSame và assertEquals (đã tìm hiểu ở ví dụ trước):

  • assertEquals chỉ quan tâm đến giá trị có bằng nhau không (thông qua phương thức equals) mà không cần biết hai giá trị được so sánh có phải cùng là một đối tượng hay không.
  • assertSame sẽ trả về PASSED chỉ khi cả hai biến cùng tham chiếu đến một đối tượng.

assertIterableEquals

assertIterableEquals so sánh các giá trị được chứa bên trong hai đối tượng kiểu Iterable. Để trả về kết quả PASSED, hai iterable phải trả về bằng số phân tử, giá trị của các phần tử đó và cả vị trí của các phần tử. Hãy cùng xem ví dụ dưới đây:

@Test
public void givenTwoLists_whenAssertingIterables_thenEquals() {
    Iterable<String> al = new ArrayList<>(asList("CodeGym", "Coding", "Bootcamp", "Java"));
    Iterable<String> ll = new LinkedList<>(asList("CodeGym", "Coding", "Bootcamp", "Java"));
    assertIterableEquals(al, ll);
}

Kết quả của test case trên là PASSED. Phương thức assertIterableEquals chỉ so sánh giá trị các phần tử bên trong mà không quan tâm đến việc các phần tử này đang được lưu trữ tại hai biến thuộc kiểu khác nhau (ArrayList và LinkedList).

assertThrows

Để có thể xác nhận được phương thức đang kiểm thử có ném ra một ngoại lệ hay không, chúng ta có thể sử dụng assertThrows. Giả sử chúng ta có một phương thức như sau:

static void throwAnException() {
          throw new IllegalArgumentException("Tham số không hợp lệ");
}

Dùng cách thức dưới đây để kiểm tra xem phương thức throwAnExcepiont() có ném ra một ngoại lệ hay không, và ngoại lệ đó có phải là IllegalArgumentException hay không:

@Test
void whenAssertingException_thenThrown() {
    Exception e = assertThrows(IllegalArgumentException.class, () -> throwAnException());
    assertEquals("Tham số không hợp lệ", e.getMessage());
}

Các assertion khác

  • assertLinesMatch
  • fail
  • assertNotNull và assertNull
  • assertAll
  • assertTimeout và assertTimeoutPreemptively

Sử dụng Mockito (Mocking framework)

Khi xây dựng phần mềm, AUT sẽ phụ thuộc vào các thành phần bên ngoài như cơ sở dữ liệu, API, hệ thống file,… Các thành phần phụ thuộc này có thể chưa sẵn sàng hoặc thậm chí chưa tồn tại ở thời điểm chúng ta viết Unit Test. Ngay cả khi những thành phần này đã được chuẩn bị sẵn sàng thì việc thực thi một test case có phụ thuộc sẽ chậm hơn vì phải cần thời gian đợi và tương tác với thành phần bên ngoài.

Làm website tin tức một mình ? Nên hay Không ?

Cô lập AUT là một trong những kỹ thuật giúp giải quyết vấn đề trên. Và lúc này, chúng ta sẽ phải cần đến các mocking framework (tạm dịch là khung mô phỏng) để giả lập các thành phần bên ngoài, nhờ đó có thể cô lập và kiểm thử AUT dễ dàng hơn. Đối tượng mô phỏng này sẽ không gây phá vỡ cấu trúc mã nguồn khi đối tượng thật được thiết kế và triển khai. Hình dưới đây thể hiện việc tạo hai đối tượng mô phỏng là Mock WS và Mock DB để thay thế sự phụ thuộc vào WebService và Database.

Làm website tin tức một mình ? Nên hay Không ?

Việc tìm hiểu cách thiết lập và sử dụng các mocking framework này là bước quan trọng giúp mở rộng Unit Test cho các hệ thống lớn và phức tạp. Với lập trì viên Java, Mockito là một công cụ không thể thiếu.

Tạo đối tượng mô phỏng

Phương thức mock() cho phép chúng ta tạo đối tượng mô phỏng từ một class hoặc interface. Phương thức này không yêu cầu thêm gì khi sử dụng. Và nó có thể tạo các thuộc tính class mô phỏng hoặc các đối tượng mô phỏng cần dùng trong phương thức. Ví dụ dưới đây thể hiện cách tạo một đối tượng mô phỏng kiểu UserRepository (đã được định nghĩa trước):

verify(stockRepository).count();

Mô phỏng hành vi

Sử dụng phương thức when() để mô phỏng hành vi của đối tượng. Để xác định kết quả thực hiện, chúng ta có thể sử dụng thenReturn() hoặc thenThrow().

  • thenReturn() trả về kết quả
  • thenThrow() sẽ ném ra một ngoại lệ
verify(stockRepository).count();

Nếu muốn trả về nhiều kết quả cho nhiều lần gọi, chúng ta sử dụng thenReturn() nhiều lần như sau;

when(stockRepository.count())
  .thenReturn(50)
  .thenReturn(100)
  .thenReturn(200);

// Kết quả in ra màn hình sẽ là:

System.out.println(stockRepository.count()); // 50
System.out.println(stockRepository.count()); // 100
System.out.println(stockRepository.count()); // 200

Kiểm chứng

Chúng ta có thể kiểm tra xem phương thức/hàm có được gọi hay không qua phương thức verify().

verify(stockRepository).count();

Mockito hỗ trợ những tham số giúp chúng ta có thể mở rộng khả năng kiểm chứng việc gọi phương thức như:

  • Số lần gọi với times()
  • Thời gian thực hiện với timeout(), giúp kiểm chứng thời gian thực hiện thuật toán có đảm bảo yêu cầu

Ví dụ:

verify(stockRepository, times(2)).count();         // gọi 2 lần
verify(stockRepository, timeout(10)).count(); // 10 mili giây

Kết hợp JUnit

Đây là đoạn mã ví dụ cách kết hợp Mockito và JUnit để viết mã kiểm thử đơn vị:

@Test
public void tryMockitoMock() {
  verify(stockRepository).count();
                when(stockRepository.count())
     .thenReturn(10);
    long stockCount = stockRepository.count();
    Assertions.assertEquals(10, stockCount);
    verify(stockRepository).count();
}

Ở phương thức trên, chúng ta mô phỏng hành vi lấy số lượng user thông qua phương thức count() được định nghĩa trong UserRepository. Khi count() được gọi, đối tượng mô phỏng sẽ trả về kết quả là 111 thay vì phải truy vấn vào cơ sở dữ liệu để lấy thông tin.

Case Study

Dự án mà chúng ta sẽ thực hiện là một trang cửa hàng trực tuyến đơn giản hỗ trợ duyệt danh sách sản phẩm và thông tin chi tiết của từng mặt hàng. Khách hàng có thể chọn sản phẩm và lưu vào giỏ hàng để thanh toán.

Trước khi thực sự viết mã, hãy thiết kế chi tiết bao gồm những interface, class và các phương thức có thể cần để thực hiện được ứng dụng này. Dựa vào bản thiết kế, hãy viết các unit test case cho ứng dụng.

Chặng đường tiếp theo

Cảm ơn bạn đã đồng hành cùng bài viết đến đây. Hy vọng những bước chân đầu tiên này sẽ mang lại nhiều ý nghĩa cho chặng đường học hỏi tiếp theo của bạn. Hãy tìm tòi và thực hành nhiều hơn để có thể làm chủ được kỹ năng Unit Test nói riêng và automation testing nói chung. Tới đây, chúng ta nên làm gì để học và thực hành hiệu quả hơn ở kỹ năng này?

Câu châm ngôn của mình là “Thế giới này thật là rộng lớn.. và có quá nhiều sách để đọc”. Nên gợi ý đầu tiên luôn là đọc những đầu sách hay về Unit Test, Test-Driven Development và những chủ đề liên quan. Các bạn xem qua các gợi ý sách và website bên dưới nhé!

Sách nên tham khảo

  • Test Driven Development: By Example – Tác giả: Kent Beck
  • The Art of Unit Testing – Roy Osherove (Các ví dụ trong sách được viết vớt .NET nhưng vẫn có thể tham khảo để phát triển ứng dụng trên Java)

Website nên tham khảo

Author: Đặng Huy Hòa

Bài viết gốc được đăng tải tại tapchilaptrinh.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Keyboard from Scratch: Từ A tới Z

Keyboard from Scratch: Từ A tới Z

Bài viết được sự cho phép của tác giả Huy Trần

Sau khi kết thúc hai phần trước, chúng ta đã có những kiến thức cơ bản về chiếc bàn phím cơ, không để các bạn đợi lâu, ở phần này chúng ta sẽ thực sự bắt tay vào làm một chiếc bàn phím hoàn chỉnh.

  50 keywords mà mọi JAVA developer nên biết
  Làm thế nào để tạo một bảng BI Dashboard bằng cách sử dụng một bảng Pivot và một thư viện biểu đồ?

TL;DR: Các bước để build một chiếc bàn phím cơ

  1. Tham khảo thật nhiều layout, thiết kế của cộng đồng
  2. Thiết kế cho mình một layout hợp lý
  3. Đặt mua linh kiện, keycaps, switches, cắt plate nếu cần thiết
  4. Hàn mạch bằng tay, hoặc thiết kế mạch in rồi mới hàn
  5. Hàn controller, viết firmware hoặc modify từ các firmware có sẵn như QMK hay TMK
  6. Done

Trước khi bắt đầu thì các bạn hãy để mình khoe hàng tí đã, chiếc bàn phím bốn chấm không, à nhầm 40% mang tên SnackyMini Keyboard  một sản phẩm kết tinh của tinh thần bốn chấm không, của trí tuệ Việt và nền công nghệ tiên tiến của Đế quốc Tư bản Huê Kỳ, cộng với nguồn cung cấp thiết bị kĩ thuật, linh kiện bán dẫn phong phú của người anh lớn Trung Hoa, một sản phẩm của người Việt, dành cho cả người Việt lẫn người không Việt, được nghiên cứu, thiết kế và tối ưu dành riêng cho các software developer, một… ấy ấy ấy, thôi các bạn đừng tắt mà, ở lại đọc tiếp đi mà, mình im rồi đây 

Keyboard from Scratch: Từ A tới Z

Bài viết sẽ mang tính chất ghi chép lại quá trình mình thực hiện chiếc bàn phím, một số yếu tố kĩ thuật sẽ được lượt bỏ hoặc tối giản, phun ra mà không có giải thích hay chú thích, nên có thể bài viết sẽ có những đoạn khó hiểu. Nếu sau khi đọc xong series bài viết này và các bạn có ý định tự mình làm một chiếc bàn phím cơ, và có thắc mắc, xin đừng ngại comment hoặc để lại lời nhắn, mình sẽ cố gắng trả lời trong phạm vi hiểu biết của bản thân.

Thiết kế layout

Việc đầu tiên cần làm khi bắt đầu bất kì một dự án nào đó là thiết kế. Chúng ta cần phải thiết kế bố cục (layout) Làm phần cứng không giống như phần mềm, chỉ cần một sai sót nhỏ trong bố cục hoặc một điểm bất hợp lý trong thiết kế thì chúng ta phải trả giá bằng cả thời gian lẫn tiền bạc và công sức, các sai lầm thường rất khó hoặc là không thể sửa chữa, làm lại.của chiếc bàn phím, bước này rất quan trọng và đòi hỏi bạn phải tham khảo thật nhiều, suy nghĩ một cách thật kĩ lưỡng để chọn được một bố cục và thiết kế ưng ý.

Nếu chưa biết mình muốn gì, thì các bạn có thể tham khảo qua các mẫu bàn phím khác nhau trên các cộng đồng dân chơi phím cơ như Reddit /r/MechanicalKeyboardsGeekhackDeskthority, trên những cộng đồng này cũng thường xuyên có những thảo luận về việc tự build bàn phím, rất hữu ích. Ngoài ra thì còn nhiều cộng đồng khác, ví dụ như VietnamMechKey.

Ý tưởng của mình là thiết kế bộ chiếc bàn phím có layout 40% nên cũng đã tham khảo nhiều từ trang 40percent.club. Một số yêu cầu thiết kế của mình tự đặt ra là như sau:

  • Sau một thời gian xài layout 60% thì mình thấy dù sao bàn phím có hàng phím mũi tên vẫn tiện hơn cả, vì thế chiếc bàn phím nhỏ gọn sắp build cũng phải có 4 phím mũi tên.
  • Tiếp theo, vì công việc chính của mình là code, nên để có thể sử dụng chiếc bàn phím này hằng ngày, thì mình vẫn phải giữ lại các phím cơ bản hay dùng như [ ] ( ) { } ; : < > , ., hoặc Tab.
  • Sau một thời gian sử dụng Emacs thì mình sử dụng phím Ctrl khá thường xuyên, vì thế phím này cần phải đặt ở một vị trí nào đó cho tiện bấm nhất.
  • Cụm phím CmdAltShift bên phía tay phải mình chưa một lần nào phải đụng tới trong suốt bao nhiêu năm xài máy tính, nên tốt nhất là vứt nó đi.
  • Layout vừa nhỏ nên sẽ không đủ chỗ để đặt hàng phím số vào, cho nên tốt hơn cả là giấu nó vào hàng phím QWERTY thông qua một phím Fn, khi nhấn phím này thì bàn phím sẽ chuyển qua layout phím số.

Sau khi quyết định xong các yêu cầu trên, thì mình bắt tay vào thiết kế layout bằng trang web http://www.keyboard-layout-editor.com, layout có dạng tương tự như bàn phím Minivan Arrow:

Bàn phím mặc định ở trên, và bàn phím khi nhấn nút Fn ở dưới:

Keyboard from Scratch: Từ A tới Z

Sau khi kết thúc bước này, các bạn có thể export layout này ra định dạng JSON và đưa qua http://builder.swillkb.com/ để thiết kế plate và case, nếu các bạn có ý định làm bàn phím plate mount. Ở đây mình chỉ xài PCB mount nên bỏ qua bước này.

Ngoài ra, bạn còn có thể vào tab Summary để xem danh sách và số lượng các phím cần dùng, ví dụ đây là danh sách các phím cần dùng cho layout của mình:

Keyboard from Scratch: Từ A tới Z

Thiết kế mạch in

Đến đây, chúng ta đã có layout, bước tiếp theo là thiết kế mạch in (PCB) để hàn các linh kiện vào. Thực ra việc này đối với nhiều người khó hơn là hàn mạch bằng tay (handwired), với mình thì… trước đây mình cũng đã làm một bản prototype handwired, tuy nhiên nhờ kĩ năng hàn mạch thần sầu, mình nướng chín luôn hầu hết diode trên mạch  và cuối cùng thì bản này bị vứt xó.

Keyboard from Scratch: Từ A tới Z

Sau khi xem xét nhiều phương án, thì việc tự thiết kế PCB là khả thi nhất, vì như thế đến công đoạn hàn linh kiện vào đỡ vất vả hơn, và giảm thiểu được tối đa nguy cơ xảy ra lỗi. Mỗi tội tốn tiền nhiều hơn.

Để thiết kế PCB thì mình dùng phần mềm KiCad vì nó trực quan, đầy đủ nhiều chức năng, có khả năng render ra board mạch hoàn chỉnh trông rất đẹp, open source và miễn phí, và quan trọng nhất là đa số các cơ sở sản xuất mạch đều hỗ trợ định dạng file của KiCad.

Cái khó nhất khi dùng KiCad là giao diện của nó không được thông minh cho lắm, hay nói thẳng ra nó luôn là giao diện ngu như . Đặc biệt là trên macOS. Đó là chưa kể cơ chế quản lý thư viện footprint và component của nó khá rối. Trước khi bắt tay vào làm thì các bạn nên đọc qua bài hướng dẫn sử dụng của Deskthority, đây là bài viết dễ hiểu nhất mà mình có thể tìm thấy, mặc dù hơi cũ.

Cái khó thứ hai, là bắt đầu như thế nào? một cái switch có những chân nào, cần đục những lỗ nào? khoảng cách giữa các switch là bao xa? để nắm được các thông tin này thì bạn cần phải bới tung các wiki và các diễn đàn về phím cơ lên. Ở đây mình sẽ nói sơ qua, vì các bạn có đọc trước cũng không thể nhớ được cho tới khi các bạn bắt tay vô làm và tự mình đụng phải các vấn đề đó 

Keyboard from Scratch: Từ A tới Z

  • Một hình vuông màu đen như trên là footprint cho một phím/switch đã kèm cả key caps (1u). Hai phím 1u kề nhau sẽ có footprint kề cạnh nhau, và khoảng cách giữa hai phím như thế này đủ để đặt vào một con diode (kí hiệu D39 như trong hình).

À, cũng phải nói thêm, mình sử dụng Teensy 3.2 làm controller cho chiếc bàn phím này, vì lý do nó dễ mua, dễ lập trình, hỗ trợ giao tiếp với máy tính như là một thiết bị USB, và có sẵn bộ thư viện Teensyduino xài khá tiện.

Sau vài ngày hì hục với KiCad thì đây là thành quả, nhìn rối như tơ vò, nhưng là một cái PCB 2 mặt:

Keyboard from Scratch: Từ A tới Z

Ngày xưa mình từng có thời gian tự làm PCB trên miếng đồng bằng máy in laser, giấy màu, bàn ủi, bàn chải đánh răng và thuốc sắt FeCl3, chưa bao giờ mình dám mơ tới chuyện làm một cái PCB có đường mạch mỏng hơn 2mm, chứ đừng nói tới một cái PCB 2 mặt.

Quên nói, 4 cái lỗ ở 4 góc board có đường kính 2.5mm, vừa đủ cho một con M2 standoff cắm vào.

Sau khi hoàn thành, thì mình hí hửng xuất file ra và gửi cho nhà in, đây là một công ty ở Trung Quốc, sở dĩ chọn Trung Quốc là vì hôm đó ngày lễ ở Mỹ, không có nhà in nào của Mỹ làm việc cả.

Có bạn hỏi muốn biết thêm chi tiết về công đoạn này, thì như thế này: Khi làm việc với các công ty in mạch, bạn sẽ phải gửi file cho họ, bạn có thể nén và gửi toàn bộ project KiCad cho họ, hoặc đơn giản hơn thì có thể xuất project ra thành nhiều file gerber (mỗi một file gerber sẽ là một layer của board, ví dụ layer mạch đồng, layer khoan lỗ, layer hình vẽ trên mạch,…) rồi nén tất cả lại thành một file zip để gửi. Trong repo Github ở cuối bài, mình có để sẵn file snackymini-manufacturing-submission.zip trong thư mục hardware, chứa các file gerber này, có thể gửi trực tiếp file này tới nhà in. Còn dịch vụ mình sử dụng là công ty JLCPCB, họ có đội ngũ support rất tận tình, trao đổi và confirm qua mail liên tục, mỗi tội tiếng Anh của các bạn này hơi bị dỏm, được cái giá cả khá ổn và thời gian gia công khá nhanh.

Vì nôn nóng nên mình chọn in gấp, chỉ tốn 2 ngày gia công và 3 ngày để mấy cái mạch bơi từ bên đó qua bên đây, tầm 50 USD ra đi cho 10 cái board mạch đen cóng ngầu xì dầu:

Keyboard from Scratch: Từ A tới Z

Trong thời gian chờ in mạch thì mình cũng đặt mua luôn các linh kiện cần thiết, bao gồm:

  • 1 board mạch Teensy 3.2 loại có hàn sẵn header
  • 50 switch Cherry MX Black
  • 100 diode 1N4148
  • Keycaps thì đã có sẵn, gom góp lại cũng đủ quân số, mặc dù lố nhố

Hầu hết các phím mình dùng đều không quá 2.5u, và cũng quên không đục lỗ cắm stabilizer, nên mình bỏ qua nó luôn, gõ thấy cũng hơi kì kì nhưng kệ đi.

Việc tiếp theo là lôi switches và diodes ra hàn, mình dùng Cherry Black, ban đầu gõ thấy khá nặng vì đã quen xài Brown, nhưng dần cũng quen.

Keyboard from Scratch: Từ A tới Z

Hàn controller vô mặt sau, ở đây thì có một vấn đề, đó là vì sợ Teensy sẽ đụng vào switch, mình phải dùng header để tạo ra khoảng cách, và hàn ngược con Teensy lại cho phần chân cắm vào phần bụng của PCB, điều này sai với thiết kế ban đầu. Rất may lỗi này có thể khắc phục được bằng phần mềm:

Hàn xong đâu ra đấy thì mới thấy khi thiết kế mạch, mình quá cẩn thận khi đã dành ra một phần diện tích khá lớn cho viền ngoài của board, về sau khi xem mạch thực tế và xem các bản thiết kế khác thì khá tiếc, vì đáng ra không có phần viền, bàn phím trông sẽ gọn gàng hơn.

Đâu ra đấy xong thì lắp key caps vào:

Keyboard from Scratch: Từ A tới Z

Thế là xong phần cứng. Tiếp theo là đến firmware.

Viết Firmware

Nếu các bạn không đọc các bài trước, thì lý do mình quyết định tự viết firmware chỉ đơn giản là vì mình không compile được các firmware có sẵn như QMK hay TMK cho Teensy 3.2  nếu các bạn sử dụng controller khác, có thể các bạn sẽ compile được và không cần phải đâm đầu vào con đường đen tối này. Suy cho cùng, tự viết firmware cũng có cái hay của nó, và mình học được rất nhiều từ việc này. Dưới đây là một vài ghi chép của mình trong quá trình viết, nếu không thực sự quan tâm, các bạn có thể bỏ qua cũng được.

Mãi cho đến khi hoàn thành xong phần hardware thì mình mới bắt tay vào viết firmware hoàn chỉnh (chứ không phải là cái firmware điều khiển 4 nút như trong bài trước). Về cơ bản thì không khác nhiều mấy so với trong bài trước, mình dùng một mảng kiểu unit8_t để lưu thông tin về layout bàn phím, đây là một mảng 3 chiều, nó gồm có 2 mảng 2 chiều, mỗi một mảng 2 chiều là một layout:

uint8_t keyLayout[][ROWS][COLS] = {
  // Default layout
  {
   { KEY_TAB  , KEY_Q   , KEY_W   , KEY_E   , KEY_R   , KEY_T   , KEY_Y   ,...
   { NULL_KEY , KEY_A   , KEY_S   , KEY_D   , KEY_F   , KEY_G   , KEY_H   ,...
   { NULL_KEY , KEY_Z   , KEY_X   , KEY_C   , KEY_V   , KEY_B   , KEY_N   ,...
   { KEY_TILDE, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY,...
  },
  // Fn layout
  {
   { KEY_ESC , KEY_1   , KEY_2   , KEY_3   , KEY_4   , KEY_5   , KEY_6   ,...
   { NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY,...
   { NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY,...
   { NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY, NULL_KEY,...
  }
};

Code cho việc chuyển layout bằng phím Fn:

if (keys[i].code == FN_KEY) {
  layoutId = FN_LAYOUT; break;
}
submitLayout(keys, keyLayout[layoutId]);

Một thay đổi nữa so với bài viết trước, đó là thuật toán debounce, sau khi thử nghiệm và tham khảo từ các firmware khác, thì mình quyết định làm đơn giản hơn, giống với các firmware phổ biến như QMK/TMK, là quét từng đợt sau mỗi 15 milli giây, đơn giản đến không đỡ được:

#define DEBOUNCE_DELAY 15

void loop()
{
  unsigned long timeNow = millis();
  if (timeNow - lastFrame > DEBOUNCE_DELAY) {
    lastFrame = timeNow;
    // Scan key
  }
}

Khi compile và upload firmware vào bàn phím, ban đầu thì mọi thứ có vẻ hoạt động rất trơn tru, nhưng khi mình thử gõ một đoạn nội dung dài vào, thì xảy ra tình trạng mất phím, ví dụ gõ:

Hello I am Huy

thì lại thành ra:

Helo I m Hy

Thế là tốn thêm 1 ngày để debug, nguyên nhân thì hết sức ngớ ngẩn  vì trong lúc viết firmware, mình lười và chỉ làm cho cái bàn phím đọc mỗi một phím duy nhất ở một thời điểm, và khi gõ nhanh, ở một thời điểm có thể sẽ có rất nhiều phím được nhấn xuống. Cũng nhờ thế mà lại biết thêm được khái niệm NKRO (n-key roll over), một chức năng giúp cho bàn phím có thể ghi nhận được nhiều phím trong một thời điểm. Đối với các bàn phím sử dụng cổng USB, thì tối đa chi ghi nhận được 6 phím, trong khi đó bàn phím dùng cổng PS/2 thì xả láng.

Việc implement chức năng này cũng không mấy khó khăn, nhờ các hàm Keyboard.set_key1Keyboard.set_key2Keyboard.set_key3,… của Teensyduino. Về ý tưởng thì ở mỗi lần quét, mình tạo một mảng gồm 6 phần tử để lưu lần lượt giá trị các phím nhận được:

#define MAXIMUM_STROKES 6

struct Key* readKey() {
  struct Key* result = (Key*)malloc(MAXIMUM_STROKES * sizeof(struct Key));
  int currentFinger = 0;

  for (int row = 0; row < ROWS; row++) {
    for (int col = 0; col < COLS; col++) {
      if (keyPressedAt(row, col)) {
        result[currentFinger].row = row;
        result[currentFinger].col = col;
        if (currentFinger < MAXIMUM_STROKES) currentFinger++;
      }
    }
  }

  return result;
}

Rồi sau đó lần lượt sử dụng các hàm Keyboard.set_key<x> để gán giá trị cho từng phím, và gửi đi một lần bằng hàm Keyboard.send_now():

void submitLayout(struct Key* keys, uint8_t layout[ROWS][COLS]) {
  int currentFinger = 0;
  ...
  for (int i = 0; i < SUPPORTED_STROKES; i++) {
    int c = layout[pos.r][pos.c];
    if (c != NULL_KEY) {
      setKey(currentFinger, c);
      currentFinger++;
    }
  }
  ...
  Keyboard.send_now();
}

Một số bàn phím còn cho phép người dùng tự cấu hình layout bằng phần mềm trên máy tính, xét ở góc độ firmware, điều này không quá khó, chỉ việc chuyển mảng keyLayout về một cấu trúc khác có thể lưu được vào bộ nhớ của Teensy, từ đó ta có thể load ra mỗi khi bàn phím được khởi động. Ví dụ lưu vào EEPROM thông qua hàm EEPROM.read() và EEPROM.write(), tuy nhiên cần lưu ý, EEPROM của Teensy 3.2 chỉ có 2KB, hơi ít, nhưng chắc vừa đủ xài. Nhưng nếu đã tự build được firmware, thì chả cần làm vậy cho mất công, chỉ cần customize layout bằng cách customize luôn source code 

Mấy hôm nay ngồi xem kĩ lại firmware QMK, thấy nó có vài features khá thú vị, như Grave Escape Key, Key Lock, Tap Dance hay Mouse Key,… hôm nào có thời gian mình sẽ ngồi clone lại và viết thêm về chủ đề này.

Chỉ cần chừng đó thứ thì bạn đã có thể tự mình viết được firmware cho chiếc bàn phím của mình rồi. Nếu quan tâm, các bạn có thể tham khảo mã nguồn đầy đủ của firmware lẫn hardware cho bàn phím này tại đây https://github.com/huytd/snackymini-keyboard/

Xin cảm ơn các bạn đã kiên nhẫn đọc đến tận đây (tui nói vậy thôi chứ tui biết bạn scroll xuống đây từ đầu trang, chỉ tốn có 3 giây). Nếu bạn cũng là dân chơi mech, hy vọng bài viết này giúp các bạn hiểu thêm về những chiếc bàn phím tiền triệu mà mình đã mua. Nếu bạn chưa phải là dân chơi, hy vọng bài viết này làm nhụt chí và ngăn bạn lao vào con đường tốn kém này. Nếu đã đọc hết mà vẫn quyết định sẽ mua hoặc tự làm một chiếc bàn phím cơ, thì mình xin chúc mừng và chúc các bạn may mắn luôn.

P/S: Nếu bạn nào đang ở US, thì mình còn dư vài cái PCB, nếu có hứng thú thì cứ PM mình qua Facebook, mình sẽ gửi tặng.

Bài viết này được gõ bằng bàn phím SnackyMini Keyboard 

Bài viết gốc được đăng tải tại thefullsnack.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Thiết lập môi trường phát triển Laravel/PHP tốc độ ánh sáng trên Windows 10 với Windows Subsystem for Linux (WSL)

Thiết lập môi trường phát triển Laravel/PHP tốc độ ánh sáng trên Windows 10 với Windows Subsystem for Linux (WSL)

Bài viết được sự cho phép của tác giả Nguyễn Trần Chung

WSL là gì

WSL (Windows Subsystem for Linux) là một tính năng có trên Windows x64 (từ Windows 10, bản 1607 và trên Windows Server 2019), nó cho phép chạy hệ điều hành Linux (GNU/Linux) trên Windows. Với WSL bạn có thể chạy các lệnh, các ứng dụng trực tiếp từ dòng lệnh Windows mà không phải bận tâm về việc tạo / quản lý máy ảo như trước đây. Cụ thể, một số lưu ý mà Microsoft liệt kê có thể làm với WSL

Bạn có thể làm gì với WSL

  • Chạy được từ dòng lệnh các lệnh linux như ls, grep, sed … hoặc bất kỳ chương trình nhị phân 64 bit (ELF-64) nào của Linux
  • Chạy được các công cụ như: vim, emacs …; các ngôn ngữ lập trình như NodeJS, JavaScript, C/C++, C# …, các dịch vụ như PHP, Nginx, MySQL, Apache, …
  • Có thể thực hiện cài đặt các gói từ trình quản lý gói của Distro đó (như lệnh apt trên Ubuntu, yum trên CentOS)
  • Từ Windows có thể chạy các ứng dụng Linux thông qua command line
  • Từ Linux có thể gọi ứng dụng của Windows

Yêu cầu

  1. WSL1: Windows 10 1607 (window + R -> winver)
  2. WSL2: Kích hoạt chế độ hỗ trợ ảo hóa của CPU (CPU Virtualization), bạn kích hoạt bằng cách truy cập vào BIOS của máy, tùy loại mainboard mà nơi kích hoạt khác nhau

Việc làm Laravel hấp dẫn trong tháng lương 2000USD

Kích hoạt Windows Subsystem Linux

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

Mở windows store lên cài đặt Ubuntu 18.04

Khởi động sau khi cài đặt

Login vào WSL với user mặc định là root

ubuntu1804 config --default-user root

Truy cập vào WSL

wsl

Cài đặt các gói cần thiết để chạy một webserver trên Ubuntu

sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
sudo apt-get autoremove -y
sudo apt -y install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/nginx
sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] http://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.5/ubuntu bionic main'
sudo apt-get update -y
apt install zip unzip nginx redis mariadb-server php7.4 php7.4-fpm php7.4-mysql php7.4-mbstring php7.4-xml php7.4-bcmath php7.4-zip php7.4-sqlite -y
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php --install-dir=/usr/bin --filename=composer
rm -f composer-setup.php
git config --global user.name "Ten Cua Ban"
git config --global user.email email_cua_ban@gmail.com

Start service

service nginx start
service php7.4-fpm start
service mariadb start
service redis-server start

Cho phép mysql đăng nhập root với password null

mysql -u root
SELECT `user`, `plugin`, `host`, `password` FROM `mysql.user` WHERE `user` = 'root';
ALTER USER 'root'@'localhost' IDENTIFIED BY '';
FLUSH PRIVILEGES;

VScode truy cập vào WSL

Cài extension: Remote – WSL

Ứng tuyển ngay các vị trí PHP tuyển dụng mới nhất trên TopDev

Thêm site laravel/php

Thêm 1 site mới bằng cách tạo file có tên: site.conf trong thư mục /etc/nginx/sites-enabled

File mẫu

server {
    listen 80;
    listen [::]:80;

    root /mnt/d/Code/nguyentranchung/chungnguyen/public;

    index index.php index.html;

    server_name chungnguyen.test;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_buffering off;
        fastcgi_buffer_size 256k;
        fastcgi_buffers 4 256k;
    }
}

Chỉnh sửa file hosts

Mở file hosts: C:\Windows\System32\drivers\etc\hosts

Thêm dòng: 127.0.0.1 chungnguyen.test

Lưu lại với quyền admin, nếu không được thì copy file hosts ra desktop sửa, sau đó dán (paste) lại thư mục C:\Windows\System32\drivers\etc

Lưu ý

Đối website laravel cần comment out dòng 155 ở file: vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php

chmod($tempPath, 0777 - umask());

Lý do là vì wsl toàn bộ files/folders có quyền 777 và không được sửa, nên các thao tác chmod trong PHP sẽ xảy ra lỗi trên WSL.

DevOps – Giải pháp phát hành phần mềm nhanh chóng

DevOps – Giải pháp phát hành phần mềm nhanh chóng

Bài viết được sự cho phép của BBT Tạp chí Lập trình

Nhanh chóng phát hành một sản phẩm mới hoặc tính năng mới ra thị trường là nhiệm vụ đầy thử thách với mọi công ty trên thế giới. Việc hóc búa nhất là làm sao để các nhóm riêng biệt: phát triển, QA và vận hành IT làm việc cùng nhau để hoàn thành công việc và phát hành sản phẩm nhanh nhất có thể.

Các qui trình và kĩ thuật đã trải qua một quá trình tiến hóa để giải quyết thử thách này. Một thập kỉ trước không ai biết đến từ DevOps, nhưng vào năm 2009, một phương pháp đã tổng hợp các qui trình để phối hợp và giao tiếp giữa nhóm phát triển, QA và vận hành IT giúp rút ngắn đáng kể thời gian đưa sản phẩm ra thị trường bắt đầu phổ biến với tên gọi DevOps.

Phương pháp DevOps là một tập hợp các kĩ thuật được thiết kế để giải quyết vấn đề rời rạc giữa nhóm phát triển, QA và vận hành thông qua hợp tác và giao tiếp hiệu quả, kết hợp chặt chẽ qui trình tích hợp liên tục với triển khai tự động.Giúp tạo ra một môi trường để phát triển, QA và phát hành phần mềm ra thị trường nhanh chóng và ổn định.

Phương pháp Truyền thống vs DevOps

Theo phương pháp thác nước truyền thống, nhà phát triển viết mã cho các yêu cầu trên môi trường local. Khi phần mềm được build, đội QA kiểm thử phần mềm trên một môi trường tương tự như môi trường production. Cuối cùng, khi đã đáp ứng các yêu cầu, phần mềm được phát hành cho bên vận hành. Quá trình từ khi thu thập yêu cầu đến khi triển khai sản phẩm vào vận hành mất nhiều thời gian. Do hai bên phát triển và vận hành làm việc độc lập, khả năng cao là sản phẩm cuối cùng sẽ mất thêm nhiều thời gian nữa để đưa vào vận hành. Ngoài ra, sản phẩm có thể không chạy đúng như mong đợi hay gặp những trục trặc khác.

Khi đó, qui trình DevOps có một phương pháp tốt hơn để giải quyết những vấn đề trên. DevOps nhấn mạnh vào việc phối hợp và giao tiếp giữa nhóm phát triển, nhóm QA và nhóm vận hành để thực hiện việc phát triển liên tục, tích hợp liên tục, chuyển giao liên tục và giám sát các qui trình liên tục bằng cách dùng các công cụ kết nối các nhóm giúp đẩy nhanh tốc độ phát hành. Nhờ đó công ty có thể nhanh chóng thích ứng với những thay đổi từ yêu cầu kinh doanh.

  DevOps trend - 8 dự đoán trong nhiều năm tới

Quan hệ giữa Agile và DevOps

DevOps ra đời một phần dựa trên khả năng phát hành sản phẩm nhanh khi công ty áp dụng Agile. Nhưng có thêm những qui trình khiến DevOps khác biệt với Agile.

Các nguyên lý của Agile chỉ áp dụng cho qui trình phát triển và QA, Agile tin tưởng vào việc tạo ra các nhóm nhỏ phát triển và phát hành phầm mềm chạy tốt trong một khoảng thời gian ngắn, được gọi là Sprint. Nhóm chỉ tập trung vào Sprint và không giao tiếp với bên vận hành.

Còn DevOps lại chú trọng hơn vào việc phối hợp suôn sẻ giữa các nhóm phát triển, QA và vận hành trong suốt chu trình phát triển. Nhóm Vận hành liên tục tham gia thảo luận cùng nhóm phát triển về các mục tiêu của dự án, lộ trình phát hành và các yêu cầu kinh doanh khác. Từ ngày đầu, nhóm vận hành nên đưa ra các yêu cầu liên quan đến vận hành cho nhóm phát triển, sau đó kiểm tra lại chúng. Việc giám sát dự án liên tục cùng với giao tiếp hiệu quả và thường xuyên giúp công ty có thể nhanh chóng phát hành.

  Làm thế nào để tìm được những "nhân tài" DevOps phù hợp nhất?

Bạn sẽ nhận được gì từ DevOps?

Hãy xem xét vài lợi ích có thể nhận được từ qui trình và văn hóa DevOps.

  • Lợi ích đầu tiên ta sẽ nhận được là DevOps giúp giảm đáng kể thời gian đưa sản phẩm ra thị trường nhờ kết nối giữa các nhóm làm việc và làm theo qui trình phát triển liên tục.
  • Nhờ các nhóm đồng bộ tốt hơn, các thành viên có được tầm nhìn rõ ràng về các công việc đang làm, do đó họ có thể thấy các vấn đề hoặc các khó khăn trước khi chúng thực sự xảy ra. Nhờ vậy thành viên nhóm có kế hoạch tốt hơn để vượt qua các vấn đề đó.
  • Nhờ sự minh bạch trong qui trình, những người phát triển sản phẩm sẽ cảm thấy mình là chủ sản phẩm. Họ thực sự sở hữu mã từ khi bắt đầu đến lúc vận hành.
  • Viện triển khai tự động sản phẩm bằng các công cụ tự động hóa trong nhiều môi trường cho phép bạn nhanh chóng thấy được các vấn đề liên quan đến môi trường. Với những phương pháp khác thì thường tốn rất nhiều thời gian để phát hiện được các vấn đề này.

Những công cụ cho DevOps

Vì DevOps là sự cộng tác của Phát triển, QA và Vận hành, không thể có một công cụ duy nhất đáp ứng được tất cả các nhu cầu. Vì vậy cần nhiều công cụ để thực hiện thành công mỗi giai đoạn.

Hãy xem thử một vài công cụ cho mỗi giai đoạn ở dưới đây.

  • Monitoring: Nagios, NewRelic, Graphite …
  • Virtualization và Containerization: Vagrant, VMware, Xen, Docker …
  • Công cụ để build, test and deployment: Jenkins, Maven, Ant, Travis, Bamboo, Teamcity…
  • Quản lý cấu hình(configuration management): Puppet, Chef, Ubuntu Juju, Ansible, cfengine …
  • Orchestration: Zookeeper, Noah …
  • Cloud services: Azure, Openstack, Rackspace …

Ngoài ra còn có các công cụ cho việc merge code, kiểm soát phiên bản,… giúp áp dụng hiệu quả các qui trình DevOps.

  7 Công Cụ Hay Dành Để Thực Hiện Devops

Các hiểu nhầm về DevOps

Dù DevOps đã ra đời hàng thập kỉ, nhưng nó vẫn rất mới mẻ với nhiều người. Do đó, vẫn còn nhiều hiểu nhầm.

Vài người nghĩ rằng triển khai DevOps cho phép nhà phát triển làm luôn công việc của bên vận hành. Điều này hoàn toàn không đúng. DevOps nhấn mạnh vào việc cộng tác từ cả hai nhóm, do vậy những nhà phát triển có các kĩ năng vận hành sẽ có lợi thế trong chu kỳ kinh doanh nhanh chóng hiện nay.

Cũng có rất nhiều người tin rằng có thể triển khai DevOps bằng cách dùng một bộ các công cụ cho tất cả phần việc. Điều đó không đúng; dùng vài công cụ không giúp ta đạt được DevOps, mà ta chỉ có thể đạt được các giá trị cốt lõi của nó thông qua thực sự triển khai qui trình DevOps và khôn ngoan chọn dùng các công cụ.

DevOps ngày càng trở lên phổ biến nhờ văn hóa phát triển liên tục, tích hợp liên tục, chuyển giao liên tục và qui trình giám sát liên tục thông qua việc cộng tác giữa Phát triển và Vận hành giúp giảm đáng kể thời gian đưa sản phẩm ra thị trường.

Nguồn: agilebreakfast.vn

Bài viết gốc được đăng tải tại tapchilaptrinh.vn

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Hướng dẫn sử dụng thư viện FluentValidation để kiểm tra Form nhập liệu winform

Hướng dẫn sử dụng thư viện FluentValidation để kiểm tra Form nhập liệu winform

Bài viết được sự cho phép của tác giả Nguyễn Thảo

Xin chào các bạn, bài viết hôm nay mình sẻ hướng dẫn các bạn cách sử dụng thư viện FluentValidation để kiểm tra dữ liệu Form nhập liệu trên Winform C#.

[C#] Using Fluent Validation Form

Bất kỳ, khi các bạn thiết kế Form nào để nhập liệu, các bạn đều phải kiểm tra xem form đó người dùng nhập liệu vào có hợp liệu hay không.

  Namespace trong C#
  So sánh tốc độ List collection và HashSet collection trong C#

Hướng dẫn sử dụng thư viện FluentValidation để kiểm tra Form nhập liệu winform

Bình thường các bạn sẽ kiểm tra theo cách thông thường như sau:

if(String.IsNullOrEmpty(txtName.Text)
{
   MessageBox.Show("Vui lòng nhập tên của bạn.");
   return;
}
C#

Hôm nay, mình giới thiệu đến các bạn thư viện FluentValidation, dùng để thực hiện công việc kiểm tra nhập liệu form.

Các bạn có thể truy cập vào địa chỉ trang chủ https://fluentvalidation.net/ để xem hướng dẫn chi tiết hơn nhé.

Dưới đây là giao diện demo ứng dụng Validate Form C#:

Hướng dẫn sử dụng thư viện FluentValidation để kiểm tra Form nhập liệu winform

Đầu tiện, các bạn tải Fluent Validation từ Nuget:

PM> Install-Package FluentValidation -Version 9.3.0
C#

Full source code c#:

using FluentValidation;
using FluentValidation.Results;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FluentValidateDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            var student = new Student();
            student.ID = txtID.Text;
            student.Name = txtName.Text;
            student.Email = txtEmail.Text;
            student.Address = txtAddress.Text;
            student.Phone = txtPhone.Text;
            var validator = new StudentValidator();

            ValidationResult results = validator.Validate(student);
            errorProvider.Clear();
            if (!results.IsValid)
            {
                foreach (var failure in results.Errors)
                {
                    switch (failure.PropertyName)
                    {
                        case "ID":
                            errorProvider.SetError(txtID, failure.ErrorMessage);
                            txtID.BorderColor = Color.Red;
                            break;
                        case "Name":
                            errorProvider.SetError(txtName, failure.ErrorMessage);
                            txtName.BorderColor = Color.Red;
                            break;
                        case "Email":
                            errorProvider.SetError(txtEmail, failure.ErrorMessage);
                            txtEmail.BorderColor = Color.Red;
                            break;
                        case "Address":
                            errorProvider.SetError(txtAddress, failure.ErrorMessage);
                            txtAddress.BorderColor = Color.Red;
                            break;
                        case "Phone":
                            errorProvider.SetError(txtPhone, failure.ErrorMessage);
                            txtPhone.BorderColor = Color.Red;
                            break;
                    }                   
                   
                }
                
                if(!results.Errors.ToList().Exists(x => x.PropertyName == "ID"))
                {
                    successProvider.SetError(txtID, "Pass");
                    txtID.BorderColor = Color.Green;
                }
                if (!results.Errors.ToList().Exists(x => x.PropertyName == "Name"))
                {
                    successProvider.SetError(txtName, "Pass");
                    txtName.BorderColor = Color.Green;
                }
                if (!results.Errors.ToList().Exists(x => x.PropertyName == "Email"))
                {
                    successProvider.SetError(txtEmail, "Pass");
                    txtEmail.BorderColor = Color.Green;
                }
                if (!results.Errors.ToList().Exists(x => x.PropertyName == "Address"))
                {
                    successProvider.SetError(txtAddress, "Pass");
                    txtAddress.BorderColor = Color.Green;
                }
                if (!results.Errors.ToList().Exists(x => x.PropertyName == "Phone"))
                {
                    successProvider.SetError(txtPhone, "Pass");
                    txtPhone.BorderColor = Color.Green;
                }


            }
            else
            {
                MessageBox.Show("Pass validate Form.");
            }
           
        }
       
        public class Student
        {
            public string ID { set; get; }
            public string Name { set; get; }
            public string Email { set; get; }
            public string Address { set; get; }
            public string Phone { set; get; }
        }

        public class StudentValidator : AbstractValidator<Student>
        {
            public StudentValidator()
            {
                RuleFor(x => x.ID)
                        .NotEmpty().WithMessage("Enter your ID.");

                RuleFor(x => x.Name)
                        .NotEmpty().WithMessage("Enter your Name.");

                RuleFor(x => x.Email)
                .NotEmpty().WithMessage("Email address is required")
                .EmailAddress().WithMessage("Email is not valid");              

                RuleFor(x => x.Address).Length(10, 100).WithMessage("Please specify a valid Address");
                RuleFor(x => x.Phone)
                       .NotEmpty().WithMessage("Phone is required")
                       .Length(10, 11).WithMessage("Please specify a valid Phone");

            }
        }
    }
}
C#

Thanks for watching!

Bài viết gốc được đăng tải tại laptrinhvb.net

Có thể bạn quan tâm:

Xem thêm Tuyển dụng Winform hấp dẫn trên TopDev

3 hướng dẫn để bắt đầu kinh doanh trong lĩnh vực nhân sự

tuyen dung it da nang
tuyen dung it da nang

HR – Nghề nhân sự tuyen dung it da nang như một sứ mệnh đặc biệt. Bạn muốn giúp bản thân mình tạo ra sự khác biệt trong phạm vi nghề nghiệp? Tạo động lực và niềm cảm hứng cho các nhân viên của mình? Sau đây là 3 hướng dẫn để giúp bạn sẵn sàng chinh chiến ở level cao hơn trong lĩnh vực nhân sự.

1. Xác định rõ ràng, cụ thể về giá trị mà bạn sẽ cung cấp cho khách hàng và gắn bó với nó

Phân tích từ một ví dụ từ thực tiễn. Bạn cung cấp dịch vụ nhân sự cho các công ty về tuyen dung it da nang thuộc chủ sở hữu theo mô hình ứng dụng công nghệ thực tiễn với nguồn lao động trẻ.

Thực tế cho thấy khi khởi nghiệp, chúng ta có xu hướng tập trung vào những thị trường quá rộng. Từ suy nghĩ ấy, khiến bạn có những định hướng chưa đúng đắn vì sự cung cấp nhầm đối tượng (rộng và lẫn lộn) sẽ khiến các khách hàng càng xa bạn hơn.

Có thể nói, điều này cũng diễn ra trong việc tuyen dung it da nang đối với các freelancer it.

tuyen dung it da nang
1- tuyen dung it da nang

Bạn cần tìm ra những giá trị cụ thể mà bạn mong muốn mang đến cho khách hàng. Xây dựng nó thành một hệ thống; lập kế hoạch định hướng có mục tiêu.

Hãy lưu ý rằng dịch vụ nhân sự cần được đảm bảo kỹ lưỡng về nguyên tắc chuyên môn. Nếu quá rời rạc và có quá nhiều sự khác nhau về dịch vụ sẽ thiếu điểm nhấn với khách hàng.

2. Áp dụng cách thức: Mở rộng quan hệ nhân sự với nhiều người – nhưng xin lời khuyên chỉ một vài người

Hiểu đơn giản tức là bạn chỉ nên tìm kiếm sự tư vấn khôn ngoan từ một vài người có kinh nghiệm. Đó là điều bạn nên thực hiện khi quyết định những gì bạn sẽ làm.

Xem thêm các việc làm NTQ Solution tuyển dụng

Chúng ta luôn có xu hướng tìm kiếm lời khuyên từ những người thân thiết. Đó không phải là việc làm sai. Nhưng nó sẽ khiến bạn mất đi nhiều thời gian để tìm ra được những người thật sự muốn lắng nghe bạn.

Vì thế, hãy linh đông và nhận ra ai là người bạn cần hỏi. Các tiêu chi bạn có thể xét là: kinh nghiệm sống, kiến thức và kỹ năng.

tuyen dung it da nang
2 – tuyen dung it da nang

Điều quan trọng nhất bạn cần nhớ là bạn có thể xin ý kiến từ nhiều nguồn; nhiều đối tượng ở các lĩnh vực khác nhau với điều kiện là dự án. Chiến lược của bạn cần được hoàn thành, chỉn chu được 90%. Và phải chắc chắn khả năng chiến lược ấy phải được tiến hành. đơn xin nghỉ việc

3. Đầu tư cho chính mình: Tìm điểm mạnh mẽ để phát triển sâu và tự cân đối cuộc sống

Bạn có thể là nhân sự giỏi trong khi làm việc cho người khác. Nhưng lại ít giỏi khi làm việc đó cho chính mình. 

Xem thêm các việc làm về tuyển dụng Data Scientist 

Điểm mạnh là thứ quan trọng bạn cần tìm kiếm. Hãy suy nghĩ về những câu hỏi cho bản thân như: Bạn thích làm điều gì, bạn muốn trở thành người thế nào,.. Thế mạnh là điều bạn phải bắt buộc tìm ra.

Đừng xem thường việc này nhé! Vì việc nhận ra thế mạnh bản thân có thể thay đổi bạn một cách tốt hơn. Thế mạnh còn là một cơ sở nền tảng quan trọng. Từ đó, các nhà quản trị tuyen dung it da nang có thể phát triển vấn đề chuyên môn cho nhân viên mình dựa trên tiềm lực thế mạnh sẵn có. 

tuyen dung it da nang
3 – tuyen dung it da nang

Một điều quan trọng nữa, đó là nếu bạn muốn thành công, bạn phải cân bằng cuộc sống của mình. Điều này khá dễ dàng để nắm bắt nhưng nhiều người không làm được điều đó, đặc biệt là khi họ mới bắt đầu.

Không ai có thể duy trì một lịch trình điên rồ kín đặc và họ cần có sự hỗ trợ của gia đình vô thời hạn. Hãy luôn đảm bảo sự cân bằng với gia đình ngay cả khi điều đó là khó khăn để làm như vậy.


Tuyển Dụng Nhân Tài IT Cùng TopDev
Đăng ký nhận ưu đãi & tư vấn về các giải pháp Tuyển dụng IT & Xây dựng Thương hiệu tuyển dụng ngay!
Hotline: 028.6273.3496 – Email: contact@topdev.vn
Dịch vụ: https://topdev.vn/page/products

Có thể bạn quan tâm:

Xem thêm việc làm Developers hàng đầu tại TopDev