Home Blog Page 107

Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

(Xem thêm: Hướng dẫn tạo certificate SSL trên Windows (file key, pem))

Với server chạy bằng Java bạn cần chuyển file pem, private key sang p.12 (PKCS#12)

  System Design Cơ Bản: HTTPS, SSL, AND TLS
  Xử lý SSL Certificate trong Selenium WebDriver

Tạo file .key

openssl genrsa -out {ten_file}.key {do_dai_key}

Ví dụ:

openssl genrsa -out cert.key 2048

Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

Tạo file .pem từ file .key

Cú pháp:

openssl req -x509 -new -nodes -key {ten_file.key} -sha256 -days 1825 -out {ten_file.pem}

Ví dụ:

openssl req -x509 -new -nodes -key cert.key -sha256 -days 1825 -out cert.pem

Sau đó nhập các thông tin của certificate như  email, name…

Bạn cũng có thể tạo file .crt, chỉ cần đổi đuôi .pem thành đuôi .crt là được

Demo:

Đây là thông tin SSL Certificate hiển thị trên trình duyệt khi mình dùng 2 file trên apply cho website của mình:

Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

(Xem thêm: Cấu hình HTTPs cho Server NGINX)

Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

Okay, Done!

References:

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

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

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

Prototype pattern – một trong những pattern phổ biến nhất

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

Quay lại chuỗi bài viết về Design Pattern ở Kieblog, hôm nay vẫn tiếp tục là Creational Pattern (pattern khởi tạo), cụ thể là Prototype pattern.

Prototype pattern – một trong những pattern phổ biến nhất
Nguồn ảnh / Source: refactoring.guru

Trong cái pattern dễ nhất là Singleton Pattern, nắm vững. Sau đó quay qua tìm hiểu cái Prototype, pattern này cũng khá phổ biến, được sử dụng rất nhiều trong thực tế.

Bắt đầu vào tìm hiểu ngay thôi!.

  Design pattern là gì? Tại sao nên sử dụng Design pattern?
  Giải thích Flux Pattern theo phong cách John Wick

1. Prototype pattern là gì?

Bắt đầu với cái định nghĩa khá là lèo nhèo của Prototype pattern.

Prototype is a creational design pattern that lets you copy existing objects without making your code dependent on their classes.

Prototype là pattern khởi tạo cho phép copy một object sẵn có nhưng không làm đoạn code mới độc lập với class đã có

Vãi linh hồn cái định nghĩa. Loằng ngoằng, lèo ngèo khó hiểu. Thực ra thì diễn giải đơn giản chỉ như này.

Prototype pattern sẽ tạo ra một object mới bằng cách copy, tuy nhiên tương tự cách hiểu về kế thừa. Không cần phải copy ra đoạn source code mới, chỉ cần extends lại cái cũ là đã ok rồi

Prototype pattern – một trong những pattern phổ biến nhất
Thực tế lúc code không phải cái gì cũng nên copy ra. Không khéo thì từ “bay được” thành “đốt được”. Nguồn ảnh / Source: refactoring.guru

2. Giải pháp của prototype pattern

Về bản chất thì prototype sẽ định nghĩa ra các interface chung nhất (common interface) cho tất cả các object có hỗ trợ cloning. Những method này cho phép clone object. Mà thực hiện clone thì không cần copy source của object cũ.

Thông thường khi implement Prototype pattern, mỗi interface sẽ có duy nhất một phương thức clone.

Một object hỗ trợ cloning thì gọi là prototype. Prototype mang ý nghĩa cái chung nhất, cái common có thể cho những cái khác clone

Prototype pattern – một trong những pattern phổ biến nhất
Với prototype, có thể loại bỏ hoặc thay thế việc sử dụng quá nhiều subclassing. Nguồn ảnh / Source: refactoring.guru

3. Cấu trúc

Phần một (1) là phần khai báo iterface, method hỗ trợ cloning. Trong nhiều trường hợp, một interface chỉ có một method clone duy nhất.

Phần hai (2) là Concrete Prototype class, phần này sẽ implement cho method clone được khai báo ở interface. Cũng có thể handle một số case về các object không được clone.

Phần ba (3) là phần client có thể copy bất kì object nào thông qua phương thức clone

4. Hiện thực như nào?

Giả sử ta đang viết 3 class cho phần vẽ hình. Bao gồm hình tròn (Circle)

public class Circle extends Shape {
public int radius;

public Circle() {
}

public Circle(Circle target) {
super(target);
if (target != null) {
this.radius = target.radius;
}
}
// Method clone của Circle, trả về một object mới.
// Từ khóa this mang ý nghĩa state của tất cả các variable sẽ được giữ nguyên
@Override
public Shape clone() {
return new Circle(this);
}

@Override
public boolean equals(Object object2) {
if (!(object2 instanceof Circle) || !super.equals(object2)) return false;
Circle shape2 = (Circle) object2;
return shape2.radius == radius;
}
}

Và hình chữ nhật Rectangle

public class Rectangle extends Shape {
public int width;
public int height;

public Rectangle() {
}

public Rectangle(Rectangle target) {
super(target);
if (target != null) {
this.width = target.width;
this.height = target.height;
}
}

@Override
public Shape clone() {
return new Rectangle(this);
}

@Override
public boolean equals(Object object2) {
if (!(object2 instanceof Rectangle) || !super.equals(object2)) return false;
Rectangle shape2 = (Rectangle) object2;
return shape2.width == width && shape2.height == height;
}
}

Abstract class của 2 thằng này là Shape. Tất nhiên, tròn hay vuông thì đều là một cái hình mà thôi

public abstract class Shape {
public int x;
public int y;
public String color;

public Shape() {
}

public Shape(Shape target) {
if (target != null) {
this.x = target.x;
this.y = target.y;
this.color = target.color;
}
}
// Shape cũng có method abstract riêng của nó
public abstract Shape clone();

@Override
public boolean equals(Object object2) {
if (!(object2 instanceof Shape)) return false;
Shape shape2 = (Shape) object2;
return shape2.x == x && shape2.y == y && Objects.equals(shape2.color, color);
}
}

Khi sử dụng, phương thức clone sẽ sử dụng như sau

public static void main(String[] args) {
List<Shape> shapes = new ArrayList<>();
List<Shape> shapesCopy = new ArrayList<>();

Circle circle = new Circle();
circle.x = 10;
circle.y = 20;
circle.radius = 15;
circle.color = "red";
shapes.add(circle);

// Dễ dàng có thể tạo ra một object clone mới, không duplicate source, source đẹp rõ ràng
Circle anotherCircle = (Circle) circle.clone();
shapes.add(anotherCircle);

Rectangle rectangle = new Rectangle();
rectangle.width = 10;
rectangle.height = 20;
rectangle.color = "blue";
shapes.add(rectangle);

cloneAndCompare(shapes, shapesCopy);
}

5. Ưu nhược điểm

Đầu tiên, rõ ràng là sử dụng Prototype pattern không làm cho code độc lập với cái class mà nó clone. Chắc chắn.

Thứ hai, dùng prototype pattern giúp clone object một cách nhanh chóng, không bị duplicate code. Trường hợp object phức tạp, chứa rối rắm nhiều thứ, Prototype là lựa chọn tuyệt vời.

Tuy nhiên, nếu object có tham chiếu hoặc kế thừa từ các object khác. Clone thì dễ, nhưng không biết mức độ ảnh hưởng tới đâu. Nếu object clone có dây mơ rễ má nhiều chỗ -> rất dễ trở thành một đám tơ vò.

6. Tham khảo

Ở phía bên Javascript có thể tham khảo bài viết về prototype cũng khá hay.

Thanks for read – Have a great day – Happy coding!

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

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

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

Todo List: Hiển thị thông báo trong ứng dụng Laravel

Todo List: Hiển thị thông báo trong ứng dụng Laravel

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

Video trong bài viết

Trong bài Kiểm tra dữ liệu, chúng ta đã hiển thị các thông báo về lỗi nhập liệu đến người dùng, các thông báo này rất cần thiết để người dùng biết được trạng thái nhập liệu. Ngoài những thông báo lỗi, chúng ta còn những thông báo cần thiết khác, ví dụ như khi đã thực hiện xong một công việc nào đó.

  API Authentication trong Laravel-Vue SPA sử dụng Jwt-auth
  Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream

Laravel Session lưu dữ liệu dùng chung trong phiên

Như các bạn đã biết, HTTP là giao thức stateless tức là giao thức không trạng thái, các lần truy cập khác nhau sẽ không liên quan và lưu trữ trạng thái của nhau. Chính vì vậy, để lưu trữ thông tin qua các lần truy cập khác nhau, chúng ta có Laravel Session.

Session trong Laravel có thể lưu trữ ở các dạng như file, database, cookie và cả memcache… Để lưu trữ thông tin giữa các lần truy cập rất đơn giản sử dụng cú pháp như sau:

$request->session()->put('key', 'value');

Thông tin lưu trữ ở dạng cặp (key, value), muốn lấy thông tin này thì sử dụng:

$request->session()->get('key');

Lưu trữ dữ liệu nhanh

Đôi khi chúng ta chỉ muốn lưu trữ các thông tin cho đến request tiếp theo, ví dụ khi thao tác dữ liệu ở request hiện tại, trong request tiếp theo chúng ta muốn hiển thị trạng thái là đã thao tác thành công. Các dữ liệu này ở những request kế tiếp đó sẽ bị xóa đi. Để lưu trữ các dữ liệu nhanh này chúng ta sử dụng cú pháp:

$request->session()->flash('success', 'Create todo successful!');

Hiển thị thông báo

Trong các bài học trước, chúng ta mới chỉ hiển thị lỗi khi kiểm tra dữ liệu, trong bài này chúng ta sẽ sử dụng Laravel Session để lưu trữ thông tin giữa các request và hiển thị thông báo khi các thao tác với bản ghi Todo hoàn thành.

Đầu tiên, chúng ta sẽ thực hiện hiển thị thông báo khi lưu trữ Todo thành công, việc lưu trữ này do phương thức store() trong TodosController đảm nhận, sau khi thực hiện save dữ liệu chúng ta sẽ lưu thông tin trạng thái vào Session và trong request tiếp theo sẽ hiển thị nó lên:

public function store()
{
    $this->validate(request(), [
        'name' => 'required|min:6|max:12',
        'description' => 'required'
    ]);

    $data = request()->all();

    $todo = new Todo();
    $todo->name = $data['name'];
    $todo->description = $data['description'];
    $todo->completed = false;
    $todo->save();

    session()->flash('success', 'Todo created successfully.');

    return redirect('/todos');
}

Ở đây sau khi lưu dữ liệu xuống database, chúng ta lưu thông tin (‘success’, ‘Todo created successfully.’) vào Session. Trong request tiếp theo chính là redirect(‘/todos’) là trang danh sách todos, chúng ta hiển thị thông báo này. Chú ý là thông báo này sẽ hiển thị ở các trang khác nhau, do đó sẽ đưa phần hiển thị vào file bố cục resources/views/layouts/app.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
  <title>
    @yield('title')
  </title>
</head>
  <body>
      <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="/">Todos App</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
              <a class="nav-link" href="/todos">todos <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item active">
              <a class="nav-link" href="/new-todos">Create todos <span class="sr-only">(current)</span></a>
            </li>
          </ul>
        </div>
      </nav>
    <div class="container">
      @if(session()->has('success'))
        <div class="alert alert-success">
          {{ session()->get('success') }}
        </div>
      @endif
      @yield('content')
    </div>
  </body>
</html>

Thử tạo mới một Todo chúng ta sẽ có thông báo “Todo created successfully!” khi hoàn thành.

Hiển thị thông báo khi tạo Todo

Tương tự với trường hợp cập nhật và xóa dữ liệu chúng ta cập nhật các phương thức update() và destroy() trong TodosController như sau:

public function update(Todo $todo)
{
    $this->validate(request(), [
        'name' => 'required|min:6|max:12',
        'description' => 'required'
    ]);

    $data = request()->all();

    $todo->name = $data['name'];
    $todo->description = $data['description'];
    $todo->save();

    session()->flash('success', 'Todo updated successfully.');

    return redirect('/todos');
}

public function destroy(Todo $todo)
{
    $todo->delete();

    session()->flash('success', 'Todo deleted successfully.');

    return redirect('/todos');
}

Source code: Bài 16 – Hiển thị thông báo thông qua Laravel Session

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

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

Xem thêm tuyển lập trình Laravel hấp dẫn trên TopDev

Awk siêu tốc

Awk siêu tốc

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

Nếu bạn đã biết 1 scripting language như Python hay Perl việc học AWK sẽ có vẻ hơi thừa/ hơi ngần ngại. Nhưng AWK – ngôn ngữ lập trình sinh ra từ những năm 1970 luôn có chỗ dùng, và sức mạnh đáng gờm.

  10 hiểu lầm tai hại về lập trình
  10 nguyên tắc lập trình nền tảng mà lập trình viên nào cũng cần biết

Bài này giới thiệu các khái niệm cơ bản của ngôn ngữ lập trình AWK, một số cách dùng thông dụng, học xong có thể dùng ngay và vô cùng hữu ích với những người xử lý dữ liệu dạng cột/ bảng mà không biết Python.

Các lệnh trong bài này dùng mawk vì nó được biết là nhanh hơn các bản awk khác, nhưng về tính năng cơ bản là giống nhau, người đọc dùng bản nào cũng được, VD gawk

$ whatis awk
awk (1)              - pattern scanning and processing language

Dùng trong các câu lệnh hàng ngày

AWK rất thích hợp để nhét vào 1 pipe các câu lệnh UNIX, việc mà Python vốn không sinh ra để làm

Ví dụ: đếm số dòng trong file /etc/passwd

$ wc /etc/passwd
  57   95 3193 /etc/passwd

Lệnh wc vốn sinh ra để đếm: dòng, số từ, số ký tự. Bạn có thể viết 1 script Python 5-7 dòng làm chuyện này, nhưng 1 dòng? Hãy thử và nếu thành công, hãy comment!

Với AWK, làm việc này không khó khăn gì. Hãy bỏ qua nếu không hiểu gì, phần giải thích sẽ theo sau

$ cat /etc/passwd | mawk '{ words += NF; chars += length($0) + 1;} END { print NR, words, chars}'
57 95 3193

Một pipe (cmd1 | cmd2 | cmd3) thường bắt đầu bằng cat file, mặc dù nó không phải cách làm tốt (tốn thêm 1 câu lệnh cat – khi mà hầu hết các câu lệnh đều hỗ trợ đầu vào là 1 file), nhưng tiện, nên ta cứ bắt đầu với cat, khi nào cần tối ưu ta sẽ bỏ nó đi. Ở đây, mawk có thể nhận file để xử lý, ta viết lại:

$ mawk '{ words += NF; chars += length($0) + 1;} END { print NR, words, chars}' /etc/passwd
57 95 3193

Một ví dụ khác

$ head /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

Một yêu cầu quái dị có thể xuất hiện như: hãy tính tổng các số ở cột số 3, với các câu lệnh CLI truyền thống, ta làm như sau

$ echo $(cat /etc/passwd | cut -d: -f3 | xargs printf '%s +') 0 | bc
75624

cut giúp lấy cột thứ 3, phân cách bằng dấu :, dùng printf để nối các số lại bằng dấu +, vì thừa 1 dấu + ở đuôi nên ta echo thêm số 0 để cho hợp lệ rồi đưa vào lệnh bc để tính.

$ mawk -F: '{sum += $3} END { print sum }' /etc/passwd
75624

Tương tự cut, ta dùng -F: để chỉ ra sẽ dùng : để phân cách cột, lấy cột số 3 $3, cộng lần lượt các giá trị vào biến sum – khi ta không khai báo, AWK mặc định đó là số 0 nếu thực hiện phép toán với số. Làm như vậy với mỗi dòng (gọi là record trong AWK):

{ sum += $3 }

Và khi hết các dòng (đánh dấu bằng END), ta print ra kết quả

END { print sum }

Khó có thể đánh bại sự ngắn gọn, sạch sẽ này.

Record và field

AWK đọc text vào, mặc định sẽ cắt tại các dấu xuống dòng, tạo thành các record, sau đó mặc định cắt tại dấu space (khoảng trắng), tạo thành các field. Ta hoàn toàn có thể chỉ định AWK cắt ở ký tự khác.

Cấu tạo một chương trình AWK

Một chương trình AWK cấu tạo bởi các câu lệnh (statements) với cú pháp:

              pattern   { action statements }

Chỉ có vậy. Khi viết vào file thì viết mỗi câu lệnh 1 dòng, nhưng hoàn toàn có thể viết trên 1 dòng.

partern

Có nhiều partern, nhưng 3 partern phổ biến và hữu ích nhất là:

  • BEGIN: theo sau là hành động / câu lệnh khi chương trình bắt đầu
  • END: theo sau là câu lệnh được chạy khi chương trình kết thúc
  • KHÔNG GHI PATTERN: thực hiện câu lệnh này cho mỗi record

Ví dụ

'{sum += $3} END { print sum }'

Ví dụ sau không có BEGIN, với mỗi record ta sẽ cộng dồn, và khi đọc hết các record, ta print ra tổng. Chú ý: dấu \ ở cuối dòng là cú pháp trong shell cho phép viết 1 dòng thành nhiều dòng, khi chạy AWK chỉ xem toàn bộ chương trình là 1 dòng.

$ echo 'pymi\npython\nfamilug' | mawk '\
 BEGIN { print "the begin" } \
 { printf "got line: %s has length %d\n", $0, length($0) }\
 { print "done process line ", NR }\
 END {print "DONE"}'

the begin
got line: pymi has length 4
done process line  1
got line: python has length 6
done process line  2
got line: familug has length 7
done process line  3
DONE

parttern tìm kiếm

parttern này giúp tìm kiếm các record có chứa một regular expression (hoặc string cố định) và xử lý record đó.

Đếm số dòng chứa từ print:

$ echo -e "printf print \nprintf"
printf print
printf
$ echo -e "printf print \nprintf" | grep -c print
2
$ echo -e "printf print \nprintf" | mawk '/print/ { count += 1 } END { print count }'
2

print

print và printf là 2 output statements (câu lệnh xử lý đầu ra), không phải function nên không sử dụng cú pháp gọi function print(thing)

$ mawk 'BEGIN { print "hello" }'
hello

variable và field variable

Mỗi record chứa nhiều field, hãy tưởng tượng như 1 dòng spreadsheet/excel có nhiều ô ứng với các cột. Các variable có sẵn:

  • $0 – toàn bộ 1 record (dòng) – chú ý dấu $ dùng để truy cập giá trị của field
  • $1 – field 1 (hay có thể nghĩ là cột số 1)
  • $2 – field 2
  • $(NF - 1) – field trước cuối cùng
  • $NF – field cuối cùng
  • NF – số field
  • NR – thứ tự của record, tăng dần sau khi xử lý xong mỗi record (số dòng hiện tại)

Khi truy cập biến, không sử dụng thêm bất cứ ký tự nào (khác với bash, bash phải thêm $varname).

$ echo '1, Le Van Xe, 27, Ha Noi, 0990090090' | mawk -F, '{ print $NF}'
 0990090090
$ echo '1, Le Van Xe, 27, Ha Noi, 0990090090' | mawk -F, '{ print $0}'
1, Le Van Xe, 27, Ha Noi, 0990090090
$ echo '1, Le Van Xe, 27, Ha Noi, 0990090090' | mawk -F, '{ print NF }'
5

Chỉ cần nắm rõ tên các variable có sẵn này, ta đã có một tool cực mạnh để xử lý dữ liệu dạng bảng như Excel/CSV/SQL.

Các kiểu dữ liệu

AWK có string, số (chia làm float và integer), và array. Ta không bàn tới array ở đây, vì nếu cần lập trình gì phức tạp hơn một câu lệnh AWK đơn giản, ta có thể sử dụng Python cho sạch sẽ, gọn gàng, tiện lợi.

Control flow

Là ngôn ngữ lập trình đầy đủ, AWK có if/else/for/while như các ngôn ngữ lập trình “giống C” khác. Ví dụ đếm số chẵn và số lẻ

$ echo -e '1\n2\n3\n4\n20\n30' | mawk '\
{ if ($1 % 2 == 0) \
     { chan += 1 } \
  else { le += 1 } \
} \
END { print chan, le }'

5 1

Function

AWK có sẵn các funtion xử lý string, số thì đủ các phép toán, các function sin cos …, người dùng cũng có thể định nghĩa function của họ. Xem thêm ở đây.

Bonus – giải bài projecteuler 1

Tính tổng các số nhỏ hơn 1000 chia hết cho 3 hoặc 5

$ seq 1 999 | mawk '{ if ($1 % 3 == 0 || $i % 5 == 0) sum += $1 } END { print sum }'
233168

Tham khảo

Hết

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

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 sử dụng Xcode và Tạo project Xcode

Hướng dẫn sử dụng Xcode và Tạo project Xcode

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Hướng dẫn sử dụng Xcode và Tạo project Xcode

1.Cài đặt môi trường và các công cụ cần thiết

1.1.Tạo tài khoản apple develop

1.2.Tải Xcode

Các bạn tải tại đây https://developer.apple.com/xcode/

Xcode là 1 IDE do apple phát triển ,giúp lập trình viên có thể thiết kế các giao diện và viết các câu lệnh code điều khiển, biên dịch và chạy trên Simulator hoặc trên các máy thật iphone.

Hiện nay, hệ điều hành Mac OS X Yosemite được cung cấp miễn phí, mình khuyên các bạn nên tải về và sử dụng, việc này hỗ trợ tốt hơn cho bạn tong quá trình lập trình.

  "Code dễ đọc" là như thế nào?
  "Mẹo bỏ túi" cho dân coder mới vào nghề

2.Tạo project

Khi bạn mở Xcode lên sẽ hiện lên 1 cửa sổ giao diện như sau

Hướng dẫn sử dụng Xcode và Tạo project Xcode

Bên phải là các project chúng ta đã tạo và là trước đó.

Đầu tiên bạn mở Xcode lên và chọn “Create a new Xcode project“, sau đó lại có 1 cửa sổ hiện lên bạn chọn “Single View Application”  để Xcode tạo cho bạn 1 dự án và màn hình đơn.  “Single View Application” là dạng project trắng và chỉ có 01 “màn hình” duy nhất.

Hướng dẫn sử dụng Xcode và Tạo project Xcode

Và khi bạn click Next thì  sẽ hiển thị 1 cửa sổ tiếp theo :

tạo project xcode

  • Product Name: Tên ứng dụng.
  • Organization Name: tên cơ quan, tổ chức hoặc tên lập trình viên.
  • Organization Identifier: tên định danh của cơ quan, tổ chức hoặc của lập trình
    viên.
  • Language: ngôn ngữ lập trình mà bạn sẽ sử dụng trong quá trình lập trình

Khi chúng ta tạo xong thì giao diện Xcode sẽ như đầy đủ như thế này

tạo project xcode

Hướng dẫn sử dụng Xcode và Tạo project Xcode

Xcode sẽ hiển thị thông tin dự án này trog khung Editor

Trong workspace, có thể bạn sẽ nhìn thấy biểu tượng lỗi với thông điệp là “Signing for FoodTracker requires a development team“. Đừng lo lắng nhé, bạn hãy cứ bỏ qua nó mà vẫn có thể lập trình một các bình thường. Cảnh báo này có nghĩa là bạn cần có một nhóm để phát triển ứng dụng.

  • ToolBar: Đây là thanh công cụ của XCode. Tại đây bạn có thể theo dõi trạng thái ứng dụng, chạy thử, bật tắt một vài thành phần giao diện khác.
  • Navigator area: Đây là nơi bạn có thể xem cấu trúc project, trạng thái lỗi, …

File  .swift là các tập tin dùng để viết mã điều khiển đối tượng, triển khai thuậ toán. Phần mở rộng là .storyboard thiết kế giao diện người dùng. Ngoài ra còn có các tập tin .framework là các thư viện được sử dụng trong ứng dụng và các tập tin .plist chứa các thông tin cơ bản và thông tin mở rộng của ứng dụng.

  • Editor area: tại đây bạn có thể viết code hoặc thiết kế giao diện.
  • Utility area: nơi cấu hình giá trị cho các thuộc tính của thành phần giao diện.

Và đây là thành quả sau khi bạn tạo project và run trên máy ảo:

điện thoại trắng

Một số phím tắt cơ bản

Command + mũi tên trái: Xoay bên trái của thiết bị

Command + mũi tên phải: Xoay điện thoại

Ctrl + Command + Z: Giả lập cử chỉ lắc

Hy vọng bài hôm nay sẽ giúp các bạn hiểu chi tiết về các thành phần cơ bản trong Xcode.

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

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

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

Load Balancers II – Determine which servers processes a request

Load Balancers II – Determine which servers processes a request

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

Trở lại chuỗi bài viết chuyên sâu về Load Balacers và Web Server. Biết về khái niệm và cách mà Load Balancers cân bằng lượng request đến đã là tốt.

Tuy nhiên, request ở máy A sẽ đi tới servers nào khi ta có tới cả 100 servers service nhỏ?.

  Angular - Tự xây dựng module "lazy load images"
  Cân bằng tải (Load Balancing)

Để trả lời cho câu hỏi này, hãy cùng nhìn lại chút xíu về Load Balancers Architecture.

Load BalancersThông qua sự “điều tiết” của Web Balancers, nhiều Application Servers nhỏ có thể handle một lượng request lớn.

1. Phán định servers

Vấn đề là Application nào sẽ handle request nào?. Ví dụ: client A ở lần request đầu tiên sẽ gửi tới Application Servers A do Load Balancers điều phối.

Gọi là phán định servers vì không thể ở request thứ nhất, Application Servers A xử l. Request thứ hai lại do Application Servers B xử.

Để có phá định chuẩn rằng Servers nào nên xử lý request nào thì ta cần hiểu rõ về Application Servers trước. Đặc điểm chính là Stateless. Vậy Stateless là gì?.

2. Stateless trong Load Balancers

Stateless có thể được hiểu như là không state. Tại sao nói không State?.

State là trạng thái, mỗi request gửi lên Servers đều mang một trạng thái của riêng nó. Tạo mới, cập nhât, xóa bỏ, … Chữ less ở đây mang ý nghĩa Application Servers sẽ không chịu trách nhiệm lưu trữ State của request.

Load Balancers

Đọc tới đây có bạn sẽ hỏi nếu App Servers lưu trữ State thì sao?. Lấy ví dụ luôn.

Giả sử khách hàng A đang có 2 sản phẩm trong giỏ (2 products). Load Balancers ban đầu phán định App Servers 5 sẽ xử lý request này. Do 4 cái còn lại đang busy.

Vậy nếu khách hàng cập nhật giỏ hàng, thêm xóa bỏ, mua mới?. Mọi request liên quan tới giỏ hàng này đều phải thông qua App Servers 5?

Giữ App Servers 5 cho một giỏ hàng thì quá lã lãng phí. Cũng không đảm bảo sự hoạt động trơn tru của Load Balancers. Chính vì vậy, App Servers giữ trong mình nó chữ Stateless.

Không quan tâm tới state đảm bảo cho mọi server có trách nhiệm và chức năng như nhau. Ai rảnh thì vào xử lý request ngay, không cần quan tâm tới state của request được gửi là như thế nào.

3. Scaling

Giữ cho các App Servers tách biệt với state cũng đảm bảo về khả năng Sclaing khi application mở rộng. Các App Servers có thể độc lập hoạt động mà không cần quan tâm tới state được gửi lên từ request như thế nào.

Load Balancers

Về scalable trong web application thì có thể đọc qua bài viết này. Tìm hiểu thêm về Horizontal và Vertical Scaling.

4. Tổng kết

Quay lại câu hỏi ngay từ ban đầu. Với kiến trúc Distributed Server và Distributed Database. Phán định server nào xử lý request như thế nào?

Câu trả lời là phán định do Load Balancers chỉ định tùy thuộc tình trạng busy hiện tại của các Server khác. Về bản chất thì các App Servers có chức năng tương tự nhau, có thể hoạt động độc lập với nhau.

5. Tham khảo

Thank for reading – Have a nice yearend – Happy coding!

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

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

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

Transaction Processing – Everything must know

Transaction Processing

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

Gì chứ nhắc tới Transaction Processing thì không một Software Engineer nào là không hiểu tường, hiểu tận. Biết có thể chỉ là một phần kiến thức nhỏ, nhưng những khái niệm đặc biệt như transaction cần phải nắm thật vững.

Bài viết này cung cấp một cái nhìn toàn diện, từ cơ bản cho tới nâng cao về Transaction Processing. Thứ được biết đến như là khái niệm cốt lỗi của Database actions, Payment Steps,…

Bắt đầu ngay thôi!

  10 tuyệt kĩ từ trang web nhanh nhất thế giới (phần 1)
  Khái niệm transaction trong database

1. Transaction là gì?

Rõ luôn là phải hiểu transaction là gì trước khi bắt tay vào tìm hiểu Transaction Processing. Ok, khái niệm. Có 3 thứ cần nhớ.

A unit of information processing that is indivisible.

Transaction là một đơn vị của “tiến trình xử lý thông tin” không thể phân chia

Đọc rõ khó hiểu, nhưng túm cái váy lại: transaction là một đơn vị, nó độc lập và không thể chia nhỏ hơn được.

It must either success or fail as a complete unit.

Nó phải thành công hoặc thất bại như là một đơn vị hoàn chỉnh

Đã nhắc tới transaction processing thì lúc kết thúc process, transaction nhất định phải có kết quả là thành công (sucess) hoặc thất bại (fail). Các transaction pending ta thường thấy cũng là đang quá trình chờ đợi. Nói về status khi kết thúc transaction, luôn nhớ rằng một là thành công hai là thất bại. Không có chuyện giữa giữa.

It can never only partically complete.

Transaction không bao giờ hoàn thành một phần

Ví dụ như giao dịch ở ngân hàng. Nếu success -> tiền chuyển đi, nếu fail -> thực hiện transaction mới. Giao dịch kiểu transaction không bao giờ có chuyện thành công một nửa, hoặc chỉ thất bại ở một step nào đó.

Đã fail dù chỉ một tiến trình nhỏ trong transaction cũng khiến cả transaction bị fail.

2. Ví dụ về Transaction Processing

Lý thuyết rõ dài, thôi thì cho xin cái ví dụ để dễ hiểu hơn.

Đây là ví dụ đơn giản nhất về mua vé máy bay. Hiện tại đang còn 5 vé có giá tốt. Mà các ông thì đã mua vé rồi, giờ làm sao để mua được vé giá tốt?.

transaction processing là gì?

Có 3 bước phải tiến hành như sau:

  • 1. Trả lại vé cũ đã mua với giá hơi chát.
  • 2. Cập nhật số lượng chuyến bay còn giảm giá khi đã mua.
  • 3. Thanh toán vé đã mua với số tiền “thơm”.

Hoàn thành cả 3 bước được gọi là một transaction. Trường hợp này, trong một unit, ta phải thực hiện thành công cả 3 actions. Chỉ một trong đó fail cũng khiến transaction thất bại -> vé không mua được.

Ví dụ thì dễ hiểu rồi, giờ tới vấn đề của chữ Processing.

3. Transaction process được hiện thực như thế nào?

Nhắc tới transaction mà focus vào process thì luôn phải nhớ “Two Phase Commit”. Từ khóa này đặc biệt quan trọng, cũng là thứ để biết Sofware Engineer đã hiểu rõ về Transaction Processing hay chưa.

Phase ở đây mang nghĩa là “giai đoạn”, một transaction sẽ trải qua hai giai đoạn để hoàn thành.

3.1 Commit request

Giả sử ta có 3 database A,B và C. Thiết kế cho Scalable Web Application chẳng hạn. Bước đầu tiên của Two Phase Commit là “Commit Request”.

Ở bước này, services hay workers sẽ gửi request tới từng database A,B,C. Request này gần giống như request thật về nội dung. Nói vậy nghĩa là sao.

Khi nhận được request từ phase 1 -> tất cả đều thực hiện thử cập nhật. Trả kết quả về cho services.

hiểu về transaction processSau khi tiến hành cập nhật thử ở DB, kết quả lần lượt được trả về (Yes – có khả năng cập nhật, No – không thể cập nhật).

3.2 Commit

Sau khi kết thúc Commit Request và nhận về được tất cả kết quả từ A,B,C (Return Result). Process Commit sẽ đưa ra phán định cho biết commit của Transaction Processing có thành công hay không?.

Nếu cả 3 đều PASS -> Rõ ràng là transaction thành công. Trường hợp một trong 3 fail -> transaction sẽ phán định fail và thực hiện xử lý tiếp theo.

Transaction processing là gì?Bước thứ 2 của Transaction Process sẽ là phán định kết quả (return result) từ step thứ nhất.

Xử lý tiếp theo ở đây là rollback. Từ rollback thì quen quá rồi.

Trường hợp thất bại, tất nhiên ta không muốn bất cứ dòng dữ liệu nào xuất hiện ở A và B, mặc dù Commit Request báo PASS. Lúc này phase số 3 (có phase 3 tuy nhiên vẫn gọi Two-phase vì nó là chính).

Việc thực hiện Commit Request để lấy result tất nhiên không thực hiện luôn ở Global Database. Sau khi có kết quả Success -> Global sẽ trả lại data như ban đầu trước khi gửi request success.

  1. After receiving notice from the global coordinator that all nodes have committed, the commit point site erases status information about this transaction. – Sau khi nhận được thông báo từ Global rằng tất cả được commit, thông báo cuối cùng về trạng thái commit được trả về.
  2. The commit point site informs the global coordinator that it has erased the status information. – Global lúc này sẽ xóa đi thông tin commit
  3. The global coordinator erases its own information about the transaction. – Sau đó cũng xóa luôn đi thông tin của cả transaction.

4. Tham khảo

Thank you for your attention – Have a good day. Happy Coding!

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

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

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

IronPython

IronPython

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

IronPython là gì?

Theo giới thiệu ở trang chủ IronPython:

IronPython is an open-source implementation of the Python programming language which is tightly integrated with the .NET Framework. IronPython can use the .NET Framework and Python libraries, and other .NET languages can use Python code just as easily.

Ironpython là 1 “implementation” mã nguồn mở của ngôn ngữ lập trình Python, tích hợp chặt chẽ với .NET Framework. IronPython có thể sử dụng .NET Framework và các thư viện Python, các ngôn ngữ .NET khác cũng có thể đọc và chạy code Python dễ dàng.

  File I/O trong Python

Cài đặt IronPython

Vào trang chủ download bộ cài đặt về (link download ở trang chủ là link github). Thời điểm viết bài, IronPython đang ở phiên bản 2.7.8. IronPython 3 đang trong quá trình phát triển, chưa có bản chính thức.

Sử dụng

  • Bật IronPython interpreter bằng cách chạy (bấm đúp – double click) vào file ở đường dẫn: C:\Program Files (x86)\IronPython 2.7\ipy.exe hoặc C:\Program Files (x86)\IronPython 2.7\ipy64.exe. Hoặc bấm nút Start -> gõ cmd -> Enter, sau khi cửa sổ Command Prompt hiện lên thì gõ đường dẫn file: C:\Program Files (x86)\IronPython 2.7\ipy.exe hoặc C:\Program Files (x86)\IronPython 2.7\ipy64.exe:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\HTL>"c:\Program Files (x86)\IronPython 2.7\ipy.exe"
IronPython 2.7.3 (2.7.0.40) on .NET 4.0.30319.42000 (32-bit)
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello from IronPython")
Hello from IronPython
  • Chạy 1 python script đã viết sẵn bằng cách gõ vào Command Prompt: C:\Program Files (x86)\IronPython 2.7\ipy.exe đường_dẫn\đến\script.py. Ví dụ nội dung file D:\HTL\Desktop\script.py:
print("Hello from inside a Python script")
C:\Users\HTL>"c:\Program Files (x86)\IronPython 2.7\ipy.exe" D:\HTL\Desktop\script.py
Hello from inside a Python script
  Thư viện Python: Cái nào tốt nhất cho vai trò gì?

Sử dụng .NET Framework và Python libraries

IronPython có sẵn thư viện clr hỗ trợ load các .NET Assemblies (VD như các file .dll) và sử dụng các công cụ trong đó. IronPython cũng có các libraries kèm theo tương tự như CPython:

C:\Users\HTL>"c:\Program Files (x86)\IronPython 2.7\ipy.exe"
IronPython 2.7.3 (2.7.0.40) on .NET 4.0.30319.42000 (32-bit)
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> clr.AddReference('System')
>>> from System import Environment
>>> print(Environment.SystemDirectory)
C:\Windows\system32
>>> import math
>>> print(math.pi)
3.14159265359

Tài liệu IronPython

Tương tự câu hỏi khi học Python thì dùng tài liệu nào, đối với IronPython thì cũng lấy tài liệu ở trang chủ. IronPython Documentation có 2 phần: phần 1 chính là Python 2.7 documentation, phần 2 là hướng dẫn tích hợp .NET với IronPython.

Kết luận

  • Học ngôn ngữ Python là có thể sử dụng trên nhiều môi trường, với nhiều implementation khác nhau (CPython, IronPython, Jython…).
  • IronPython là sự lựa chọn hợp lý khi làm việc với môi trường Windows và các phần mềm chạy trên Windows.
  • Alternative: Trả lời cho câu hỏi “Mình vẫn muốn dùng CPython và vẫn muốn sử dụng .NET Framework thì làm như thế nào?” -> Tìm hiểu pythonnet nhé. Tuy nhiên mình khuyến khích dùng IronPython để làm việc trên Windows và các phần mềm chạy trên Windows.

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

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

Xem thêm tuyển python lương cao hấp dẫn trên TopDev

Biến số và kiểu dữ liệu số trong Python

Biến số và kiểu dữ liệu số trong Python

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

Trong lập trình biến và kiểu dữ liệu là những khái niệm cơ bản nhất, từ những khái niệm cơ bản này chúng ta mới tiếp tục những phần nâng cao hơn như tương tác với người dùng, các cú pháp điều khiển luồng ứng dụng, thuật toán… Khóa học này nhắm đến cả những bạn mới bắt đầu làm quen với lập trình do đó nội dung đi khá chi tiết, bạn nào đã có kiến thức sẵn có thể xem các bài tiếp theo.

1. Biến số

1.1 Biến số trong ngôn ngữ lập trình là gì?

Biến số (variable) là một khái niệm cơ bản trong lập trình, biến dùng để lưu trữ thông tin, các tham chiếu và sử dụng để thao tác dữ liệu. Các biến bản chất là một cách để đánh nhãn cho dữ liệu với một tên gợi nhớ, các chương trình có thể hiểu được cần lấy dữ liệu từ đâu với biến đó. Đặt tên biến gợi nhớ cũng giúp cho các lập trình viên khác có thể hiểu được đoạn code bạn chia sẻ. Một hình tượng khác có thể dễ hiểu hơn là các biến giống như những chiếc công tơ nơ chứa bên trong các nội dung là đồ vật, hàng hóa… được đánh số (đặt tên) ví dụ công tơ nơ thực phẩm, công tơ nơ đồ điện giúp cho muốn tìm đến một loại hàng hóa nào đó dễ dàng.

Trong Python, các biến được khai báo với cú pháp như sau:

ten_bien = gia_tri

Trong đó:

  • ten_bien: là một tên gợi nhớ cho dữ liệu cần xử lý, ví dụ tuoi_nguoi_dung, tong_so_tien… Chú ý nên đặt tên gợi nhớ giúp cho người khác hoặc chính bản thân bạn có thể đọc lại code một cách dễ dàng, tránh các tên biến theo kiểu abc, xyz, heeeeee, hiiiii…
  • gia_tri: là giá trị khởi tạo cho biến, giá trị này sẽ được lưu vào bộ nhớ máy tính và khi chương trình cần dùng đến dữ liệu này sẽ gọi đến tên biến. Giá trị có thể là số, chuỗi ký tự hoặc thậm chí là một hàm tính toán khác.

Quay lại ví dụ Hello world trong bài trước, chúng ta in ra màn hình một lời chào bằng câu lệnh print(). Tiếp theo, chúng ta sẽ sử dụng một biến lưu trữ câu chào và thực hiện in ra màn hình câu chào thông qua biến này.

loi_chao = "Hello, world!"
print(loi_chao)

Kết quả là giống nhau, vậy tại sao cần sử dụng biến trong Python? Mình sẽ ví dụ cho các bạn thấy tại sao cần biến số, ví dụ người dùng nhập vào tên và chúng ta in ra lời chào. Như vậy tên người dùng nhập vào cần được lưu trữ trong một biến ten_nguoi_dung vì chúng ta không thể biết trước tên người dùng là gì?

Như vậy, biến số ngoài việc lưu giá trị còn để “xào nấu” dữ liệu. Giá trị trong biến có thể thay đổi. Ví dụ tiếp theo:

age = 30
print(age)

age = 40
print(age)

Kết quả chúng ta có số 30 in ra trước và đến dòng thứ 2 in ra số 40.

1.2 Cách đặt tên biến

Mỗi ngôn ngữ lập trình có quy ước bắt buộc hoặc một thói quen cộng đồng về việc quy chuẩn đặt tên khác nhau. Ví dụ có các kiểu đặt tên như:

  • underscore hay snake_case: sử dụng các dấu gạch dưới phân cách các từ trong tên biến. Ví dụ: ten_nguoi-dung, TI_LE_CHIET_KHAU
  • camelCase: viết hoa các chữ cái đầu tiên của từng từ trừ chữ cái từ đầu tiên. Ví dụ: tenNguoiDung
  • PascalCase: viết hoa tất cả các chữ cái đầu tiên của từng từ. Ví dụ: TenNguoiDung.

Trong Python, các kiểu đặt tên trên đều sử dụng được, tuy nhiên theo quy ước viết code chung của cộng đồng thì sử dụng kiểu gạch chân. Tên các biến sẽ được viết thường và tên hằng số được viết hoa.

# Tên biến trong Python
ten_nguoi_dung = "Nguyen Van A"
tuoi_nguoi_dung = 35

# Tên hằng số trong Python
SO_PI = 3.14159
KHACH_HANG_LA_THUONG_DE = true

Một số chú ý khi đặt tên biến trong Python:

  • Tên biến có thể chứa chữ số nhưng không được phép bắt đầu bằng chữ số.
  • Tên biến không được chứa các ký tự đặc biệt ngoài dấu gạch chân _.
  Những cải tiến đáng giá của Python 3.12
  Biến và kiểu dữ liệu cơ bản trong Python

2. Kiểu dữ liệu số trong Python

Kiểu dữ liệu số trong Python bao gồm hai loại là kiểu nguyên và kiểu thập phân. Trong một số các ngôn ngữ lập trình khác, kiểu nguyên hoặc kiểu thập phân còn được chi tiết hơn với khoảng rộng của dải số có thể (độ dài ô chứa số đó, ví dụ int và longint khác nhau). Python chỉ phân biệt số có và không có dấu chấm thập phân.

# Kiểu số nguyên - integer
tuoi_nguoi-dung = 35

# Kiểu số thập phân - float
ti_le_binh_chon = 8.2

3. Thực hiện phép toán trong Python

Trong Python chúng ta có thể thực hiện các phép toán đơn giản như +, -, *, / với quy tắc tính giống như ngoài thực tế là ưu tiên trong ngoặc trước, ngoài ngoặc sau, trong phép toán trước, ngoài phép toán sau (phép toán như khai căn, số mũ, logarit…), nhân chia trước, cộng trừ sau. Đây là các thứ tự thực hiện phép toán theo luật Pemdas, Bodmas.

Ví dụ thực hiện một phép tính trong Python:

maths_operation = 1 + 3 * 4 / 2 -2
print(maths_operation)

Kết quả nhận được là 5.0. Chú ý, kết quả của phép chia trong Python luôn trả về là một số thập phân dù phần thập phân có thể bằng 0.

4. Phép chia lấy phần nguyên và lấy phần dư trong Python

Trong ví dụ trên, nếu chúng ta muốn trả về là một số nguyên, trong Python chúng ta sẽ sử dụng toán tử // thay cho /. Toán tử này trả về phần nguyên của phép chia.

Ví dụ:

# Phép chia lấy phần nguyên
integer_division = 8 // 3
print(integer_division)

# Kết quả là 2 

Ngoài ra, Python cũng có toán tử % để lấy phần dư trong phép chia. Chúng ta có thể tính toán nếu biết phần nguyên nhưng sử dụng toán tử có sẵn sẽ thuận tiện hơn:

# Phép chia lấy phần dư
division_with_remainder = 13 // 5
print(division_with_remainder)

# Kết quả là 3 vì 13 chia 5 dư 3

Toán tử lấy phần dư phép chia có ứng dụng xác định một số là số chẵn hay số lẻ bằng cách kiểm tra phần dư trong phép chia cho 2 có kết quả là 0 hay 1. Vì số chẵn chia hết cho 2, số lẻ chia cho 2 dư 1. Kết quả này thường ứng dụng vào việc tô màu cho các dòng trong một bảng dữ liệu, giúp cho bảng dữ liệu dễ đọc hơn.

Bảng dữ liệu có phối màu nhờ xác định dòng chẵn lẻ

Như vậy chúng ta đã được giới thiệu về biến số là gì, cách đặt tên biến trong Python và kiểu dữ liệu đầu tiên là kiểu số (integer, float). Những kiến thức ban đầu rất cơ bản, bạn nào chưa bao giờ học lập trình nên đọc và thực hành kỹ bởi đây là nền tảng không chỉ học Python mà bất kỳ ngôn ngữ lập trình nào bạn sẽ tìm hiểu sau này.

5. Các phép toán phức tạp trong Python

Mặc định, Python hỗ trợ các phép toán thông thường để chúng ta tính toán, khi cần dùng đến các phép toán phức tạp hơn, chúng ta có thể sử dụng thư viện math. Để sử dụng thư viện này trong phần đầu của code chúng ta sử dụng lệnh import math để hệ thống tải thư viện này và chúng ta có thể sử dụng các hàm mà math cung cấp.

Ví dụ, có diện tích hình vuông ta muốn xác định cạnh của nó bằng hàm khai căn bậc 2 như sau:

import math

area_square = 64
square_edge = math.sqrt(area_square)
print(square_edge) # Kết quả là 8

Thư viện math còn có một số các hàm toán học hay sử dụng như sin, cos, log, pow (lũy thừa)…

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

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

Xem thêm tìm việc lập trình viên hấp dẫn trên TopDev

Function trong Python là gì? Tạo Function trong Python

Function trong Python là gì? Tạo Function trong Python

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Function trong Python là gì? Tạo Function trong Python

Function trong Python là gì?

Trong Python, function là một nhóm các câu lệnh (khối code) liên quan tới nhau, nhằm mục đích thực hiện một công việc nào đó.

Function giúp chia nhỏ chương trình thành các module nhỏ hơn. Chương trình càng lớn thì function càng nhiều.

Function giúp sử dụng lại các đoạn code. Tránh lặp lại các đoạn code trùng nhau.

Xem thêm việc làm python tuyển dụng từ các công ty lớn trên TopDev

Cú pháp của Function, cách tạo Function

Cấu trúc function:

def function_name ( arg1, arg2, ...) : 
 ...... 
# function body 
 ......
  • Từ khóa def đánh dấu bắt đầu function header
  • Tên của một function phải là duy nhất
  • Dấu hai chấm : đánh dấu kết thúc function header
  • Phần body mô tả công việc của function
  • Các function có thể có từ khóa return để trả về một kết quả sau khi function xử lý.

Ví dụ:

def subtract(a, b):
return (a-b)

def say_hello():
print("Hello World")

Gọi function: để gọi một function ta viết tên và các tham số của nó.

say_hello()
print("10 - 5 = %d" % subtract(10, 5)) # prints -2

Kết quả:

Hello World
10 - 5 = 5
  Python Lists: Append vs Extend (Có ví dụ)

Phạm vi và vòng đời của biến trong function

Các biến trong function chỉ có giá trị bên trong function (biến local). Sau khi function kết thúc, chúng bị hủy đi.

Ví dụ:

def my_func():
 x = 10
print("Value inside function:",x)

x = 20
my_func()
print("Value outside function:",x)

Kết quả:

Value inside function: 10
Value outside function: 20

Okay, Done!

  Vẽ đồ thị trong Python với thư viện Matplotlib

References: https://docs.python.org/2.0/ref/function.html

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

Xem thêm IT tuyển dụng từ các công ty lớn trên TopDev

Lý thuyết toán ma trận sử dụng trong các thuật toán Machine Learning

Lý thuyết toán ma trận sử dụng trong các thuật toán Machine Learning

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

Machine learning là một tập hợp rất nhiều các thuật toán khác nhau và nó có liên hệ rất mật thiết với toán học, đặc biệt là toán cao cấp. Chúng ta ai đã mài đũng quần trên giảng đường đại học đều không còn xa lạ với Đại số tuyến tính và đây cũng là kiến thức nền tảng của rất nhiều các thuật toán sẽ được giới thiệu trong Machine Learning.

  9 hiểu lầm "ngớ ngẩn" về machine learning
  Chia sẻ cơ bản sử dụng machine learning để giải quyết bài toán.

1. Một số khái niệm cơ bản

1.1 Vô hướng (Scalar)

Scalar (mathematics), an element of a field, which is used to define a vector space, usually the field of real numbers

Một đại lượng vô hướng là một phần tử của một trường được sử dụng để xác định một không gian vector, thông thường ở đây là trường số thực.

Wiki

Tóm lại đại lượng vô hướng (Scalar) là một số bất kì thuộc tập số nào đó. Khi định nghĩa một số ta phải chỉ rõ tập số mà nó thuộc vào. Ví dụ, nn là số tự nhiên sẽ được kí hiệu: nNn∈N, hoặc rr là số thực sẽ được kí hiệu: rRr∈R. Một số thường có thể định nghĩa được bằng một kiểu dữ liệu nguyên thủy của các ngôn ngữ lập trình. Như số tự nhiên có thể là kiểu int, số thực có thể là kiểu float trong Python.

1.2 Véc tơ (Vector)

Vector là 1 mảng của các đại lượng vô hướng tương tự như mảng 1 chiều trong các ngôn ngữ lập trình. Các phần tử trong vector được đánh địa chỉ và có thể truy cập nó qua các địa chỉ tương ứng của nó. Trong toán học, một vector có thể là vector cột nếu các nó được biểu diễn dạng cột, hoặc có thể là vector hàng nếu nó được biểu diễn dưới dạng cột của các phần tử.

Một véc-tơ cột có dạng như sau:

x=⎡⎣⎢⎢⎢⎢x1x2xn⎤⎦⎥⎥⎥⎥x=[x1x2⋮xn]


Một véc-tơ hàng có dạng như sau:

x=[x1x2xn]x=[x1x2⋯xn]

Trong đó, x1x1x2x2, …, xnxn là các phần tử thứ 1, thứ 2, … thứ n của vector.

1.3 Ma trận (Matrix)

Ma trận trên trường K là một bảng liệt kê các số như: số thực, số phức hay một hàm số,… được sắp xếp theo một trật tự nhất định gốm có m dòng và n cột

A=⎡⎣⎢⎢⎢⎢⎢a11a21am1a12a22am2a1na2namn⎤⎦⎥⎥⎥⎥⎥A=[a11a12⋯a1na21a22⋯a2n⋮⋮⋱⋮am1am2⋯amn]

Trong đó aijaij là phần tử dòng i cột j, phần tử này có thể là số thực hoặc số phức. Ma trận này được ký hiệu là A=(aij)mxnRm×nA=(aij)mxn∈Rm×n

Như vậy véc tơ là trường hợp đặc biệt của ma trận:

  • m = 1 chúng ta có ma trận A=(aij)1xnA=(aij)1xn là véc tơ hàng.
  • n = 1 chúng ta có ma trận A=(aij)mx1A=(aij)mx1 là véc tơ cột.

Ma trận tương ứng với mảng 2 chiều trong các ngôn ngữ lập trình. Véc tơ tương ứng với mảng 1 chiều.

1.4 Ten-xơ (Tensor)

Ten-xơ là một mảng đa chiều, nó là trường hợp tổng quát khi biểu diễn trường số đa chiều. Như vậy, ma trận, véc tơ và vô hướng chỉ là những trường hợp cụ thể của ten-xơ:

  • Ma trận là ten-xơ 2 chiều.
  • Véc tơ là ten-xơ 1 chiều.
  • Vô hướng là ten-xơ 0 chiều.

Các phần tử trong ten-xơ được xác định bằng các chỉ số trên từng chiều của ten-xơ, ví dụ một ten-xơ 3 chiều A=(aijk)mxnxpA=(aijk)mxnxp khi đó phần tử aijkaijk sẽ ở hàng i, cột j và mặt phẳng k.

Tìm ngay việc làm Machine Learning tại TopDev!

2. Một số ma trận đặc biệt

2.1 Ma trận không

Ma trận không là ma trận mà các phần tử bên trong đều bằng 0, aij=0,i,jaij=0,∀i,j. Ma trận không được ký hiệu là 

=⎡⎣⎢⎢⎢⎢⎢000000000⎤⎦⎥⎥⎥⎥⎥∅=[00⋯000⋯0⋮⋮⋱⋮00⋯0]

2.2 Ma trận đơn vị

Ma trận đơn vị là ma trận vuông có các phần tử trên đường chéo từ bên trên tay trái xuống bên dưới tay phải bằng 1, còn các phần tử khác bằng 0. Ma trận đơn vị thường được ký hiệu là InIn trong đó nn là số hàng và số cột của ma trận:

{aij=0,ijaij=1,i=j{aij=0,∀i≠jaij=1,∀i=j

In=⎡⎣⎢⎢⎢⎢⎢100010001⎤⎦⎥⎥⎥⎥⎥In=[10⋯001⋯0⋮⋮⋱⋮00⋯1]

2.3 Ma trận vuông

Ma trận vuông là ma trận có số hàng bằng với số cột A=(aij)n×nA=(aij)n×naijRn×naij∈Rn×n. Trong ma trận vuông, đường chéo từ trên bên trái xuống dưới bên phải được gọi là đường chéo chính {aij}i=j{aij}∀i=j.

Ví dụ một ma trận vuông:

A=⎡⎣⎢132309255⎤⎦⎥A=[13−2−305−295]

2.4 Ma trận nghịch đảo

Cho một ma trận vuông A=(aij)n×nRn×nA=(aij)n×n∈Rn×n, nếu có ma trận B=(bij)n×nRn×nB=(bij)n×n∈Rn×n sao cho A×B=InA×B=In với InIn là ma trận đơn vị có kích thước nn thì ta nói rằng:

  • Ma trận AA là khả nghịch.
  • Ma trận BB là ma trận nghịch đảo của AA và được thường ký hiệu là A1A−1

Ma trận nghịch đảo thường được sử dụng để tìm lời giải cho phương trình tuyến tính dạng A×x=BA×x=B với A=(aij)n×nRn×nA=(aij)n×n∈Rn×nx=[x1x2...xn]x=[x1x2…xn] và B=(bij)n=[b1b2...bn]RnB=(bij)n=[b1b2…bn]∈Rn.

Phương trình tuyến tính này có thể viết dưới dạng chi tiết như sau:

⎧⎩⎨⎪⎪⎪⎪⎪⎪a11x1+a12x2+...+a1nxn=b1a21x1+a22x2+...+a2nxn=b2...an1x1+an2x2+...+annxn=bn{a11x1+a12x2+...+a1nxn=b1a21x1+a22x2+...+a2nxn=b2...an1x1+an2x2+...+annxn=bn

Để giải phương trình này ta chỉ cần tìm ma trận nghịch đảo A1A−1, thật vậy:

A1×A×x=A1×Bx=A1×BA−1×A×x=A−1×B⇒x=A−1×B

2.5 Ma trận chuyển vị

Ma trận chuyển vị, ký hiệu ATAT là ma trận được thành lập từ ma trận ban đầu bằng cách chuyển dòng thành cột và ngược lại:

AT=⎡⎣⎢⎢⎢⎢⎢a11a21an1a12a22am2a1ma2manm⎤⎦⎥⎥⎥⎥⎥AT=[a11a12⋯a1ma21a22⋯a2m⋮⋮⋱⋮an1am2⋯anm]

Chú ý: Đôi khi, người ta định nghĩa véc tơ cột từ véc tơ dòng như sau:

x=[x1,x2,,xn]x=[x1,x2,…,xn]⊺

Ma trận đối xứng:

Nếu một ma trận bằng chính ma trận chuyển vị của nó thì ma trận đó được gọi là ma trận đối xứng.

A=AA=A⊺ thì AA được gọi là ma trận đối xứng.

2.6 Ma trận liên hợp

Nếu ma trận A=(aij)m×nA=(aij)m×naijCm×naij∈Cm×n có các phần tử là số phức thì khi vừa thực hiện chuyển đổi hàng thành cột và lấy liên hợp phức các phần tử chúng ta được ma trận liên hợp Hermitian, được ký hiệu là AHAH.

Nói cách khác, ta có ma trận A=(aij)m×nA=(aij)m×naijCaij∈C thì ma trận B=(bij)n×mB=(bij)n×mbijCbij∈C là ma trận liên hợp phức nếu:

bij=aji¯¯¯¯¯¯,i=1,n¯¯¯¯¯¯¯¯,j=1,m¯¯¯¯¯¯¯¯¯bij=aji¯,∀i=1,n¯,j=1,m¯

Ví dụ, ta có ma trận sau:

A=[12i23+4ii]A=[1−2i3+4i2−i]

thì ma trận liên hợp phức của A sẽ là:

AH=[1+2i34i2i]AH=[1+2i23−4ii]

Khi AA là ma trận số thực (ARm×nA∈Rm×n) thì ta có AH=AAH=A⊺.

Ma trận Hermitian:

Nếu ma trận A=(aij)m×nCm×nA=(aij)m×n∈Cm×n thì ma trận A được gọi là ma trận Hermitian nếu AH=AAH=A.

3. Các phép toán với ma trận

3.1 Nhân ma trận với một số

Nhân ma trận với một số (vô hướng) là cách thực hiện phép nhân từng phần tử của ma trận với số đó.

α×A=(α×aij)m×nα×A=(α×aij)m×n

α×A=⎡⎣⎢⎢⎢⎢⎢α×a11α×a21α×an1α×a12α×a22α×am2α×a1mα×a2mα×anm⎤⎦⎥⎥⎥⎥⎥α×A=[α×a11α×a12⋯α×a1mα×a21α×a22⋯α×a2m⋮⋮⋱⋮α×an1α×am2⋯α×anm]

Nhân ma trận với một số có những tính chất như sau:

  • Giao hoán: α×A=A×αα×A=A×α
  • Tính chất kết hợp: α(βA)=(αβ)Aα(βA)=(αβ)A
  • Tính chất phân phối: (α+β)A=αA+βA(α+β)A=αA+βA

Ví dụ:

A=⎡⎣⎢⎢⎢5703328061219535⎤⎦⎥⎥⎥A=[536−9−72150−82−33015]

Thì:

2×A=⎡⎣⎢⎢⎢⎢2×52×(7)2×02×32×32×22×(8)2×02×62×12×22×12×(9)2×52×(3)2×5⎤⎦⎥⎥⎥⎥=⎡⎣⎢⎢⎢10140664160122421810610⎤⎦⎥⎥⎥2×A=[2×52×32×62×(−9)2×(−7)2×22×12×52×02×(−8)2×22×(−3)2×32×02×12×5]=[10612−18−1442100−164−660210]

3.2 Phép cộng hai ma trận

Phép cộng hai trận chỉ thực hiện được khi cùng cấp, ví dụ A=(aij)m×nA=(aij)m×n có thể cộng với B=(bij)m×nB=(bij)m×n:

A+B=(aij)m×n+(bij)m×n=(aij+bij)m×nA+B=(aij)m×n+(bij)m×n=(aij+bij)m×n

Viết một cách chi tiết như sau:

A+B=⎡⎣⎢⎢⎢⎢⎢a11a21am1a12a22am2a1na2namn⎤⎦⎥⎥⎥⎥⎥+⎡⎣⎢⎢⎢⎢⎢b11b21bm1b12b22bm2b1nb2nbmn⎤⎦⎥⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢⎢a11+b11a21+b21am1+bm1a12+b12a22+b22am2+bm2a1n+b1na2n+b2namn+bmn⎤⎦⎥⎥⎥⎥⎥A+B=[a11a12⋯a1na21a22⋯a2n⋮⋮⋱⋮am1am2⋯amn]+[b11b12⋯b1nb21b22⋯b2n⋮⋮⋱⋮bm1bm2⋯bmn]=[a11+b11a12+b12⋯a1n+b1na21+b21a22+b22⋯a2n+b2n⋮⋮⋱⋮am1+bm1am2+bm2⋯amn+bmn]

Phép cộng hai ma trận có một số tính chất như sau:

  • Cộng với ma trận không bằng chính nó: A+=AA+∅=A
  • Tính giao hoán: A+B=B+AA+B=B+A
  • Tính kết hợp: A+(B+C)=(A+B)+CA+(B+C)=(A+B)+C
  • Tính phân phối: α(A+B)=αA+αBα(A+B)=αA+αB

3.3 Phép nhân hai ma trận

Cho hai ma trận A=(aij)m×nA=(aij)m×n và B=(bij)n×pB=(bij)n×p. Phép nhân hai ma trận cho kết quả là một ma trận C=(cij)m×pC=(cij)m×p với:

cij=k=1naik×bkj,i=1,m¯¯¯¯¯¯¯¯¯;j=1,p¯¯¯¯¯¯¯cij=∑k=1naik×bkj,∀i=1,m¯;j=1,p¯

Chú ý: Để nhân được hai ma trận thì số cột của ma trận thứ nhất phải bằng số hàng của ma trận thứ hai trong phép nhân.\

Một số tính chất của phép nhân hai ma trận:

  • Nhân ma trận với ma trận đơn vị không làm thay đổi ma trận đó: A×I=AA×I=A
  • Không có tính chất giao hoán trong phép nhân: A×BB×AA×B≠B×A, trong nhiều trường hợp phép nhân B×AB×A còn không tồn tại do số cột của B khác số hàng của A.
  • Tính kết hợp: A×(B×C)=(A×B)×CA×(B×C)=(A×B)×C.
  • Tính phân phối: A×(B+C)=A×B+A×CA×(B+C)=A×B+A×C và (A+B)×C=A×C+B×C(A+B)×C=A×C+B×C.
  • Chuyển vị của một tích bằng tích các chuyển vị theo thứ tự ngược lại: (A×B)=B×A(A×B)⊺=B⊺×A⊺.
  • Liên hợp phức của một tích bằng tích các liên hợp phức theo thứ tự ngược lại: (A×B)H=BH×AH(A×B)H=BH×AH.

4. Giải tích ma trận

4.1 Hàm đa biến số

Như chúng ta đã biết các phương trình đường thẳng y=ax+by=ax+b (có thể viết dạng ax+by+c=0ax+by+c=0) hay phương trình mặt phẳng ax+by+cz+d=0ax+by+cz+d=0. Tổng quát hóa, một siêu mặt phẳng trong không gian n chiều có phương trình như sau:

a1x1+a2x2+...+anxn+a0=0a1x1+a2x2+…+anxn+a0=0

Hàm số đa biến số là một hàm phụ thuộc vào nhiều biến số f(x):RnRf(x):Rn→R. Viết một các chi tiết hơn:

(x1,x2,...,xn)f(x1,x2,...,xn)R(x1,x2,…,xn)→f(x1,x2,…,xn)∈R

Ví dụ, z=x2+y2z=x2+y2 là một hàm số của biến x,yx,y.

Trong machine learning, các vấn đề chúng ta gặp phải không chỉ có đầu ra là một số (vô hướng) mà có thể là một vector, tổng quát hơn có thể là ma trận hoặc tensor. Do đó hàm số đa biến sẽ ở dạng tổng quát hơn, còn gọi là hàm véc tơ như sau:

f(x):RnRmf(x):Rn→Rm

Ví dụ một hàm vector có ba biến số như sau f(x,y,z):R3R2f(x,y,z):R3→R2:

f(x,y,z)=[x2+sin(y)+xzcos(x)+y2z]f(x,y,z)=[x2+sin(y)+xzcos(x)+y2z]

4.2 Đạo hàm riêng

Đạo hàm riêng của một hàm nhiều biến số là đạo hàm theo biến số đó với giả thuyết các biến số khác là hằng số. Ký hiệu fx(x0,y0)fx′(x0,y0) hoặc f(x0,y0)x∂f(x0,y0)∂x, đây là đạo hàm riêng theo biến xx, còn đạo riêng theo biến yy sẽ viết như sau: fy(x0,y0)fy′(x0,y0) hoặc f(x0,y0)y∂f(x0,y0)∂y.

Ví dụ: với hàm số ở phần trên ta có đạo hàm riêng theo các biến x,y,zx,y,z như sau:

f(x,y,z)x=[2x+zsin(x)]f(x,y,z)x′=[2x+z−sin(x)]

f(x,y,z)y=[cos(y)2yz]f(x,y,z)y′=[cos(y)2yz]

f(x,y,z)z=[xy2]

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 Machine Learning hấp dẫn trên TopDev

Tuple comprehension

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

Python có sẵn (builtin) 4 kiểu dữ liệu “compound”/”container” quan trọng, chúng dùng để chứa các giá trị. listtuplesetdict.

Một lập trình viên Python phải nắm thành thạo cả 4 kiểu dữ liệu trên và vận dụng linh hoạt, biết điểm mạnh yếu của từng kiểu. Bàn về chuyện ấy lại cần vài bài dài dòng khác nên sẽ giữ lại “để sau”/”lúc nào rảnh”.

  10 sự thật thú vị về ngôn ngữ lập trình Python
  11 tip học Python dành cho các “newbie”

Comprehension

Comprehension là một đặc sản của Python, một khi biết đến là hay bị nghiện, thứ cú pháp ngắn gọn sạch sẽ ngọt như mía lùi cũng chính là vũ khí giết những con ong ham ăn.

Cú pháp này Python “vay mượn” mà không bao giờ trả từ Haskell – một ngôn ngữ vốn có tiếng khó học và vi diệu. Hãy thử xem 2 ví dụ sau:

In [1]: names = ['vuong', 'tron', 'tam giac']

In [2]: more_than_four_chars = []

In [3]: for name in names:
   ...:     if len(name) > 4:
   ...:         more_than_four_chars.append(name.title())
   ...:

In [4]: print(more_than_four_chars)
['Vuong', 'Tam Giac']

4 dòng code (dòng print không tính) trên để ta filter (lọc) từ một tập hợp đã cho, thu về các phần tử thỏa mãn điều kiện (hơn 4 ký tự) rồi map (biến đổi) các ký tự đứng đầu thành chữ hoa.

Dù đẹp sạch dễ hiểu lắm rồi, nhưng so với list comprehension:

In [5]: names = ['vuong', 'tron', 'tam giac']

In [6]: print([name.title() for name in names if len(name) > 4])
['Vuong', 'Tam Giac']

thì sự ngắn gọn, đơn giản này đánh bại hoàn toàn cú pháp thông thường.

Và ta còn làm tương tự được với setdict:

In [9]: {i for i in [1,2,3,4,1,2] if i % 2 == 0}
Out[9]: {2, 4}

In [10]: {i: i**2 for i in range(5,10) if i % 2 == 1}
Out[10]: {5: 25, 7: 49, 9: 81}

Tuple comprehension

Dễ tưởng tượng ra là ta sẽ có luôn tuple comprehension – vì nghe có vẻ hợp lý mà:

In [13]: type((i for i in range(5,10) if i % 2 == 0))
Out[13]: <class 'generator'>

SAI! khái niệm tuple comprehension không tồn tại. Cùng cú pháp nhưng kết quả thu được là 1 generator.

Vì sao thế?

Tuple được tạo ra, ban đầu trông như 1 phiên bản thiếu tính năng của list, nhưng mục đích tạo ra tuple là hoàn toàn khác. tuple được dùng như khái niệm struct trong các ngôn ngữ khác, nó là tập hợp của các thông tin khác nhau:

In [14]: student = ('Meo', 18, '0699609096', 'PyMi.vn')

và khi dùng thì unpack các giá trị ra:

In [15]: name, age, phone, school = student

In [16]: print(school)
PyMi.vn

Còn list dùng để lặp qua/ duyệt qua:

In [17]: names = ['vuong', 'tron', 'tam giac']

In [18]: for name in names:
    ...:     print('Hello các bạn mình là {}'.format(name.title()))
    ...:
Hello các bạn mình  Vuong
Hello các bạn mình  Tron
Hello các bạn mình  Tam Giac

Xem thêm tại FAQ của Python.

Ok, vậy chẳng có nghĩa lý gì để “comprehension” ra tuple cả.

Lập trình viên phê list comprehension túy lúy!

Đã dùng là nghiện, mà nghiện là rất khó tỉnh. List comprehension hấp dẫn vậy nên thường bị dùng SAI, lạm dụng. Một điều duy nhất quan trọng cần nhớ:

List comprehension là để tạo ra list.

Thế nhưng không ít lần, nó bị lạm dụng, khi người ta không cần đến list:

  • khi chỉ cần đếm “số lượng phần tử”
  • để tính tổng
  • để in ra màn hình
  • để viết những vòng lặp điều kiện phức tạp.

List comprehension tạo ra 1 list, vậy nên nếu không cần tới list kết quả đó thì không nên dùng tới list comprehension mà hãy dùng vòng lặp for thông thường:

Đừng viết:

In [19]: [print(name.upper()) for name in names]
VUONG
TRON
TAM GIAC
Out[19]: [None, None, None]

Hãy viết:

In [20]: for name in names:
    ...:     print(name.upper())
    ...:
VUONG
TRON
TAM GIAC

Ta không tạo ra 1 cái list vô nghĩa chứa 3 phần tử None – tức là tiết kiệm bộ nhớ (memory).

Đừng viết:

In [21]: len([i for i in range(100,1000) if i % 2 == 0])
Out[21]: 450

Hãy viết:

In [22]: c = 0

In [23]: for i in range(100, 1000):
    ...:     if i % 2 == 0:
    ...:         c = c + 1
    ...:

In [24]: print(c)
450

vì ta sẽ không tạo ra 1 list (tạm) chứa 450 phần tử.

Và đừng viết:

In [25]: sum([i for i in range(5000000)])
Out[25]: 12499997500000

Mà hãy viết:

In [26]: sum_zero_to_5mil = 0

In [27]: for i in range(5000000):
    ...:     sum_zero_to_5mil = sum_zero_to_5mil + i
    ...:

In [28]: sum_zero_to_5mil
Out[28]: 12499997500000

bởi ta sẽ không vô tình tạo ra một list chiếm tới ~180MB bộ nhớ chỉ để tính tổng.

Cách tính

In [32]: import sys

In [33]: list_size =  sys.getsizeof([i for i in range(5000000)])

In [34]: all_numbers_size = sys.getsizeof(5000000) * 5000000

In [35]: print(list_size, all_numbers_size, list_size + all_numbers_size)
40215168 140000000 180215168

Và nếu như số vòng for hay lệnh if trong list comprehension nhiều hơn 2,3 nó không còn sạch sẽ và dễ đọc nữa, hãy quay trở về dùng vòng lặp for thông thường. Ở CIA họ dạy thế.

List/set/dict comprehension rất tiện để tạo list/set/dict, nhưng khi không cần tới list/set/dict kết quả, hãy đừng lạm dụng.

Generator

Generator sinh ra các phần tử của list tương ứng, nhưng mỗi lần, chỉ có 1 phần tử được tạo ra, vì vậy thường dùng để tiết kiệm RAM. Cú pháp tạo generator đơn giản chỉ là thay dấu [] thành ().

In [36]: sys.getsizeof([i for i in range(5000000) if i % 3 == 0 or i % 5 == 0])
Out[36]: 19836760

In [37]: sys.getsizeof((i for i in range(5000000) if i % 3 == 0 or i % 5 == 0))
Out[37]: 88

In [38]: sum([i for i in range(5000000) if i % 3 == 0 or i % 5 == 0])
Out[38]: 5833329166668

In [39]: sum(i for i in range(5000000) if i % 3 == 0 or i % 5 == 0) # chỗ này mượn tạm luôn dấu () của sum
Out[39]: 5833329166668

Đã đến lúc lạm dụng generator!!! nó được dùng mọi nơi trong Python3 và là một cải tiến hấp dẫn của Python3 so với Python2.

Hết.

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

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

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

Ngôn ngữ C là gì? Code ví dụ Hello World

Ngôn ngữ C là gì? Code ví dụ Hello World

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Ngôn ngữ C là gì? Code ví dụ Hello World

1. Ngôn ngữ lập trình C là gì?

C là một ngôn ngữ lập trình máy tính. Được dùng để tạo ra các chỉ dẫn cho máy tính.

C được phát triển bởi Dennis M. Ritchie để phát triển hệ điều hành UNIX sau đó được sử dụng để phát triển các phần mềm…

C có thể chạy trên hầu hết các hệ điều hành.

C được coi như là ngôn ngữ mẹ vì nó được dùng để viết ra nhiều ngôn ngữ khác như C++, Python, Java

C được đánh giá là dễ học so với các ngôn ngữ bậc thấp như Assembly hay Pascal… Do đó nó được sử dụng làm môn lập trình cơ sở (Hiện tại một số trường đại học đã chuyển môn cơ sở sang Javascript). Tuy nhiên so với các ngôn ngữ bậc cao như Java, Python thì nó lại khó học hơn rất nhiều.

Tham khảo việc làm lập trình viên C/C++ lương cao trên TopDev

C là một ngôn ngữ bậc trung, được sử dụng để:

  • Kết hợp với Assembly để viết các trình điều khiển
  • Viết hệ điều hành
  • Viết ra các ngôn ngữ khác
  • Sử dụng để viết các hệ thống core

Nhìn chung thì C khá là khó (bởi khái niệm con trỏ, quản lý bộ nhớ) và thường trên trường chỉ học ở mức độ cơ bản. Nếu theo lập trình về phần cứng, hệ điều hành hay các hệ thống core thì mới tiếp tục học nâng cao… do đó mới đầu học C các bạn thấy khó nhằn một chút thì cũng bình thường.

  Kiến thức C cho người mới và cách tự học lập trình C

2. Code ví dụ C – Hello World

Ví dụ in ra dòng chữ ‘Hello World’ bằng ngôn ngữ lập trình C.

Tạo file Hello.c với nội dung sau:

#include <stdio.h>

int main() {
printf("Hello World!");
return 0;
}

(Các file viết bằng ngôn ngữ c có đuôi mở rộng là .c)

  • #include <stdio.h> khai báo file stdio.h, nó là một thư viện mà ta có thể dùng sẵn. Trong trường hợp này hàm printf() mà mình sử dụng đã được định nghĩa trong sdtio.h, nếu mình không khai báo stdio.h thì chương trình sẽ không hiểu hàm printf() là gì.
  • int main() hàm main (chương trình viết bởi c sẽ bắt đầu chạy từ hàm main). int biểu thị kết quả trả về của hàm main là kiểu số nguyên
  • Các dấu {} được dùng để đánh dấu mở đầu và kết thúc của một khối lệnh, một hàm. Dấu ; được dùng để kết thúc 1 lệnh
  • printf("Hello World!"); thực hiện in ra dòng chữ Hello World!
  • return 0; kết quả trả về của hàm main là 0. Trong ví dụ này thì giá trị trả về của hàm main không quan trọng (mình sẽ nói rõ về phần này sau)
  Các từ khóa/key words trong ngôn ngữ C/C++

Chạy file Hello.c

File Hello.c được viết bằng ngôn ngữ C. Do đó để chạy được file Hello.c ta phải biên dịch nó thành mã máy (file .exe) để chạy.

Để biên dịch được các file viết bằng ngôn ngữ C ta cần cài đặt trình biên dịch (complier) cho ngôn ngữ C.

Nếu bạn đang sử dụng linux thì không cần cài đặt thêm vì linux viết bằng C nên nó đã tích hợp sẵn trình biên dịch C.

Trường hợp bạn sử dụng Windows thì phải cài thêm trình biên dịch C như MinGW, Cygwin…

Ngôn ngữ lập trình C là gì? Ví dụ Hello

Mình sử dụng Windows và đã cài trình compiler MinGW.

Thực hiện compile file Hello.c thành file .exe

Ví dụ file Hello.c mình để ở folder D:\programming, mình sẽ mở màn hình cmd, di chuyển tới folder D:\programming

Ngôn ngữ C là gì? Code ví dụ Hello World

Chạy lệnh gcc Hello.c -o hello.exe để build (biên dịch/compile) file Hello.c thành file hello.exe

Ngôn ngữ C là gì? Code ví dụ Hello World

Chạy file hello.exe vừa tạo ra ta sẽ thấy in ra dòng chữ Hello World! trên màn hình.

Ngôn ngữ C là gì? Code ví dụ Hello World

Okay! Done!

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

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

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

Dynamic Sharding – Nghệ thuật của locator

Dynamic Sharding – Nghệ thuật của locator

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

Tìm hiểu về Scalable Web, App hay bất cứ nội dung nào khác liên quan tới database tất nhiên không thể bỏ qua khái niệm về Dynamic Sharding.

Vậy Dynamic Sharding là gì?. Điều gì làm nên sức mạnh của nó?. Điểm mạnh, điểm yếu.

Tất cả sẽ được phân tích cụ thể qua bài viết dưới đây. Bắt đầu ngay thôi nào!.

  Kết nối Database động với PHP, Dynamic Database Connection!
  Kiểm thử tĩnh vs kiểm thử động (Static vs Dynamic testing)

1. Dynamic Sharing là gì?

Đầu tiên, nhắc tới Sharing là nhắc tới kỹ thuật Scaling. Thường sử dụng cho các hệ thống được thiết kế để scalable (có thể mở rộng một cách nhanh chóng).

Vậy Sharding là gì?

Sharding involves breaking up one’s data into two or more smaller chunks, called logical shards. The logical shards are then distributed across separate database nodes, referred to as physical shards, which can hold multiple logical shards. Despite this, the data held within all the shards collectively represent an entire logical dataset.

Shadring là kỹ thuật sử dụng để phân chia data thành 2 hoặc nhiều hơn các khối nhỏ (chunks), cũng được gọi là logical shards. Các khối logical shards này được phân chia và thuộc về các node database nhỏ. Giống như các khối vật lý, có thể được tồn tại trong đó các khối vật lý. Mặc dù vậy, dữ liệu được giữ trong tất cả các shards đại diện chung cho toàn bộ tập dữ liệu logic.

Má, định nghĩa tiếng việt viết ra khéo đọc không ai hiểu. Tốt nhất là anh em nên đọc tiếng anh. Túm cái váy lại thì với Dynamic Sharding, có 2 loại phổ biến nhất là Horizontal Scaling và Vertical Scaling. Đã được đề cập đầy đủ và chi tiết ở bài viết Toàn tập về thiết kế Scalable Web Application II

Hai kiểu Scaling chính (Horizontal và Vertical Scaling). Nguồn ảnh/ Source: digitalocean.com

2. Locator trong Dynamic Sharding

Dynamic Sharding lại gồm 2 từ. Dynamic và Sharding, từ Sharding thì đã nhắc tới ở phía trên. Còn Dynamic?. Nhắc tới Dynamic phải nhớ tới Locator.

Nếu không có Locator thì không có Dynamic. Nói thì hơi khó hiểu, xem thử ví dụ sau:

Giả sử ta có 3 Shards, mỗi Shards lại nắm một đoạn dữ liệu trong DB (tổng là 100). Thằng A thì giữ từ 1-30, thằng B thì giữ từ 30-60, thằng C thì giữ từ 60-100. Trường hợp client muốn request 35. Làm sao client biết để request tới B (vốn là thằng đang giữ từ 30-60).

Đấy là lúc thằng locator ra tay!

Dynamic ShardingLocator sẽ phán định cho biết DB nào sẽ xử lý request tới từ Client.

Chính vì thằng Locator chịu trách nhiệm “điều đào”, ấy lộn “điều request” nên ta mới có cái chữ Dynamic trong khái niệm. Bất kì request nào từ phía client đều đi qua Locator, được Locator xem xét, phán định nên đi về “chốn nào”.

Dùng một đại ca như Locator anh em thấy có ưu nhược điểm gì không?. Quyền lực quá đôi khi cũng là một cái hại.

3. Điểm yếu, điểm mạnh của locator

Thành phần quan trọng nhất của Dynamic Sharding là locator. Locator như là “chị đại” trong giới giang hồ. Do tất cả các client request đến đều thông qua locator. Tất nhiên, luôn có điểm mạnh và điểm yếu của kiến trúc này.

Nói về điểm mạnh thì locator cho phép client request tới chính xác DB có chưa nội dung đang cần. Client A sẽ không đi lệch tới DB B để tìm nội dung mà nó cần. Với cách truy xuất này, thời gian để client A tới DB B được giảm đi đáng kể.

Vấn đề này đã được đề cập tới trong bài viết Load Balancers II – Determine which servers processes a request. Lựa chọn server nào cho request nào. Đây là điểm mạnh đầu tiên của Dynamic Sharding

Tuy nhiên, do tất cả đều thông qua chị đại. Không tránh khỏi trường hợp chị đại “tèo” thì client cũng ra đi. Anh em giang hồ theo chân chị đại là DB cũng không người dẫn đầu. Như “rắn mất đầu”.

Dynamic Sharding locatorLuôn cần tới một Locator backup trong trường hợp locator chính gặp vấn đề.

Lúc này ta cần tới một Locator backup. Locator này cần đồng bộ với locator chính. Tuy nhiên trong các trường hợp Create hay Update ở DB. Locator này lại chưa đáp ứng được, lúc Locator chính sống lại cần synchronous lại ngay.

4. Khi nào thì nên sử dụng Dynamic Sharding

Do tính chất linh động khi sử dụng kiến trúc Dữ liệu phân tán (Distributed Database). Dynamic Sharding được sử dụng cho các kiến trúc lớn như Google Drive, Mega File. Mỗi file được chia thành các phần nhỏ và lưu trữ ở nhiều nơi.

Khi client yêu cầu nội dung file. Dynamic Sharding có thể phán định chính xác các phần nhỏ của file đang ở đâu, sau đó thực hiện nối ghép các file. Đem đến cho người dùng nội dung hoàn chỉnh.

5. Tham khảo

Cảm ơn vì đã đọc bài – Have a great week – Happy Coding!

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

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

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

Cách viết thông báo lỗi phù hợp để cải thiện trải nghiệm người dùng

viết thông báo lỗi
Cách viết thông báo lỗi phù hợp để cải thiện trải nghiệm người dùng

Tác giả: Andrico Karoulla

Đã qua rồi cái thời những thông báo lỗi xuất hiện một cách chung chung và gần như vô ích. Nếu bạn quan tâm đến việc làm ra các sản phẩm hướng tới người dùng và giúp cho trải nghiệm của người dùng trở nên thú vị nhất có thể, thì đây chính là bài viết dành cho bạn. Như đã biết, thông báo lỗi đóng một vai trò quan trọng trong số những tác nhân ảnh hưởng đến trải nghiệm người dùng. Những thông báo lỗi dễ nhận diện và có ích chắc chắn sẽ giúp ích rất nhiều cho việc cải thiện những gì mà người dùng tiếp cận.

viết thông báo lỗi
Viết thông báo lỗi như thế nào để tối ưu trải nghiệm người dùng?

1. Trạng thái hiện tại của thông báo lỗi

Trong một thế giới gọi là hoàn hảo, các thông báo lỗi sẽ là thứ dư thừa và người dùng có thể sử dụng bất kỳ thứ gì bạn đã xây dựng một cách dễ dàng. Nhưng, đáng tiếc là không có một thế giới hoàn hảo như thế, lỗi sẽ xảy ra và người dùng cuối chắc chắn sẽ đối mặt với chúng.

Những lỗi này có thể bắt nguồn từ:

  • Xác thực không thành công
  • Lỗi phía máy chủ
  • Giới hạn tỷ lệ

Và khi có sự cố, thông báo lỗi trên giao diện người dùng thường xuất hiện theo một trong hai cách:

Các lỗi chung chung không có thông tin có ý nghĩa, ví dụ: Something went wrong, please try again later

Thông báo quá cụ thể từ dấu vết ngăn xếp được gửi bởi máy chủ, ví dụ: Error 10x29183: line 26: error mapping Object -> Int32

Cả hai dạng thông báo này đều không hữu ích cho người dùng cuối. Đối với users, lỗi chung có thể tạo ra cảm giác bất lực và thất vọng. Nếu họ nhận được thông báo như vậy, họ hoàn toàn không thể làm gì và không có cách nào để biết tại sao lỗi lại xảy ra và làm thế nào (hoặc nếu) họ có thể giải quyết nó. Điều này có thể khiến website hoặc app của bạn mất lòng tin của người dùng cuối, mất khách hàng hoặc bị đánh giá một sao.

Mặt khác, thông báo lỗi quá cụ thể sẽ bị xem là một lỗ hổng về kỹ thuật của công ty bạn và người dùng cuối đương nhiên không nên nhìn thấy. Thứ hai, cũng là điểm đặc biệt, nếu lĩnh vực hoạt động của công ty bạn liên quan nhiều đến các trải nghiệm người dùng thì thông báo lỗi của phải mang tính con người và hướng đến dịch vụ nhiều hơn.

  Laravel 5.6 thêm Collision Package cho CLI Error Report
  3 lỗi javascript thường mắc phải làm ảnh hưởng perfomance

2. Tại sao nên build các thông báo lỗi có tính hỗ trợ cao hơn?

2.1. Giúp các developers làm việc dễ dàng hơn

Kiểm tra nhật ký người dùng mỗi ngày là việc làm khá tẻ nhạt. Nếu người dùng cuối báo cáo lỗi, điều quan trọng là họ phải cung cấp cho chúng ta nhiều thông tin hữu ích nhất có thể.

Một báo cáo từ một người dùng cho biết với mẫu như thế này:

Hi, I was using the app sometime last night updating my profile and all of a sudden it stopped working. The error said something about a validation error, but I don't know what that means

sẽ ít hữu ích hơn nhiều so với:

Hi, I was using the app sometime last night updating my profile and all of a sudden it stopped working. The error said "We had trouble updating your details. Your address must be located within the EU" but I live in England

Điều này giúp các lập trình viên phía sau tiết kiệm được rất nhiều thời gian và cắt giảm sự nghiên cứu để tìm ra chính xác lỗi đó là gì. Một thông báo lỗi rõ ràng và cụ thể cũng có thể giúp người dùng cuối hiểu được bản thân họ đã làm gì sai và có thể cho phép họ sửa chữa lỗi của mình.

2.2. Hoạt động của hệ thống được trơn tru hơn

Đối với những người làm việc trong các công ty lớn hơn, việc sao chép/nhắn tin có thể thuộc trách nhiệm của một bộ phận hoàn toàn riêng biệt. Càng có nhiều vị trí trong mã yêu cầu thay đổi bản sao, bản sao càng dễ trở nên không đồng bộ với các nguyên tắc thương hiệu của công ty.

Ngược lại, việc lưu giữ tất cả các thông báo lỗi của bạn trong một nguồn duy nhất giúp những người sở hữu bản sao tuân thủ các nguyên tắc thương hiệu đó dễ dàng hơn nhiều. Việc khắc phục sự cố với tin nhắn của bạn khi người dùng điền sai biểu mẫu, thiếu dữ liệu hoặc không có quyền cho một hành động cụ thể có thể tác động tích cực đến quá trình làm việc của team.

Xem thêm Làm thế nào để làm theo “Hướng dẫn” một cách thông minh nhất?

2.3. Trải nghiệm của người dùng cuối được thoải mái hơn

Bằng cách cung cấp thông báo lỗi lành mạnh, mong muốn lớn nhất là để không khiến người dùng cuối cảm thấy khó khăn trong quá trình sử dụng. Như đã mô tả trước đó, thông điệp của một thông báo lỗi được xem là hữu hiệu phải hướng đến dịch vụ. Chúng nên hướng dẫn người dùng cách hoàn thành quy trình làm việc, hoặc ít nhất là cho họ biết họ có thể đến đâu và nhận trợ giúp nếu vấn đề nằm ngoài tầm kiểm soát của họ.

Thông báo lỗi đóng một vai trò quan trọng trong việc ngăn chặn điều này, vì chúng có thể hoạt động như người kiểm soát cuối cùng giúp người dùng tránh được việc bị mắc kẹt hoặc thoát khỏi ứng dụng do thất vọng.

Nếu ai đó đang sử dụng sản phẩm của bạn cho mục đích giao dịch như mua vé máy bay hoặc mua sắm trực tuyến và họ bị dừng lại trong quá trình thực hiện một nhiệm vụ mà không có cách nào để tiếp tục, thì khả năng họ rời khỏi trang web của bạn cho một nhiệm vụ khác sẽ tăng vọt. Và cứ thế, việc đánh mất khách hàng sẽ còn kéo theo rất nhiều hệ lụy đáng lo khác.

error messages

3. Thông báo thế nào được xem là thông báo tốt?

Theo cuốn Microcopy: A complete guide, một thông báo lỗi hữu ích phải đáp ứng được một trong số các tiêu chuẩn sau:

  • Giải thích rõ ràng vấn đề
  • Nếu có thể, hãy cung cấp giải pháp để người dùng có thể hoàn tất quá trình
  • Hoặc hướng dẫn người dùng đến với trang web có thể giúp đỡ họ
  • Tạo một tin nhắn dễ hiểu nhất có thể

Ví dụ đơn giản như sau:

  • Chúng tôi đã giới hạn số lần bạn có thể đặt lại mật khẩu của mình mỗi giờ. Bạn có thể thử lại sau.
  • Vui lòng đăng nhập để xem hồ sơ này
  • Chúng tôi không thể tạo hồ sơ của bạn, chỉ cư dân Vương quốc Anh mới có thể sử dụng ứng dụng của chúng tôi.

4. Build một hệ thống báo lỗi hiệu quả bằng cách nào?

Có một open source gọi là sane-error-messages. Chạy công cụ này sẽ tạo ra một repo hoàn toàn mới được thiết kế để chứa thông báo lỗi mặc định. Bạn có thể điều chỉnh các giá trị mặc định, thêm hoặc xóa tin nhắn, sau đó xuất bản nó để sử dụng trong các ứng dụng dành cho khách hàng của mình.

sane-error-messages hoạt động bằng cách tổng hợp tất cả thông điệp của bạn vào một đối tượng JavaScript duy nhất. Key là một code lỗi và value là một thông báo tương ứng. Code lỗi phải giống với code bạn nhận được từ máy chủ của mình, chẳng hạn như POSTS_NOT_FOUND hoặc CONFLICTING_USER_RECORD. Repo thông báo lỗi cho thấy một chức năng nhận thông báo lỗi từ một code bị lỗi.

Nói một cách ngắn gọn:

  • Người dùng “xem tất cả các sản phẩm”
  • Giao diện người dùng thực hiện một yêu cầu mạng
  • Yêu cầu mạng không thành công và trả về mã lỗi “USER_NOT FOUND”
  • Giao diện người dùng yêu cầu thông báo lỗi tương ứng từ error-messages của bạn
  • Giao diện người dùng áp dụng bất kỳ thông tin ngữ cảnh có liên quan nào
  • Giao diện người dùng hiển thị thông tin này cho người dùng cuối

5. Cách thiết lập thông báo lỗi

Nếu bạn gặp bất kỳ sự cố nào trong quá trình hướng dẫn, bạn có thể gửi thông tin sự cố về GitHub.

Bắt đầu bằng cách chạy

yarn global add sane-error-message

sau đó

sane-error-messages create <dirName>

để mở đầu cho project. Làm vậy sẽ tạo ra một module hoàn toàn mới để bạn tùy chỉnh với các thông báo lỗi mặc định của mình. Module mới sử dụng ẩn tsdx để xử lý tất cả các tập lệnh quản lý module, chẳng hạn như chạy, xây dựng và thử nghiệm.

Bạn có thể tìm hiểu thêm về tsdx tại đây.

Tóm lại, nội dung làm việc sẽ phát triển giống như sau:

/* errorCodes.ts: The file that defines each error code like */
const USER_NOT_ADMIN = '403_USER_NOT_ADMIN'

/* defaultErrorMessages.ts: Maps each code to a default message */
const errorCodes {
  // your codes and messages go here...
  [USER_NOT_ADMIN]: "We're afraid only administrators have access to "
}

/* ErrorMessages.ts: The class you'll use to instantiate your error messages object in the consuming project */
class ErrorMessages {
  // You can override default messages with more specific ones
  constructor: (customErrorMessages: Partial<Record<string | number, string>>): ErrorMessages;

  // Pass through an error code to get your custom message
  getErrorMessage: (code: string | number, fallbackMessage?: string): string;

  // Checks to see if the argument is a valid error code and acts as a guard for non-ErrorCode values
  isErrorCode(code: string | number): boolean;

  // Returns the errorCodes object with your custom messages
  messages: Record<ErrorCode, string>
}

type ErrorCode = ValueOf<errorCodes>

6. Cách xử lý thông báo lỗi

Nếu bạn đã tạo một repo có tên custom-error-messages và xuất bản nó lên npm, bạn có thể sử dụng nó trong các ứng dụng của mình bằng cách làm như sau:

import { ErrorMessages } from 'custom-error-messages';

const customErrorMessages = {
  '400_validation': 'Please enter the fields in your form correctly',
};

// Initialise your errorMessages object with your custom messages
const errorMessages = new ErrorMessages(customErrorMessages);

function riskyFunction() {
  try {
    // Throws an error 
    await boom();
  } catch (err) {
    // Get the error code our server sent over
    const { code } = err;
		
    // Get the code's corresponding message
    const message = errorMessages.getErrorMessage(code);
    
    // Display the message to the client
    displayNotification(message);
  }
}

Sau đó, bạn có thể lấy tất cả các code bị lỗi mà phía máy chủ trả về và áp dụng các thông báo tương ứng cho chúng. Khi đã sẵn sàng, bạn có thể xuất bản công cụ của mình lên NPM, sau đó sử dụng nó từ các ứng dụng dành cho khách hàng của bạn.

Lỗi là một trong những vấn đề thường xuyên gặp khi phát triển web, app. Biết cách cải thiện và sửa chữa vấn đề chắc chắn sẽ giúp cho công việc của bạn hoạt động trơn tru và hiệu quả hơn.

Bài viết được phỏng dịch dựa trên bài gốc tại freecodecamp.org

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

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

Cài đặt TestNG trong Eclipse

Cài đặt TestNG trong Eclipse

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

TestNG là một nền tảng được sử dụng để giúp chúng ta thiết kế tự động test chức năng hoặc unit test trong Java. Eclipse là một trong những IDE rất phổ biến cho phát triển các test trong Java. Và để sử dụng testNG, không phải là bạn sẽ tải về và cài đặt như một cái tool, mà sẽ giống như một cái phần mềm nho nhỏ được cài đặt tích hợp trong Eclipse nha.

Ngày xưa còn chưa biết đến automation, hóng được testNG, thì cứ nghĩ nó là một cái tool độc lập phải cài vào máy mới dùng được. 😦 Giờ thì thông tin nhiều hơn rồi nên chắc không ai bị như mình ngày đấy đâu! hihi

  Hướng dẫn cách kết nối đến Database MySQL trong Eclipse
  A/B testing và những tiêu chí chính để đánh giá sự thành công của ASO

Hôm nay thì mình sẽ hướng dẫn các bạn các bước để cài đặt testNG trong Eclipse nhé!

1. Mở Eclipse IDE. Chọn Help > Install new software… -> Trên màn hình sẽ hiển thị một cửa sổ có tên Install:

Cài đặt TestNG trong Eclipse

2. Nhấn nút Add, màn hình lúc này sẽ hiển thị một popup nho nhỏ, bạn sẽ điền thông tin này vào từng trường tương ứng nhé:

  1. Name: TestNg ( Bạn có thể đặt tên tùy ý chỗ này)
  2. Location: http://beust.com/eclipse/  (Link này thì lấy chính xác nhé! :D)
  3. Nhấn OK

Cài đặt TestNG trong Eclipse

3. Check vào checkbox TestNG vừa hiển thị, sau đó nhấn Next

Cài đặt TestNG trong Eclipse

4. Check đồng ý vào điều khoản liên quan đến bản quyền

Cài đặt TestNG trong Eclipse

5. Lúc này quá trình download diễn ra, và TestNG sẽ được cài đặt sau đó

Cài đặt TestNG trong Eclipse

6. Sau khi quá trình cài đặt ở bước trên đã xong, sẽ có một cửa sổ hiển thị yêu cầu bạn sẽ khởi động lại Eclipse để cập nhật những cài đặt vừa rồi. Bạn chọn Yes để hoàn tất việc cài đặt TestNG.

Cài đặt TestNG trong Eclipse

Rất đơn giản đúng không nào!

Có một cách khác mà bạn cũng có thể sử dụng để cài đặt TestNG cho Eclipse đó là:

  1. Click Help > Eclipse Marketplace…
  2. Gõ TestNG và nhấn Go để tìm kiếm framework
  3. Nhấn Install để cài đặt
  4. Chờ cho đến khi cài đặt xong và khởi động lại TestNG là được

Cài đặt TestNG trong Eclipse

Hi vọng là với các bước đơn giản phía trên bạn có thể cài đặt TestNg một cách dễ dàng và nhanh chóng hơn.

Chúc một đầu tuần tràn đầy năng lượng 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

RxSwift 7: Disposing và terminating

RxSwift 7: Disposing và terminating

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

Trong bài trước, chúng ta đã nghiên cứu cách tạo các observables ở những kiểu khác nhau. Ở bài chúng ta nghiên cứu phần xử lý và chấm dứt chúng.

  RxSwift 10: Làm việc với PublishSubjects
  RxSwift 2: Khái niệm cơ bản về lập trình bất đồng bộ

Hãy nhớ rằng 1 observable sẽ không làm gì cho đến khi nó nhận được đăng ký(subscription). Một đăng ký kích hoạt nó phát ra các sự kiện, cho đến khi nó tạo ra 1 sự kiện .error hoặc .completed để kết thúc. Bạn có thể đăng ký nó và chấm dứt nó. Cùng xem ví dụ sau:

example(of: "dispose") {
  // 1
  let observable = Observable.of("A", "B", "C")
  // 2
  let subscription = observable.subscribe { event in
// 3
    print(event)
  }
}
  1. Tạo 1 observable gồm các string
  2. Đăng ký vào observable, phát ra các sự kiện
  3. Hiển thị các sự kiện phát ra

Kết quả:

--- Example of: dispose ---
next(A)
next(B)
next(C)
completed

Để hủy 1 subscribe, ta thêm dispose() cho nó. Và nó ngừng phát ra sự kiện. Thêm đoạn code này vào cuối chương trình:

subscription.dispose()

Quản lý hủy đăng ký rất tẻ nhạt, cho nên RxSwift cung cấp cho chúng ta công cụ để hủy là hàm .disposed(by:), và sẽ tự động gọi dispose mỗi khi đăng ký bị hủy. Cùng xem đoạn code sau:

example(of: "DisposeBag") {
  // 1
  let disposeBag = DisposeBag()
// 2
  Observable.of("A", "B", "C")
    .subscribe { // 3
print($0) }
    .disposed(by: disposeBag)
}
  1. Tạo 1 disposeBag
  2. Tạo 1 observable
  3. Subscibe và hiển thị các sự kiện của nó
  4. Trả về giá trị cho disposeBag

Đây là mẫu mà bạn sẽ sử dụng thường xuyên nhất, tạo và đăng ký 1 observable đồng thời thêm đăng ký vào xử lý disposeBag. Khi bạn quên đăng ký disposeBag cho nó có thể gây rò rỉ bộ nhớ. Tuy nhiên đừng lo lắng, trình biên dịch sẽ cảnh báo cho bạn.

Trong các ví dụ trước, bạn quan sát các sự kiện thông qua sự kiện .next. Cùng xem ví dụ sau:

example(of: "create") {
    Observable<String>.create { observer in
      // 1
      observer.onNext("1")
      // 2
      observer.onCompleted()
    // 3
      observer.onNext("?")
    // 4
      return Disposables.create()
    }
}
  1. Thêm sự kiện .next cho observer
  2. Thêm sự kiện .completed
  3. Thêm sự kiện onNext cho Observer
  4. Trả về 1 disposable

Bạn có nghĩ phần tử onNext “?” có emmit cho subscibers không? Cùng xem ví dụ sau:

example(of: "create") {
    let disposeBag = DisposeBag()
    
    Observable<String>.create { observer in
      // 1
      observer.onNext("1")
      // 2
      observer.onCompleted()
    // 3
      observer.onNext("?")
    // 4
      return Disposables.create()
    }.subscribe(
        onNext: { print($0) },
        onError: { print($0) },
        onCompleted: { print("Completed") },
        onDisposed: { print("Disposed") }
      )
    .disposed(by: disposeBag)
}

Kết quả như sau:

--- Example of: create ---
1
Completed
Disposed

Vì sự kiện complete đã phát ra cho nên sự kiện 3 không thể phát ra nữa. Điều gì sẽ xảy ra khi bạn thêm 1 sự kiện error cho nó? Cùng thêm đoạn code sau vào đầu file:

enum MyError: Error {
  case anError
}

Và thêm đoạn code sau vào giữa .onNext và .onCompleted:

observer.onError(MyError.anError)

Kết quả như sau:

--- Example of: create ---
1
anError
Disposed

Điều gì sẽ xảy ra khi chúng ta không emit ra sự kiện onCompleted và .error cũng như không đăng ký với disposeBag? Sửa lại đoạn code như sau:

example(of: "create") {
  enum MyError: Error {
    case anError
  }
  let disposeBag = DisposeBag()
  Observable<String>.create { observer in
    // 1
    observer.onNext("1")
//    observer.onError(MyError.anError)
    // 2
//    observer.onCompleted()
// 3
    observer.onNext("?")
// 4
    return Disposables.create()
  }
  .subscribe(
    onNext: { print($0) },
    onError: { print($0) },
    onCompleted: { print("Completed") },
    onDisposed: { print("Disposed") }
)
//   .disposed(by: disposeBag)
}

Kết quả như sau:

--- Example of: create ---
1
?

Xin chúc mừng, bạn vừa tạo ra 1 leak memory! Observable sẽ không bao giờ kết thúc, dispose sẽ không bao giờ được sử dụng.

Trong bài tiếp theo chúng ta sẽ học cách tạo 1 observable factories.

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

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

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

Machine learning là gì?

Machine learning là gì?

Bài viết được sự cho phép của tác giả Khiêm Lê

Machine learning là một chủ đề được nhắc đến rất nhiều trong thời gian trở lại đây bên cạnh trí tuệ nhân tạo, nó được ứng dụng cực kỳ nhiều ở thời điểm hiện tại trong hầu hết tất cả các lĩnh vực. Trong bài viết hôm nay, chúng ta sẽ cùng tìm hiểu xem machine learning là gì, các khái niệm cơ bản và vì sao nó lại được ứng dụng rỗng rãi như vậy?

Lưu ý trước khi đọc bài: mình mới vừa tìm hiểu về machine learning không lâu nên sai sót là điều không thể tránh khỏi. Các bạn đọc bài nếu thấy sai đừng quên góp ý dưới phần comment để mình hoàn thiện bài viết tốt hơn nha!

Machine learning là gì?

Tính đến thời điểm hiện tại, có rất nhiều định nghĩa về machine learning, nếu bạn nào từng google thì hẳn các bạn sẽ biết. Mình đã đọc và tổng hợp lại sau đó rút ra khái niệm như sau:

Machine learning (ML) hay máy học là một nhánh của trí tuệ nhân tạo (AI), nó là một lĩnh vực nghiên cứu cho phép máy tính có khả năng cải thiện chính bản thân chúng dựa trên dữ liệu mẫu (training data) hoặc dựa vào kinh nghiệm (những gì đã được học). Machine learning có thể tự dự đoán hoặc đưa ra quyết định mà không cần được lập trình cụ thể.

Bài toán machine learning thường được chia làm hai loại là dự đoán (prediction) và phân loại (classification). Các bài toán dự đoán như dự đoán giá nhà, giá xe… Các bài toán phân loại như nhận diện chữ viết tay, nhận diện đồ vật…

Tham khảo thêm các vị trí tuyển dụng Machine Learning lương cao cho bạn.

Machine learning Workflow

Machine learning workflow sẽ cho bạn thấy quy trình để làm việc với machine learning như thế nào. Hãy nhìn vào sơ đồ bên dưới:

Cụ thể từng bước trong machine learning workflow như sau như sau:

  1. Data collection – thu thập dữ liệu: để máy tính có thể học được bạn cần có một bộ dữ liệu (dataset), bạn có thể tự thu thập chúng hoặc lấy các bộ dữ liệu đã được công bố trước đó. Lưu ý là bạn phải thu thập từ nguồn chính thống, có như vậy dữ liệu mới chính xác và máy có thể học một cách đúng đắng và đạt hiệu quả cao hơn.
  2. Preprocessing – tiền xử lý: bước này dùng để chuẩn hóa dữ liệu, loại bỏ các thuộc tính không cần thiết, gán nhãn dữ liệu, mã hóa một số đặc trưng, trích xuất đặc trưng, rút gọn dữ liệu nhưng vẫn đảm bảo kết quả… Bước này tốn thời gian nhất tỉ lệ thuận với số lượng dữ liệu bạn có. Bước 1 và 2 thường chiếm hơn 70% tổng thời gian thực hiện.
  3. Training model – huấn luyện mô hình: bước này là bước bạn huấn luyện cho mô hình hay chính là cho nó học trên dữ liệu bạn đã thu thập và xử lý ở hai bước đầu.
  4. Evaluating model – đánh giá mô hình: sau khi đã huấn luyện mô hình xong, chúng ta cần dùng các độ đo để đánh giá mô hình, tùy vào từng độ đo khác nhau mà mô hình cũng được đánh giá tốt hay không khác nhau. Độ chính xác của mô hình đạt trên 80% được cho là tốt.
  5. Improve – cải thiện: sau khi đã đánh giá mô hình, các mô hình đạt độ chính xác không tốt thì cần được train lại, chúng ta sẽ lặp lại từ bước 3, cho đến khi đạt độ chính xác như kỳ vọng. Tổng thời gian của 3 bước cuối rơi vào khoảng 30% tổng thời gian thực hiện.
  9 hiểu lầm "ngớ ngẩn" về machine learning
  Chia sẻ cơ bản sử dụng machine learning để giải quyết bài toán.

Phân loại Machine learning

Có rất nhiều cách phân loại machine learning, thông thường thì machine learning sẽ được phân làm hai loại chính sau:

  • Supervised learning: học có giám sát
  • Unsupervised learning: học không giám sát

Ngoài ra, machine learning còn có thể phân làm các loại sau:

  • Semi-supervised learning: học bán giám sát
  • Deep learning: học sâu (về một vấn đề nào đó)
  • Reinforce learning: học củng cố/tăng cường

Mình sẽ chỉ đề cập đến cách phân loại phổ biến nhất là phân làm hai nhóm: học có giám sát và học không giám sát.

Supervised learning

Supervised learning là việc cho máy tính học trên dữ liệu đã được gán nhãn (label), hay nói cách khác, với mỗi đầu vào Xi, chúng ta sẽ có nhãn Yi tương ứng.

Unsupervised learning

Unsupervised learning là cho máy tính học trên dữ liệu mà không được gán nhãn, các thuật toán machine learning sẽ tìm ra sự tương quan dữ liệu, mô hình hóa dữ liệu hay chính là làm cho máy tính có kiến thức, hiểu về dữ liệu, từ đó chúng có thể phân loại các dữ liệu về sau thành các nhóm, lớp (clustering) giống nhau mà chúng đã được học hoặc giảm số chiều dữ liệu (dimension reduction).

Môt số khái niệm cơ bản

Dataset (còn gọi là data corpus hay data stock): là tập dữ liệu ở dạng nguyên thủy chưa qua xử lý mà bạn đã thu thập được ở bước data collection. Một dataset sẽ bao gồm nhiều data point.

Data point: là điểm dữ liệu, mỗi điểm dữ liệu biểu diễn cho một quan sát. Mỗi data point có nhiều đặc trưng hay thuộc tính khác nhau, được chia làm hai loại: dữ liệu số (numerical) và dữ liệu không phải số (ví dụ như chuỗi) (non-numerical/categorical). Data point được biểu diễn thành dòng tương ứng, mỗi dòng có thể có 1 hoặc nhiều dữ liệu (chính là các đặc trưng).

Training data và test data: dataset thường sẽ được chia làm 2 tập này, training data dùng để huấn luyện cho mô hình, test data dùng để dự đoán kết quả và đánh giá mô hình. Có bài toán người ta sẽ cho sẵn hai tập này thì bạn không cần phải chia nữa, đối với bài toán chỉ cho mỗi dataset thôi thì phải chia ra. Thường tỷ lệ giữa tập train và test sẽ là 8/2.

Features vector: là vector đặc trưng, mỗi vector này sẽ biểu diễn cho một điểm dữ liệu trong dataset. Mỗi vector có n chiều biểu diễn các đặc trưng của điểm dữ liệu, mỗi đặc trưng là một chiều và phải là dữ liệu số. Các mô hình chỉ có thể huấn luyện được từ các vector đặc trưng này, do đó dataset cần phải chuyển về dạng một tập các vector đặc trưng (features vectors).

Model: là các mô hình được dùng để training trên một training data theo thuật toán của mô hình đó. Sau đó mô hình có thể dự đoán hoặc đưa ra các quyết định dựa trên những gì chúng đã được học.

Ứng dụng của Machine learning

Machine learning được ứng dụng cực kỳ nhiều trong đời sống hiện nay trong mọi lĩnh vực:

  • Tài chính – ngân hàng
  • Sinh học
  • Nông nghiệp
  • Tìm kiếm, trích xuất thông tin
  • Tự động hóa
  • Robotics
  • Hóa học
  • Mạng máy tính
  • Khoa học vũ trụ
  • Quảng cáo
  • Xử lý ngôn ngữ tự nhiên
  • Thị giác máy tính

Và còn rất rất nhiều lĩnh vực mà machine learning có thể được áp dụng, machine learning tỏ ra cực kỳ hiệu quả, hơn hẳn con người trong cụ thể các lĩnh vực mà chúng được áp dụng.

Ví dụ đơn giản như dự báo thời tiết, người ta sẽ dùng các phép tính và những quan sát, ghi nhận về thời tiết trong quá khứ để dự báo về thời tiết của những ngày kế tiếp. Tuy nhiên sẽ thế nào nếu như có cực kỳ nhiều quan sát được thực hiện, có thể lên đến hàng triệu, hàng tỉ quan sát, lúc đó con người không thể nào thực hiện được việc tính toán trên dữ liệu lớn như vậy. Hơn nữa, việc tính toán với dữ liệu lớn như vậy có thể gặp sai sót và dẫn đến kết quả dự đoán bị sai.

Khi này, việc áp dụng machine learning vào để cho máy tính học các quan sát được ghi nhận trong quá khứ, chúng có thể dự đoán được thời tiết trong tương lai với độ chính xác cao hơn rất nhiều so với con người dự đoán.

Chính vì sự phổ biến và hiệu quả của machine learning, việc bạn biết và học về machine learning chắc chắn là một lợi thế lớn trong thời đại công nghệ 4.0 như ngày nay.

Tổng kết

Vậy là trong bài này, mình đã cùng các bạn tìm hiểu qua về machine learning là gì, các khái niệm cơ bản và ứng dụng của nó. Nếu như bạn thấy bài viết này hay hoặc có đóng góp về bài viết, đừng quên bình luận phía bên dưới để giúp mình hoàn thiện bài viết tốt hơn nha.

Cảm ơn các bạn đã theo dõi bài viết!

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

Xem thêm IT Jobs for Developer hấp dẫn trên TopDev

Thử làm một “lập trình viên Odoo”

Thử làm một

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

Odoo là gì?

Ố đù tự mô tả về mình trên GitHub:

Odoo is a suite of web based open source business apps. The main Odoo Apps include an Open Source CRM, Website Builder, eCommerce, Warehouse Management, Project Management, Billing & Accounting, Point of Sale, Human Resources, Marketing, Manufacturing, Purchase Management, … Odoo Apps can be used as stand-alone applications, but they also integrate seamlessly so you get a full-featured Open Source ERP when you install several Apps.

Nó là một bộ các web app phục vụ các công việc trong kinh doanh như quản lý quan hệ khách hàng, quản lý dự án, tính tiền/kế toán, tuyển dụng… đầy đủ đến mức nó là một giải pháp “ERP” cho doanh nghiệp. Odoo là tên mới từ bản 8.0 (giờ đang là 10.0) của phần mềm OpenERP.

  Todo App ASP.NET MVC x Entity Framework
  10 nguyên tắc lập trình nền tảng mà lập trình viên nào cũng cần biết

Đó là nhìn từ phía người dùng. Còn về phía lập trình viên, Odoo là gì?

Ứng tuyển ngay các vị trí Odoo tuyển dụng lương cao trên TopDev

Kiến trúc

Odoo sử dụng kiến trúc server – client.

Mỗi chương trình (webapp), được đóng thành 1 python module (thư mục với file __init__.py), và nằm trong thư mục addons https://github.com/odoo/odoo/tree/10.0/addons

Vài phút làm lập trình viên Odoo

Lấy code về

$ git clone https://github.com/odoo/odoo.git
Cloning into 'odoo'...
remote: Counting objects: 1999445, done.
remote: Compressing objects: 100% (546/546), done.
Receiving objects:  84% (1679534/1999445), 1.47 GiB | 1.33 MiB/s
Receiving objects:  84% (1691261/1999445), 1.47 GiB | 1.27 MiB/s
remote: Total 1999445 (delta 208), reused 258 (delta 105), pack-reused 1998777
Receiving objects: 100% (1999445/1999445), 1.67 GiB | 2.29 MiB/s, done.
Resolving deltas: 100% (1660073/1660073), done.
Checking connectivity... done.
Checking out files: 100% (21097/21097), done.

Yeah, 1.67 GB

Nếu tải sourcecode bằng file zip (không có git)

$ du -h 10.0.zip
121M    10.0.zip

Giải nén file zip rồi cài.

Code Odoo không tuân theo chuẩn PEP8 nhưng khá sạch sẽ và dễ đọc. Tài liệu cho developer đầy đủ, dễ xem. http://www.odoo.com/documentation/10.0/index.html

Đứng ở góc độ của lập trình viên, việc phát triển một “module/addon” cho Odoo không có gì quá khác biệt hay cao siêu so với viết một web app bằng bất cứ framework nào (Django, Flask…), ngoài chuyện clone 1.6GB git repo.

Cài đặt và chạy thử

Code Python cài từ source có một số thư viện yêu cầu lập trình viên phải cài thêm các thư viện C (bằng apt trên Ubuntu):

  • Yêu cầu chung: python-dev
  • lxml: libxml2-dev libxslt1-dev
  • python-ldap: libsasl2-dev libldap2-dev libssl-dev
  • psycopg2: libpq-dev

Phải cài npm để cài less, xem chi tiết tại https://www.odoo.com/documentation/10.0/setup/install.html#setup-install-source

Tạo virtualenv Python2 (Odoo hỗ trợ Python 2.7+, ko hỗ trợ 3), cài các requirements:

$ pip install -r requirements.txt
...

Successfully installed Babel-2.3.4 Jinja2-2.8 Mako-1.0.4 MarkupSafe-0.23 Pillow-3.4.1 PyYAML-3.12 Python-Chart-1.39 Werkzeug-0.11.11 XlsxWriter-0.9.3 beautifulsoup4-4.6.0 decorator-4.0.10 docutils-0.12 ebaysdk-2.1.4 feedparser-5.2.1 funcsigs-1.0.2 gevent-1.1.2 greenlet-0.4.10 jcconv-0.2.3 lxml-3.5.0 mock-2.0.0 ofxparse-0.16 passlib-1.6.5 pbr-3.1.1 psutil-4.3.1 psycogreen-1.0 psycopg2-2.7.1 pyPdf-1.13 pydot-1.2.3 pyparsing-2.1.10 pyserial-3.1.1 python-dateutil-2.5.3 python-ldap-2.4.27 python-openid-2.2.5 python-stdnum-1.6 pytz-2016.7 pyusb-1.0.0 qrcode-5.3 reportlab-3.3.0 requests-2.11.1 six-1.10.0 suds-jurko-0.6 vatnumber-1.2 vobject-0.9.3 xlrd-1.0.0 xlwt-1.1.2

Mặc dù dùng qweb template engine, Odoo vẫn có vài chỗ dùng jinja2 hay Mako template engine:

[2] although it uses a few others, either for historical reasons or because they remain better fits for the use case. Odoo 9.0 still depends on Jinja and Mako.

Sau khi cài

Thử làm một "lập trình viên Odoo"

Giao diện quản lý dự án

Thử làm một "lập trình viên Odoo"

Cảm nhận chung là Odoo vẫn chậm như thời OpenERP, khá ngốn RAM, 180MB cho process Python chạy Odoo, chưa làm gì cả + một đống process chạy postgres.

# ps xau | grep odo[o]
root     26287  0.0  0.0  54104  3640 pts/1    S    11:27   0:00 su odoo
odoo     26288  0.0  0.0  24468  5524 pts/1    S    11:27   0:00 bash
odoo     26766  2.3  2.2 2387728 180068 pts/1  Sl+  11:32   2:16 python ./odoo-bin
postgres 26779  0.0  0.1 303684 12532 ?        Ss   11:33   0:00 postgres: odoo postgres [local] idle
postgres 26796  0.2  0.6 316460 56828 ?        Ss   11:33   0:15 postgres: odoo db1 [local] idle
postgres 26813  0.0  0.5 306484 41576 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26823  0.0  0.5 307428 45272 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26836  0.6  0.9 323972 73628 ?        Ss   11:34   0:37 postgres: odoo db1 [local] idle
postgres 26841  0.0  0.5 306992 42800 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26847  0.0  0.5 307052 41240 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26848  0.0  0.5 306232 41784 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26849  0.0  0.5 306536 41104 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26850  0.0  0.5 306976 43236 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26851  0.0  0.5 306528 44344 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26852  0.0  0.5 306272 41192 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle
postgres 26853  0.0  0.4 306608 39024 ?        Ss   11:34   0:00 postgres: odoo db1 [local] idle

Làm lập trình viên Odoo

Khi vận hành trang tổng hợp việc Python của PyMi, những tin tuyển lập trình viên Odoo hiện lên hàng ngày, lặp đi lặp lại, với mức lương phổ biến trong khoảng 6-10 triệu.

Các nhà tuyển dụng thì lại bắt buộc lập trình viên phải có sẵn kinh nghiệm với Odoo… NOOOOOO!

Chẳng có lập trình viên web Python nào đầu tư vào 1 framework không dùng ở đâu ngoài để phát triển chính Odoo module/addon, họ học Django, Flask. Một lập trình viên Django hay Flask có thể viết Odoo webapp chỉ sau vài tiếng chuyển đổi những kiến thức tương tự sang những thư viện của Odoo framework.

Tại sao anh đòi hỏi thứ không ai có, mà lại trả lương thấp?

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

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

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

JavaScript có thể làm được nhiều hơn bạn nghĩ!

làm gì với javascript
JavaScript có thể làm được nhiều hơn bạn nghĩ!

Tác giả: Abiola Farounbi

Theo như kết quả nghiên cứu của Stack Overflow trong năm 2020, JavaScript là ngôn ngữ lập trình phổ biến nhất trên thế giới, với hơn 63% các nhà phát triển đã và đang sử dụng nó. JavaScript có kho lưu trữ gói mã nguồn mở lớn nhất trên thế giới (npm) và cũng có nhiều khung và thư viện khác nhau được xây dựng cùng với nó. JavaScript rất dễ bắt đầu vì nó không yêu cầu bất kỳ cài đặt nào để bắt đầu coding.

làm gì với javascript
JavaScript có thể làm nhiều việc hơn so với những gì bạn biết

Phát triển Front-end Web

Front-end web là một hình thức phát triển giao diện người dùng liên quan mà người dùng có thể xem và tương tác được. Có 3 ngôn ngữ chính hiện nay có thể dùng để phát triển front-end: HTML, CSS và JavaScript.

HTML (Ngôn ngữ đánh dấu siêu văn bản) liên quan đến cấu trúc và nội dung của trang web, CSS (Trang tính kiểu xếp tầng) xử lý kiểu dáng.

Và cuối cùng, JavaScript làm cho trang web mang các hiệu ứng động, dễ nhìn hơn. Và điều này có thể được thực hiện theo nhiều cách khác nhau, chẳng hạn như:

Thuyết trình

Bạn có thể tạo băng chuyền và thanh trượt trên trang web một cách dễ dàng bằng cách sử dụng một số thư viện JavaScript như Reveal JS, Swiper JSOwl JS

Với các thư viện này, bạn có thể tùy chỉnh cách trình bày trang web của mình một cách nhanh chóng và không quá phiền phức.

  Sử dụng thuật toán quay lui giải bài toán phân tích số bằng JavaScript

Hình ảnh động

Một trong những cách bạn có thể làm cho trang web của mình trở nên sinh động và hấp dẫn hơn là sử dụng hình ảnh động. Bạn có thể sử dụng chúng trên một trang web theo nhiều cách khác nhau, chẳng hạn như thông qua các chuyển động, sự biến đổi của các đối tượng và rất nhiều điều tuyệt vời khác.

Có một số thư viện ảnh gif để bạn lựa chọn, chẳng hạn như Anime JS, Greensock JS, Mo JSAnimate On Scroll. Đây là tất cả các thư viện được xây dựng bằng ngôn ngữ JavaScript giúp tạo hoạt ảnh của bạn dễ dàng hơn bằng cách sử dụng các khối mã nhỏ hơn.

  10 câu hỏi javascript để nâng cao trình độ

Phát triển Back-end Web

Phát triển back-end liên quan đến phần phía sau của trang web mà người dùng không tương tác trực quan. Đây còn được gọi là phát triển ở phía máy chủ. Phát triển back-end liên quan đến việc tạo cơ sở dữ liệu, API, máy chủ tệp, dịch vụ đám mây, v.v.

Và với việc tạo ra Node.js, một công cụ thời gian chạy JavaScript, giờ đây bạn cũng có thể sử dụng JavaScript để phát triển web back-end. Các khung JavaScript khác nhau đã được xây dựng để đơn giản hóa quá trình phát triển web back-end. Một số trong số đó bao gồm:

  • Express Js: Express là một Web Application framework nổi tiếng nhất dựa trên Node.js. Nó chủ yếu được sử dụng để phát triển Web Applications và API REST.
  • Fastify: Đây là một Server-Side Web Framework tối giản, tập trung nhiều vào trải nghiệm của nhà phát triển và hiệu suất ứng dụng.
  • Koa: Đây là một framework trung gian hiện đại và mạnh mẽ cho các Web Applications và APIs.

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

coding với javascript
JavaScript hỗ trợ đa dạng các chức năng

Phát triển game

Game là một trong những dự án thú vị nhất mà bạn có thể tạo, vì cả bạn và người dùng cuối đều có thể tận hưởng chúng. Có nhiều cách khác nhau để sáng tạo game mới với ngôn ngữ JavaScript, tùy thuộc vào độ phức tạp của trò chơi.

Bạn có thể xây dựng các trò chơi 2D đơn giản từ đầu bằng HTML, CSS và JavaScript vani. Tham khảo thêm nguồn chia sẻ về vấn đề này: Learn JavaScript by building 7 games by Ania Kubow

Để xây dựng các game có thiết kế phức tạp, cũng như các trò chơi mang tính hiệu quả hơn và nhanh hơn, bạn có thể sử dụng công cụ trò chơi JavaScript để làm cho quá trình này dễ dàng hơn. Một số engines này là Phaser Js, Blyon JsLime Js có thể giúp bạn làm việc dễ dàng hơn.

  9 lỗi JavaScript các lập trình viên hay gặp

Phát triển Mobile App

Phát triển ứng dụng dành cho thiết bị di động đề cập đến quá trình viết phần mềm hoạt động trên thiết bị di động. Nó liên quan đến việc phát triển các ứng dụng có thể được sử dụng trên thiết bị di động.

Bạn có thể sử dụng JavaScript để phát triển các mobile app. Các khung và thư viện Javascript khác nhau đã được xây dựng để tạo các ứng dụng gốc, đa nền tảng và kết hợp bằng JavaScript. Một số trong số đó là:

  • React Native: React Native là một framework mã nguồn mở có thể được sử dụng để xây dựng các cross-platform native apps – ứng dụng gốc đa nền tảng. React Native sử dụng phong cách lập trình khai báo và các thành phần có thể sử dụng lại cho giao diện người dùng.
  • NativeScript: NativeScript là một trong những framework đa nền tảng nổi tiếng nhất giúp bạn phát triển các mobile app cho các nền tảng Android và iOS. Vì nó là một khuôn khổ mã nguồn mở, các nhà phát triển có thể điều chỉnh giao diện người dùng cho nhiều màn hình và thiết bị, đồng thời cũng sử dụng các biến phụ thuộc khác nhau.
  • Ionic: Ionic là một JavaScript framework phổ biến khác để xây dựng các ứng dụng kết hợp. Đối với các nhà phát triển quen thuộc với công nghệ web và phát triển ứng dụng web, việc hiểu cấu trúc của một ứng dụng Ionic rất đơn giản.

Việc chọn JavaScript framework phù hợp cho dự án của bạn phụ thuộc vào ứng dụng bạn đang xây dựng và cũng như nền tảng mà nó dành cho. Vì vậy, hãy chắc chắn chọn một cái dựa trên trường hợp sử dụng của bạn nếu bạn có thể.

JavaScript là một ngôn ngữ đa dụng và có thể được ứng dụng trong nhiều lĩnh vực công nghệ khác nhau. Cá nhân tôi rất đề cao nó và thật sự khuyên bạn nên học JavaScript như một ngôn ngữ lập trình nếu bạn quan tâm đến bất kỳ lĩnh vực nào mà tôi đã chia sẻ ở trên.

Phỏng dịch dựa trên bài viết gốc được đăng tải tại freecodecamp.org

Tìm việc làm IT lương cao trên TopDev ngay!