Home Blog Page 57

Giới thiệu Widgetbook – Storybook dành cho Flutter

Giới thiệu Widgetbook

Bài viết được sự cho phép của tác giả Phạm Minh Khoa

Như tiêu đề, Widgetbook là 1 package giúp tạo Storybook dành cho Flutter; nó giúp developers thiết lập danh mục các widgets của họ, thử nghiệm 1 cách nhanh chóng trên các thiết bị và themes; đồng thời có thể dễ dàng chia sẻ cho designers và khách hàng.

Use cases cho Widgetbook

  • Xây dựng các widgets 1 cách độc lập và test chúng 1 cách trực quan

Widgetbook cung cấp 1 môi trường để xây dựng các UIs 1 cách độc lập. Chúng cho phép bạn có thể phát triển các widgets mà không bị ảnh hưởng từ các phụ thuộc thành phần khác của màn hình. Bạn có thể nhanh chóng hiển thị UIs trên các thiết bị giả lập khác nhau, giúp bạn có thể kiểm tra (test) và phát triển các lỗi giao diện.

  Cài đặt và sử dụng Storybook cho ReactJS
  Giới thiệu về StoryBook cho dự án FrontEnd
Dễ dàng phát triển ra lỗi khi text quá dài
Như trường hợp này thì lỗi xảy ra với dark mode
  • Có 1 cái nhìn tổng quan về tất cả các widgets của bạn

Khi projects của bạn càng ngày càng nhiều widgets được tạo ra, thì việc có 1 quyển từ điển để dễ dàng tìm kiếm, tra cứu cách sử dụng của những widgets sẵn có trong projects là 1 điều hết sức cần thiết. Đây cũng là ý nghĩa của việc tạo ra Storybook.

Tìm ngay việc làm ReacJS HOT tại TopDev!

  • Nâng cao khả năng hợp tác với designer, PO và khách hàng

Widgetbook cung cấp services giúp bạn có thể đẩy storybook widgets và màn hình của bạn lên host giúp khách hàng và các bên liên quan có thể dễ dàng review trên các thiết bị và themes khác nhau 1 cách dễ dàng; từ đó giúp giảm bớt tối đa thời gian họp và chỉnh sửa cho phần UIs trong dự án.

Cách cài đặt và sử dụng Widgetbook

Link package: https://pub.dev/packages/widgetbook

  • Thêm dependency vào pubspec.yaml
# pubspec.yaml
dev_dependencies:
  widgetbook:
  • Cấu trúc thư mục
example_app
+ lib
+--- main.dart
+ widgetbook
+--- main.dart
+--- widgetbook.dart

File widgetbook/widgetbook.dart chứa khai báo Widgetbook

class HotReload extends StatelessWidget {
  const HotReload({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Widgetbook(...);
  }
}

File widgetbook/main.dart khai báo hàm main để chạy app

void main() {
  runApp(HotReload());
}
  • Ví dụ sử dụng
class HotReload extends StatelessWidget {
  const HotReload({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Widgetbook(
      categories: [
        WidgetbookCategory(
          name: 'widgets',
          widgets: [
            WidgetbookWidget(
              name: '$CustomWidget',
              useCases: [
                WidgetbookUseCase(
                  name: 'Default',
                  builder: (context) => CustomWidget(),
                ),
              ],
            ),
          ],
          folders: [
            WidgetbookFolder(
              name: 'Texts',
              widgets: [
                WidgetbookWidget(
                  name: 'Normal Text',
                  useCases: [
                    WidgetbookUseCase(
                      name: 'Default',
                      builder: (context) => Text(
                        'The brown fox ...',
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ],
        ),
      ],
      appInfo: AppInfo(
        name: 'Widgetbook Example',
      ),
    );
  }
}

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

Theo dõi những bài viết mới của TopDev nhé:

Sử dụng phương thức flatMap() của đối tượng Stream trong Java

phương thức flatMap() của đối tượng Stream trong Java

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

Khi làm việc với đối tượng Stream trong Java, đôi khi chúng ta sẽ có những đối tượng Stream của những đối tượng List, Set hay là Array. Ví dụ như:

List<String> students1 = new ArrayList<>();
students1.add("Khanh");

List<String> students2 = new ArrayList<>();
students2.add("Thanh");
students2.add("Dung");

List<List<String>> students = Arrays.asList(students1, students2);

Stream<List<String>> stream = students.stream();

Ở đây, chúng ta có đối tượng List chứa những đối tượng List của những đối tượng String và khi convert đối tượng này qua đối tượng Stream, chúng ta có đối tượng Stream chứa đối tượng List của những đối tượng String. 

  Java Stream – Collectors và Statistics

Khi đó, nếu chúng ta cần thao tác trên đối tượng Stream này ví dụ như filter chẳng hạn thì chúng ta không thể làm được. Ví dụ như:

Sử dụng phương thức flatMap() của đối tượng Stream trong Java

Xem thêm nhiều việc làm Java hấp dẫn trên TopDev

Để giải quyết vấn đề này, chúng ta có thể sử dụng phương thức flatMap() trong đối tượng Stream trước khi chúng ta cần thao tác điều gì đó trên đối tượng Stream. Sử dụng phương thức flatMap() chúng ta có thể chuyển đổi đối tượng Stream của những đối tượng List, Set or Array thành đối tượng Stream của những đối tượng đơn giản hơn.

Ví dụ như:

  Tìm hiểu cơ chế Lazy Evaluation của Stream trong Java 8

Bây giờ, chúng ta có thể sử dụng phương thức flapMap() để giải quyết vấn đề trên:

Sử dụng phương thức flatMap() của đối tượng Stream trong Java

Tiềm năng ứng dụng thực tế của blockchain & Web3

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

Mấy nay nghe báo chí ca ngợi về blockchain & Web3 quá nên mình quyết định bước chân vào lĩnh vực này để tìm hiểu coi nó có ứng dụng thực tế gì không. Sau một tháng đọc tài liệu và viết code thử, mình nghĩ là đã tìm thấy câu trả lời.

Mình tìm hiểu về blockchain & Web3 với tâm thế của một người làm kĩ thuật, tức là mình không chỉ đọc khơi khơi. Mình muốn lập trình, làm ra được một ứng dụng cụ thể từ blockchain. Trong số các hệ thống blockchain, mình chọn Solana để nghiên cứu. Mình chọn nó là vì:

Nó cho phép lập trình bằng ngôn ngữ Rust. Mình ưu tiên Rust không chỉ vì lý do cảm tính (yêu thích) mà còn vì lý do thực dụng: Đầu tư vào Rust để sau khi làm về blockchain, mình có thể sử dụng Rust để làm việc cho các mảng khác (web, hệ thống nhúng v.v…). Nếu mình theo Ethereum thì phải học ngôn ngữ Solidity, nhưng Solidity chỉ có giá trị với smart contract. Rời blockchain ra thì chẳng dùng Solidity được vào việc gì khác, phí thời gian học tập.

Solana có tốc độ xử lý giao dịch nhanh. Theo mình, muốn có ứng dụng thực tế thì phải nhanh. Tương tự như bạn vô một website mà tải chậm thì lần sau bạn chẳng muốn ghé lại nữa.

  Web3 techstack - Hành trang cho anh em developer

Trong một tháng đấy mình vừa đọc tài liệu kĩ thuật, vừa tập tành viết code. Việc viết code không xuôi chèo mát mái tí nào vì đa số các tài liệu hướng dẫn bị lạc hậu hơn phiên bản phần mềm, không làm theo được. Mò mẫm tới lui thì cũng viết ra được một vài ứng dụng chạy được:

code web3

Mình cũng bỏ công nghiên cứu thực sự, đến khi đi ngủ cũng ráng đọc thêm về nó, và đêm qua thì lần mò tới mục này: Developing with Rust – Restriction

tiềm năng web3

Một điểm rất quan trọng là ứng dụng trên chain của Solana không thể dùng std::net, tức là không thể tạo socket và sử dụng các giao thức mạng, trao đổi thông tin qua mạng với các máy khác.

Xem thêm các việc làm JavaScript lương cao trên TopDev

Để thấy việc truyền nhận thông tin qua mạng quan trọng thế nào, lấy ví dụ về hệ thống kiểm soát, điều khiển trang trại của AgriConnect:

  • Hệ thống có các nút cảm biến. Các thiết bị này đo nhiệt độ, độ ẩm rồi gửi dữ liệu về một máy điều khiển trung tâm. Việc này đòi hỏi có mạng.
  • Máy điều khiển trung tâm lưu các dữ liệu vào hệ thống database (PostgreSQL). Việc trao đổi với hệ thống database cũng thông qua giao thức mạng.
  • Người quản lý trang trại muốn xem diễn biến nhiệt độ, độ ẩm thì dùng trình duyệt (trên điện thoại, laptop) truy cập vào website của máy điều khiển trung tâm. Việc tương tác giữa trình duyệt và website cũng tiến hành qua mạng.
  • Người quản lý trang trại thiết lập lịch tưới trên website. Lịch tưới này cũng được lưu vào database. Các việc này cũng tiến hành qua mạng.
  • Máy điều khiển trung tâm căn cứ vào số liệu nhiệt độ, độ ẩm thu được, so sánh với lịch tưới đã được cài đặt, sẽ ra lệnh tắt, mở bơm tưới. Tín hiệu điều khiển này được gửi qua mạng đến máy bơm đặt ở trang trại.
  Xu hướng phát triển của IoT hiện nay

Bởi vậy, ứng dụng blockchain, Web3 mà không sử dụng được mạng thì coi như cụt tay. Nói “blockchain, web3 là tương lai” thì nổ quá. Mà hạn chế này cũng không phải của riêng Solana. Có vẻ bản chất của blockchain khiến phải có hạn chế này, vì Ethereum cũng bị như thế.

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

Xem thêm:

Cài đặt transaction in memory cho Java

Cài đặt transaction in memory cho Java

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

Khi xây dựng hệ thống backend chúng ta thường xuyên phải làm việc với transaction – đây là một khái niệm rất quen thuộc với các lập trình viên backend. Việc nắm bắt và sử dụng thành thạo các loại này là việc cần thiêt để xây dựng một hệ thống backend tốt.

Tuy nhiên trong nhiều trường hợp database chúng ta sử dụng lại không hỗ trợ transaction hoặc việc insert vào các loại cơ sở dữ liệu quan hệ được xử lý bởi các hệ thống acsync điều này khiến chúng ta phải xử lý các transaction trên logic trong application của mình.

Những hệ thống trước đây tôi xây dựng đều phải xử lý điều này và sau khi tìm được một cách hay ho có thể sử dụng lại thì tôi quết định viết bài chia sẻ cho mọi người.

  Cách sử dụng Transaction trong SQL hiệu quả

  Transaction Processing – Everything must know

Ta sẽ chú ý ví dụ lưu các sản phẩm khách hàng mua thành công trên RAM sau:

import blog.common.transaction.element.TxnHashMap;

import java.util.ArrayList;
import java.util.List;


public class TestTransaction {
    private TxnHashMap<String, List<String>> userData;

    public TestTransaction() {
        this.userData = new TxnHashMap<>();
    }

    private void buySuccess(String userName, String productName) {
        if (!userData.contain(userName)) {
            userData.put(userName, new ArrayList<>());
        }
        userData.get(userName).add(productName);
    }

    private void buyFail() {
        throw new RuntimeException(" something is error");
    }

    public TxnHashMap<String, List<String>> getUserData() {
        return userData;
    }

    public void setUserData(TxnHashMap<String, List<String>> userData) {
        this.userData = userData;
    }

    public static void main(String[] args) {

        TestTransaction test = new TestTransaction();

        TxnManager manager = new TxnManager();

        manager.executeTransaction(() -> {
            test.buySuccess("demtv","iphone");
            test.buySuccess("demtv","ipad");
            test.buySuccess("maitv","ipad");
            manager.executeTransaction(()->{
                test.buySuccess("maitv","ipad");
                test.buyFail();
                return null;
            });
            return null;
        });

        manager.executeTransaction(() -> {
            test.buySuccess("maipm","iphone");
            test.buyFail();
            return null;
        });

        System.out.println(test.getUserData().getValue());
    }

}

Tại đây tôi sẽ lưu các sản phẩm khách hàng mua thành công vào một TxnHashMap là implement của một HashMap nhưng áp dụng cho transaction. Kết quả của lệnh in là

{maitv=[ipad], demtv=[iphone, ipad]}

Đừng bỏ lỡ việc làm Java hấp dẫn trên TopDev

Tại đây tôi có các class chính sau :

  • interface Txn : Class này đại diện cho một transaction trong hệ thống, đảm bảo các TxnElement được hoạt động. Chứa tất cả thay đổi của TxnElement trong một tracsaction để thực hiện commit hoặc rollback khi cần.
  • TxnManager : Class quản lý cách transaction của hệ thống hoạt động.
  • interface TxnElement : Muốn sử dụng được transaction thì cần phải implement lại interface này. Trong ví dụ trên là TxnHashMap.

Cài đặt chi tiết mọi người tham khảo trong project nhé.
Link github : github.com/trandem/blog/tree/main/common/sr..

Tại đây tôi chỉ implement TxnHashMap để sử dụng trên RAM của chương trình trong thực tế mọi người có thể tự impl các class khác nhau để phục vụ cho các mục đích khác nhau. Ví dụ thao tác với 1 key trên redis, gọi hệ thống ngoài,…

Nếu mọi người dùng được cách implement này thì cho mình 1 sao nhé.

Bài viết gốc được đăng tải tại demtv.hashnode.dev

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

Đừng bỏ lỡ việc làm IT mọi cấp độ tại TopDev

Cách dùng nhiều tên miền cho một trang web

cách dùng nhiều tên miền cho 1 trang web

Bài viết được sự cho phép của tác giả Lại Đình Cường

Dùng nhiều tên miền cho 1 trang web sẽ hữu ích trong một vài trường hợp và tùy vào nhu cầu của người dùng. Bài viết này mình sẽ hướng dẫn cho các bạn cách trỏ nhiều tên miền chạy chung cho 1 trang web. Việc này khác với chuyện trỏ nhiều tên miền chạy độc lập trên 1 hosting nha mọi người. Đầu tiên thì bạn phải trỏ IP hoặc nameserver về hosting đang sử dụng trước nhé.

cấu hình dns cho tên miền

Cách dùng nhiều tên miền cho 1 web

Tiếp đến, các bạn đăng nhập vào trong hosting, tùy vào mã nguồn sử dụng mà cách làm có thể hơi khác nhau. Trong bài viết này mình sẽ hướng dẫn cho các bạn cách làm trên hosting cPanel, DirectAdmin và Plesk.

  Hướng Dẫn Xây Dựng Trang Đăng Nhập Trong WordPress
  Chuyển hosting bao lâu thì mới cập nhật?

Tạo parked domain (domain alias) cho tên miền chính

Đối với hosting Plesk thì các bạn đăng nhập vào bảng điều khiển và nhấn vào nút + Add Domain Alias trong khu vực các nút chức năng phía trên tên miền để tạo parked domain.

them domain alias trên plesk

Đối với hosting cPanel thì các bạn đăng nhập vào bảng điều khiển và nhấn vào link Aliases trong khu vực chức năng Domains để tạo parked domain.

thêm domain aliases

Đối với hosting DirectAdmin thì các bạn vào bảng điều khiển và nhấn vào link Domain Pointers trong khu vực Advanced Features để tạo parked domain.

them-domain-alias-tren-directadmin-hosting

TOP việc làm WordPress có ngay tại TopDev! 

Cập nhật lại tập tin wp-config.php của WordPress

Tiếp theo, các bạn vào file manager của hosting hoặc vào admin dùng trình chỉnh sửa file hoặc dùng FTP client để thay đổi nội dung tập tin wp-config.php của WordPress thành như sau:

define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
Lưu ý: Nếu đã có sẵn dòng define WP_SITEURL và WP_HOME thì các bạn thay đổi lại giá trị, còn nếu chưa có thì các bạn thêm vào nhé.

Cập nhật tập tin .htaccess để tránh lỗi font, css và js

Bạn mở tập tin .htaccess lên và tìm xem có dòng dưới hay chưa, nếu chưa có thì thêm vào trước dòng # BEGIN WordPress:

<IfModule mod_headers.c>
 <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
 Header set Access-Control-Allow-Origin "*"
 </FilesMatch>
</IfModule>
# BEGIN WordPress

Cập nhật lại canonical url để không bị ảnh hưởng SEO

Bạn thêm đoạn code sau vào tập tin functions.php của giao diện, và cái này chỉ thực hiện đối với bạn nào đang sử dụng plugin Yoast SEO nhé. Nếu bạn đang dùng plugin khác để làm SEO WordPress thì gửi lại bình luận để mình cập nhật cho các bạn:

/**
 * Update canonical url to main url prevent lost SEO
 *
 * @param $canonical
 *
 * @return mixed
 */
function hocwp_theme_custom_wpseo_canonical_filter( $canonical ) {
 $canonical = str_replace( home_url(), 'maydothinghiem.com.vn', $canonical );

 return $canonical;
}

add_filter( 'wpseo_canonical', 'hocwp_theme_custom_wpseo_canonical_filter' );

Chú ý: Các bạn thay maydothinghiem.com.vn thành tên miền chính các bạn đang dùng nhé.

Tự động thay đổi đường link custom post type

Nếu các bạn đang sử dụng custom post type và có bỏ link tĩnh vào menu thì các bạn có thể sử dụng đoạn code sau:

function hocwp_theme_custom_wp_nav_menu_objects_filter( $items ) {
    if ( is_array( $items ) ) {
       foreach ( $items as $key => $item ) {
           if ( is_object( $item ) ) {
              if ( 'custom' == $item->object && 'custom' == $item->type ) {
                  $parse = parse_url( $url );
                              $parse = isset( $parse['query'] ) ? $parse['query'] : '';
                              parse_str( $parse, $params );
                 
                  $pt = $params['post_type'] ?? '';

                  if ( post_type_exists( $pt ) ) {
                     $item->url = get_post_type_archive_link( $pt );
                  }

                  $item->url = remove_query_arg( 'post_type', $item->url );

                  $items[ $key ] = $item;
             }
          }
       }
    }

    return $items;
}

add_filter( 'wp_nav_menu_objects', 'hocwp_theme_custom_wp_nav_menu_objects_filter' );

Kết luận

Như vậy là qua bài viết này mình đã hướng dẫn cho các bạn cách dùng nhiều tên miền cho cùng 1 web. Cụ thể hơn, mình đã hướng dẫn cho các bạn cách tạo parked domain hay còn gọi là domain alias cho hosting với từng ví dụ cụ thể. Hy vọng rằng bài viết này sẽ giúp ích được cho mọi người, hãy để lại bình luận và share bài viết này nếu bạn cảm thấy hữu ích nhé. Chúc bạn thành công.

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

Xem thêm:

Đừng bỏ lỡ việc làm IT hấp dẫn trên TopDev nhé!

Khi code bí thì phải làm sao? 5 kinh nghiệm siêu hay để giải quyết vấn đề

khi code bí phải làm gì

Bài viết được cho phép bởi tác giả Phạm Huy Hoàng

Với những bạn đang bắt đầu học lập trình hoặc vừa mới đi làm, đôi khi các bạn sẽ bị… bí, không biết code hoặc giải quyết vấn đề như thế nào (Thật ra mình đi làm lâu rồi nhiều khi cũng bị).

Cảm giác … không biết code như thế nào, không biết giải quyết vấn đề ra sao rất là khó chịu. Gặp nhiều bạn sẽ dễ nản, chán code, chán ngành.

Do vậy, hôm nay mình chia sẻ 5 kinh nghiệm hay ho trị bệnh … bí code, các bạn có thể áp dụng thử nhé! Theo kinh nghiệm của mình thì 96.69% các trường hợp đều áp dụng được và có hiệu quả nha!

1. Google vấn đề để xem người khác giải quyết ra sao

Nói thật, 99% những lỗi bạn gặp khi code, người khác đã gặp rồi, nên chỉ cần Google là sẽ tìm ra được cách giải.

Đa phần các bạn mới học code thường chưa biết nhiều keyword, nên không biết Google thế nào cho đúng. Đây là 1 số kinh nghiệm Google của mình:

  • Tập Google bằng tiếng Anh chứ đừng dùng tiếng Việt
  • Đọc message lỗi, copy message lỗi bỏ vào Google, nhớ bỏ tên biến/tên hàm/tên project ra
  • Ghi rõ ngôn ngữ/công nghệ để search cho dễ (vd “JS remove special character”, “Python connect MongoDB”)
  • Kết quả thường có trên Stackoverflow, hoặc 1 số thread Github

Bạn cũng đừng ngại hay nghĩ mình code dở vì phải Google cách giải 1 bài nào đó. Bản thân mấy ông senior đi làm lâu lâu vẫn Google xem cách làm nào tối ưu nhất, ít code nhất; hoặc quên code phải Google kiếm code để copy vào ấy.

Đừng bỏ lỡ việc làm FrontEnd hấp dẫn trên TopDev

tra cứu trên google
Mấy ông senior/team lead vẫn Google thường xuyên nha =))

2. Tách thành nhiều vấn đề nhỏ hơn cho dễ xử lý

Với các bạn bắt đầu làm đồ án, mới đi làm, các bạn sẽ bị khó khăn khi muốn làm 1 chức năng. Vì chức năng đó lớn quá, chưa có kinh nghiệm các bạn không biết bắt đầu từ đâu cả.

Cách giải quyết cũng khá đơn giản, chỉ cần tách vấn đề ra thành nhiều vấn đề nhỏ hơn là được. Ví dụ bạn muốn làm chức năng đăng nhập:

  • Đăng nhập phải có form để điền username, password. Vậy bạn phải design và code cái form cho người dùng điền 2 cái đó vào.
  • Đăng nhập phải check username, password đã có trong database chưa. Nếu chưa có thì sao. Bạn phải viết code back-end hoặc SQL để check cái này.
  • Làm sao để back-end nhận username, password nhận được từ phía người dùng? Phải viết code trong controller để đọc dữ liệu. Sau đó đưa chúng vào hàm check mật khẩu phía trên
  • Sau khi kiểm tra đúng mật khẩu thì làm gì? Code chức năng cần làm khi đúng mật khẩu (Login, đưa user vào session v…v)

Đấy, khi tách vấn đề thành nhiều vấn đề nhỏ hơn, bạn có thể dễ dàng code từng thứ rồi ghép chúng lại với nhau. Bản thân mình cũng hay dùng to-do list như hình dưới để code, code xong check là được.

Tách thành nhiều vấn đề nhỏ hơn cho dễ xử lý
Mình cũng hay tách chức năng lớn thành nhiều task nhỏ cho dễ xử lý (chữ hơi xấu hihi)

3. Thử giải quyết vấn đề dễ hơn trước

Nhiều khi, bạn gặp một vấn đề không quá lớn, nhưng lại hơi khó, không biết cách giải quyết ra sao.

Trong trường hợp này, hãy thử giải quyết vấn đề dễ hơn trước. Ví dụ, bài tập yêu cầu bạn tính tuổi trung bình của sinh viên trong trường.

Tuy nhiên, dữ liệu chỉ cho số báo danh, tên họ, ngày tháng năm sinh. Bạn có thể thử giải bài toán dễ hơn:

  • Giả sử ta có tuổi của toàn bộ sinh viên trong trường
  • Tuổi trung bình sẽ bằng tổng số tuổi chia cho số sinh viên
  • Vậy làm sao để có tuổi của sinh viên? Lấy năm hiện tại trừ cho năm sinh là ra.
  • Làm sao để có năm sinh? Dùng hàm nào đó để lấy số năm từ ngày tháng năm sinh trong dữ liệu là được.

Ta có thể suy ngược ra cách giải: Lấy năm hiện tại trừ đi năm sinh của từng sinh viên để có tuổi, sao đó cộng toàn bộ chia cho số sinh viên.

Các bạn thấy không? Chỉ cần thử giải bản dễ hơn, các bạn sẽ dần dần mò ra được cách giải thôi!

4. Đọc lại document, hỏi ý kiến đồng nghiệp

Đi làm, có lúc các bạn sẽ phải dùng framework do công ty/đối tác tự phát triển, mò Google không ra. Hoặc công ty có chuẩn/coding standard gì đó, bạn không biết code theo ra sao.

Lúc này, hãy chịu khó đọc lại kĩ document, coding guideline, code example để xem họ hướng dẫn code ra sao, dùng những hàm nào.

Nếu xui hơn … không có cả document hay unit test để đọc (vì team bị dí quá làm gì có thời gian viết), bạn có thể tranh thủ hỏi sếp, hỏi đồng nghiệp. Do họ đã có kinh nghiệm làm việc với dự án, biết những cách nên làm bạn sẽ đỡ tốn công mày mò nhiều.

Nhớ tìm hiểu kĩ trước khi hỏi, gom hết lại hỏi 1 lượt, chứ đừng hỏi lắt nhắt ảnh hưởng công việc người ta nhé!

hỏi ý kiến đồng nghiệp
Thà chai mặt hỏi đồng nghiệp, còn hơn mò mò code lung tung hỏng code nhé!

5. Đi uống, đi dạo đi ngủ (1 mình)

Trong khi làm việc, hẳn bạn đã từng trải qua cảm giác code hoài không được, chạy bị lỗi không biết tại sao, càng ngồi lâu càng bực mình mà không giải quyết được vấn đề.

Lúc này, cách hay nhất là bạn nên … đứng dậy, gác vấn đề qua một bên. Sau đó đi rót nước uống, làm một cốc cà phê, hoặc đi dạo vòng vòng trong công ty rồi quay lại.

Lúc này, bộ não của bạn sẽ được refresh lại, đôi khi bạn sẽ tự … bật ra cách giải, nhìn ra bạn đã sai chỗ nào! Hoặc có thể đi giải quyết vấn đề khác, sau đó đi ngủ 1 giấc, sáng hôm sau quay lại bỗng dưng não lại nghĩ ra cách giải quyết vấn đề cũ.

Nghe hơi vô lý đúng không nào? Không tin thì các bạn cứ thử xem sao nhé, nếu không hiệu quả cứ lên đây đòi tiền thằng Code Dạo.

đi dạo
Dắt gấu chó, lộn, dắt gấu và chó đi dạo sẽ giúp bạn refresh đầu óc, giải quyết vấn đề nha!

 

Tạm kết

Đấy, trong bài này, mình đã chia sẻ với các bạn những kinh nghiệm hay ho. Bản thân mình thấy cách 1 và cách 5 là hiệu quả nhất! Còn bạn thấy cách nào hay ho thì cứ chia sẻ trong mục comment nhé!

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

Xem thêm những bài viết liên quan dưới đây:

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

Java Serializable là gì? Serialization và Deserialization trong Java

Serialization và Deserialization trong Java

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

Khi lập trình với Java chắc hẳn bạn đã bắt gặp khái niệm serialize nhất là khi đọc ghi object ra file, mapping với cơ sở dữ liệu…

Java Serializable là gì?

Serialization trong Java là cơ chế chuyển đổi trạng thái của một đối tượng (giá trị các thuộc tính trong object) thành một chuỗi byte sao cho chuỗi byte này có thể chuyển đổi ngược lại thành một đối tượng.

Quá trình chuyển đổi chuỗi byte thành đối tượng gọi là deserialization.

Một object có thể serializable (có thể thực hiện Serialization) nếu class của nó thực hiện implements interface java.io.Serializable

  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java
  Java Developer là gì? Lộ trình để trở thành Java Developer

Tại sao cần Serialization?

Trong Java, khi trao đổi dữ liệu giữa các thành phần khác nhau (giữa các module cùng viết bằng Java) thì dữ liệu được thể hiện dưới dạng byte chứ không phải là đối tượng. Do đó ta cần có một cơ chế để hiểu các đối tượng được gửi và nhận.

Quá trình serilization hoàn toàn độc lập với platform (không phụ thuộc vào hệ điều hành) nên việc chuyển đổi giữa byte và object giữa các module được đảm bảo.

Java tuyển dụng lương cao, đãi ngộ tốt

Code ví dụ

Ví dụ mình có 2 module, một module thực hiện chuyển đối tượng Customer thành byte và ghi ra file .Một module thực hiện đọc byte từ file và chuyển ngược lại thành đối tượng Customer.

(Trong thực tế thì 2 module có thể trao đổi qua database, network chứ không phải qua file)

package stackjava.com.serializable.demo;

import java.io.Serializable;

public class Customer implements Serializable{

  private static final long serialVersionUID = 1L;

  private int id;
  private String name;
  private transient String address;

  @Override
  public String toString() {
    return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
  }

  // getter - setter

}
  • Đối tượng Customer sẽ gồm có 3 thuộc tính là id, name và address trong đó address được đánh dấu là transient tức là nó sẽ không được serialization.
  • private static final long serialVersionUID = 1L; để đảm bảo chắc chắn rằng đối tượng trước và sau khi serialization là một.
package stackjava.com.serializable.demo;

import java.io.*;

public class WriteObjectDemo {

  public static void main(String[] args) throws FileNotFoundException, IOException {

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("src/customer.dat")));
    Customer customer = new Customer();
    customer.setId(1);
    customer.setName("kai");
    customer.setAddress("ha noi");

    System.out.println("Customer before serialization:");
    System.out.println(customer);
    oos.writeObject(customer);
    oos.close();
  }
}

Method writeObject() sẽ kiểm tra đối tượng được ghi có phải là serializable không, sau đó sẽ chuyển thành byte và thực hiện khi.

Kết quả:

Customer before serialization:
Customer [id=1, name=kai, address=ha noi]

Java Serializable là gì? Serialization và Deserialization trong Java

Tiếp theo mình thực hiện đọc dữ liệu từ file và chuyển thành đối tượng Customer.

package stackjava.com.serializable.demo;

import java.io.*;

public class ReadObjectDemo {

  public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("src/customer.dat")));
    System.out.println("Customer after deserialization:");
    Customer customer = (Customer) ois.readObject();
    System.out.println(customer);
    ois.close();
  }
}

Method readObject() sẽ chuyển byte thành đối tượng.

Vì mình ghi ra file dạng đối tượng Customer nên sau khi readObject() mình sẽ ép thành kiểu đối tượng Customer (Nếu bạn khi ra file dạng Map, List thì lúc đọc các bạn phải ép đúng kiểu tương ứng.

Kết quả:

Customer after deserialization:
Customer [id=1, name=kai, address=null]

Trường address là transient nên sau khi deserialization sẽ không có dữ liệu.

Một số lưu ý về Serialization trong Java

  • Nếu class cha implement Serializable thì các class con không cần thực hiện implement Serializablenữa.
  • Các thuộc tính static và transient sẽ không được serialization.
  • Hàm khởi tạo (constructor) sẽ không được gọi khi một đối tượng được deserialization.
  • Khi thực hiện serialization một đối tượng thì tất cả các thuộc tính bên trong nó đều phải là serializable (áp dụng với các thuộc tính có kiểu đối tượng, ví dụ object Person có thuộc tính Address thì thuộc tính Address đó cũng phải implement Serializable nếu không sẽ bị lỗi java.io.NotSerializableException khi thực hiện serialization đối tượng person).

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

Xem thêm:

Tuyển dụng IT lương cao, đãi ngộ hấp dẫn. Ứng tuyển ngay!

Tổng hợp các khoản phụ cấp không phải đóng BHXH và thuế TNCN

phụ cấp không phải đóng BHXH và thuế TNCN
Bài viết được sự cho phép của hrvnacademy.com

Tiền phụ cấp chi trả cho người lao động được xác định cho các mục đích phụ cấp khác nhau. Do đó một số phụ cấp được tính vào đóng BHXH, tính Thuế TNCN. Các bạn lưu ý là trong bài học này, khi mình nhắc đến các khoản phụ cấp nào phải chịu Thuế TNCN và không chịu thuế TNCN của người lao động là khoản được chi trả bằng tiền vào lương. Tuy nhiên, công ty chỉ thu thuế TNCN khi tổng thu nhập của họ đạt ngưỡng chịu thuế, còn dưới thì mặc nhiên là không thu bạn nhé!

Chi tiết các khoản lương, thưởng, phụ cấp theo lương, khoản phúc lợi hỗ trợ khác mình có trích dẫn bên dưới để các bạn tiện tham khảo. Mình chỉ làm rõ thêm một số mục theo mình là quan trọng và bạn cần nắm thêm như sau:

Tiền ăn ca có đóng BHXH và Thuế TNCN không?

Về thuế TNCN

– Công ty tự tổ chức nấu ăn, mua suất ăn hoặc cấp phiếu ăn cho người lao động => Thì không tính vào thu nhập chịu thuế TNCN.

– Công ty không tổ chức bữa ăn giữa ca, ăn trưa mà chi tiền cho người lao động theo mức chi phù hợp với hướng dẫn của Bộ LĐTBXH tối đa cho khoản hỗ trợ ăn ca này là 730.000 đồng/người/tháng thì không tính thuế TNCN. Nếu chi vượt thì sẽ tính thuế trên phần vượt.

Căn cứ pháp lý: Điều 2 Thông tư số 111/2013/TT-BTC ngày 15/08/2013 của Bộ tài chính; Điều 22 Thông tư số 26/2016/TT-BLĐTBXH ngày 01/09/2016 của Bộ LĐTBXH.

  Lương Gross Net là gì? Cách tính lương đơn giản nhất

Về BHXH

Như trong bài học trước mình đã trích dẫn khá chi tiết, thì tiền hỗ trợ ăn ca sẽ không đóng BHXH. Nên một số công ty thường chia thu nhập thành khoản hỗ trợ ăn ca này khá cao để giảm mức đóng BHXH.

Mọi người cần lưu ý tính hợp lý của khoản phụ cấp này và phải có thể hiện trong Hợp đồng lao đồng, quy chế lương thưởng nhé! Đồng thời phải cân đối với chính sách thu thuế TNCN, chi phí hợp lý của doanh nghiệp.

Xem thêm việc làm Java hấp dẫn tại TopDev

Hỗ trợ đi lại, nhà ở, điện thoại có giới hạn là bao nhiêu?

Các khoản hỗ trợ đi lại, nhà ở, điện thoại là những khoản không phải đóng BHXH nhưng phải đóng thuế TNCN. Nhiều công ty đang lạm dụng điều này để giảm mức đóng BHXH của người lao động đến mức tối đa.

Và các khoản hỗ trợ đi lại, nhà ở, điện thoại…này phải đóng Thuế TNCN. Các bạn lưu ý ở đây là mình xét các khoản này được trả bằng tiền vào lương chứ không phải trả qua công ty thứ ba hay là công ty thực hiện thuê nhà, tự trả cước điện thoại cho nhân viên.

Với quy định của BHXH thì hiện tại chưa có mức trần tối đa cho khoản hỗ trợ đi lại, nhà ở, điện thoại này. Tuy nhiên, công ty cần cân đối mức hợp lý; Và cần có quy định cụ thể mức hỗ trợ này với từng chức danh trong quy chế lương thưởng công ty chứ không phải muốn phân bỗ bao nhiêu cũng được trên bảng lương thì sẽ bị coi là lách luật.

  Tìm hiểu hệ thống lương 3P

Thưởng tháng 13 có đóng BHXH và thuế TNCN không?

Tiền lương tháng đóng BHXH bắt buộc không bao gồm các khoản chế độ và phúc lợi khác, như tiền thưởng theo quy định tại Điều 103 Bộ luật lao động, cho nên khoản tiền thưởng tháng 13, thưởng Tết sẽ không đóng BHXH. Được quy định tại Điều 89 Luật BHXH 2014, Điều 17 Nghị định 115/2015/NĐ-CP và Điều 30 Thông tư 59/2015/TT-BLĐTBXH.

Theo Khoản 2 Điều 2 Thông tư 111/2013/TT-BTC quy định thu nhập của người lao động (NLĐ) từ tiền lương, tiền công là khoản thu nhập chịu thuế thu nhập cá nhân. Trong đó bao gồm các khoản thưởng bằng tiền hoặc không bằng tiền dưới mọi hình thức. Do đó, khoản thu nhập của NLĐ từ thưởng Tết là khoản thu nhập chịu thuế TNCN.

Khoản thưởng KPI có đóng BHXH và Thuế TNCN không?

Trong bài học này mình chỉ xem xét ở mức độ đơn giản để trả lời câu hỏi Khoản lương, thưởng KPI có đóng BHXH và Thuế TNCN không , chi tiết hơn mình sẽ có một bài phân tích sâu hơn bạn nhé! và tiền thưởng KPI có thể được trả hàng tháng hoặc quý tùy theo quy định của mỗi công ty.

Theo Điều 3 Thông tư 10/2020/TT-BLĐTBXH thì các khoản bổ sung xác định được mức tiền cụ thể cùng với mức lương thỏa thuận trong hợp đồng lao động và trả thường xuyên trong mỗi kỳ trả lương sẽ phải đóng BHXH. Tuy nhiên, khoản thưởng KPI lại không cố định và phụ thuộc vào kết quả hoàn thành công việc nên sẽ không phải đóng BHXH.

Lưu ý: Thưởng KPI phải có thang bảng đánh giá đi kèm, có tiêu chí và các chỉ số đo lường rõ ràng và số tiền KPI háng tháng không cố định bạn nhé!

Theo Khoản 2 Điều 3 Luật Thuế thu nhập cá nhân 2007, sửa đổi năm 2012 thì tiền lương, tiền công và các khoản có tính chất tiền lương, tiền công và các khoản phụ cấp, trợ cấp được tính là thu nhập chịu thuế TNCN của người lao động.

Phần lương theo KPI (hoặc thưởng KPI) được tính và chi trả theo hiệu quả công việc; Và không thuộc các khoản trợ cấp, phụ cấp được miễn thuế TNCN. Do đó, tiền lương KPI cũng sẽ được cộng vào tổng thu nhập chịu thuế để tính thuế . 

Trên đây mình đã cùng nhau tìm hiểu một số khoản tiền lương, phụ cấp nào phải đóng BHXH và thuế TNCN hay không. Hy vọng các bạn đã có cái nhìn bao quát hơn về vấn đề này. Nếu bạn có bất kỳ thắc mắc nào, vui lòng để lại comment bên dưới. Mình sẽ trả lời cho các bạn trong thời gian sớm nhất.

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


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

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

Tăng trưởng kinh doanh đa kênh Omnichannel – Bùng nổ doanh số 2023 cùng Haravan

kinh doanh đa kênh Omnichannel

Omnichannel là thuật ngữ khá quen thuộc trong lĩnh vực kinh doanh Online trên thế giới. Tuy nhiên, không phải ai cũng biết Omnichannel là gì? Lợi ích của Omnichannel mang đến cho doanh nghiệp ra sao? Làm sao để áp dụng Omnichannel hiệu quả? Cùng tìm hiểu về Giải pháp quản lý bán hàng đa kênh – Omnichannel.

——————————

“Kinh doanh online đa kênh Omnichannel’ giúp gì cho bạn?

Tìm hiểu Omnichannel là gì
Tìm hiểu Omnichannel là gì và lợi ích khi sử dụng

OmniChannel được biết đến là một mô hình kinh doanh bán lẻ tiềm năng, thu hút nhiều nhà kinh doanh/ doanh nghiệp đẩy mạnh triển khai trong những năm gần đây.

Omnichannel là giải pháp bán hàng đa kênh, quản lý tập trung các kênh bán hàng online và offline: website, sàn TMĐT, mạng xã hội, cửa hàng vào cùng một nền tảng. Ngoài hoạt động bán hàng truyền thống tại cửa hàng, kinh doanh online trên đa kênh trở thành một giải pháp tất yếu giúp nhà bán lẻ kinh doanh đa kênh hiệu quả, tối ưu và tăng trải nghiệm cho khách hàng, từ đó đem lại nguồn doanh thu, lợi nhuận tối ưu.

  1. Haravan – Giải pháp tăng trưởng kinh doanh online đa kênh cho mọi quy mô
Giải pháp Haravan quản lý bán hàng đa kênh
Giải pháp Haravan quản lý bán hàng đa kênh cho mọi nhà kinh doanh

Được thành lập từ năm 2014, Haravan là công ty công nghệ hàng đầu Việt Nam trong lĩnh vực cung cấp các giải pháp bán lẻ Omnichannel, Thương mại điện tử và Engagement Marketing cho doanh nghiệp và người kinh doanh tại Việt Nam.

Với nền tảng công nghệ tiên phong hỗ trợ nhà bán lẻ tăng trưởng và kinh doanh online dễ dàng, Haravan giúp tối đa hiệu quả kinh doanh, đồng thời tạo trải nghiệm cá nhân hóa cho khách hàng ở đa kênh Online và Offline. 

Quản lý bán hàng đa kênh hiệu quả bằng giải pháp công nghệ Haravan
Quản lý bán hàng đa kênh hiệu quả bằng giải pháp công nghệ Haravan

Ngoài hệ thống quản lý bán hàng trên đa kênh tinh gọn, Haravan còn mang đến cho các nhà bán lẻ/ doanh nghiệp các giải pháp bán hàng và marketing hiệu quả với đa dạng tính năng, tiện ích có sẵn trên hệ thống.

Giải pháp bán hàng đa kênh tin dùng bởi nhiều thương hiệu
Giải pháp bán hàng đa kênh tin dùng bởi nhiều thương hiệu

Nền tảng Haravan gồm trang quản trị tinh gọn, dễ sử dụng giúp nhà kinh doanh có thể vận hành và theo dõi mọi hoạt động bán hàng, đồng bộ dữ liệu trên đa kênh:

☑ Website Thương mại điện tử chuyên nghiệp

☑ Bán hàng trên mạng xã hội: Facebook, Instagram, Livestream, Zalo

☑ Kết nối bán hàng trên sàn Thương mại điện tử: Shopee, Lazada, Tiki, TikTok Shop

☑ Quản lý bán hàng trực tiếp tại cửa hàng POS

☑ Giải pháp quảng cáo trên Google, Facebook và TikTok 

Cùng các tiện ích và tính năng hỗ trợ nhà bán hàng theo dõi hiệu suất kinh doanh, và tối ưu, tăng trải nghiệm về giao hàng, thanh toán:

☑ Báo cáo, thống kê hiệu quả bán hàng toàn diện

☑ Quản lý thu chi, công nợ nhà cung cấp 

☑ Kết nối sẵn các nhà vận chuyển và cổng thanh toán online phổ biến

Haravan nhận giải thưởng Best Solution Awards 2021
Haravan nhận giải thưởng Best Solution Awards 2021

Năm 2021, Haravan vinh dự nhận giải thưởng Best Solution Awards 2021 với giải pháp Haravan Omnichannel. Đây là cột mốc đánh dấu cho sự thành công của Haravan cũng như sự công nhận của các chuyên gia trong ngành và sự tin tưởng của các doanh nghiệp bán lẻ với các giải pháp kinh doanh online đa kênh của Haravan.

Đến nay, Haravan đã được hơn 50.000 người kinh doanh tin dùng làm nền tảng để tăng trưởng trong thời đại kinh tế số, trong đó có các thương hiệu nổi bật trong nước và quốc tế như: Nestle, Dell, L’Oréal,  AEON, Maison, Vinamilk, Thiên Long, Biti’s, The Face Shop, Juno, The Coffee House,… Haravan cũng là đối tác công nghệ chiến lược của Google và Meta (Facebook) trong việc cung cấp giải pháp công nghệ kinh doanh & Marketing tại Việt Nam.

—————-

Tìm hiểu thêm về Haravan tại đây: https://www.haravan.com

Xem thêm:

Nginx và Apache là gì? So sánh Nginx và Apache

Nginx và Apache

Bài viết được sự cho phép của tác giả Lê Chí Dũng

I. Giới thiệu

1. Apache là gì?

Apache HTTP Server, hay thường được gọi là Apache là phần mềm web server được sử dụng nhiều nhất trên thế giới. Ban đầu được dựa trên NCSA HTTPd server. Apache bắt đầu được phát triển vào khoảng đầu năm 1995 khi NCSA bị đình trệ và đóng 1 vai trò quan trọng trong sự phát triển ban đầu của World Wide Web, nhanh chóng vượt qua NCSA HTTPd như HTTP server ưu thế và trở nên phổ biến nhất kể từ tháng 4/1996. Vào năm 2009, nó trở thành phần mềm web server đầu tiên phục vụ hơn 100 triệu website.

apache là gì

Apache được phát triển và duy trì bởi 1 cộng đồng mở của các nhà phát triển dưới sự bảo trợ của Apache Software Foundation. Thường được sử dụng trên hệ thống giống Unix (thường là Linux), ngoài ra còn hỗ trợ rộng rãi các hệ điều hành khác bao gồm eComStation, Microsoft Windows, NetWare, OpenVMS, OS/2 và TPF. Apache là miễn phí và là phần mềm mã nguồn mở.

Vào tháng 11/2015, Apache được đánh giá phục vụ 50% của tất cả các website đang hoạt động và 35% top server trên tất cả các lĩnh vực.

2. Nginx là gì?

Nginx (phát âm là “engine x”) là 1 web server tập trung mạnh mẽ vào khả năng xử lý đồng thời cao, hiệu suất và sử dụng ít bộ nhớ. Nó cũng có thể hoạt động như một reverse proxy server cho các giao thức HTTP, HTTPS, SMTP, POP3 và IMAP, cũng như cân bằng tải (load balancer) và HTTP cache.

Được tạo ra bởi Igor Sysoev năm 2002, Nginx chạy trên Unix, Linux, các biến thể BSD, Mac OS X, Solaris, AIX, HP-UX và Microsoft Windows. Nginx là miễn phí và là phần mềm mã nguồn mở.

  Web server là gì? Hiểu rõ về web server

II. So sánh Nginx và Apache

1. Tổng quan chung

  • Apache web server là server phổ biến nhất trên Internet từ năm 1996.
  • Nginx được Igor Sysoev tạo ra năm 2002 nhằm giải quyết nhu cầu cần phục vụ 1 số lượng lớn các request đồng thời và vấn đề C10K (tức là hệ thống cần xử lý được khi có 10.000 khách hàng sử dụng cùng 1 thời điểm).

2. Kiến trúc

Apache hoạt động dựa trên kiến trúc hướng quy trình. Nginx hoạt động dựa trên kiến trúc hướng sự kiện.

Apache cung cấp một loạt các module đa xử lý (MPMs) để quy định cách mà nó phục vụ các request của người dùng. Các loại MPMs mà chúng ta có thể lựa chọn gồm:

  • Prefork: Nếu sử dụng MPM này thì mỗi request đến sẽ được một process xử lý, điều này sẽ tốn nhiều RAM nếu như có nhiều request đến (sẽ có nhiều process được tạo ra), tuy nhiên ưu điểm là nếu một process có vấn đề thì không ảnh hưởng đến các process khác. Số lượng process được tạo ra chúng ta có thể quy định trong file cấu hình của apache.
  • Worker: Nếu sử dụng MPM này thì mỗi request đến sẽ được xử lý bởi một thread thay vì một process (các thread có thể share memory chung với nhau), do đó sẽ tiết kiệm RAM nhiều hơn. Số lượng thread và process sinh ra, số thread trong một process, … chúng ta có thể quy định trong file cấu hình. Nhược điểm của MPM này là nếu như một thread có vấn đề sẽ ảnh hưởng đến các thread khác trong cùng process, hơn nữa nếu cấu hình keep-alive thì tất cả các process/thread đều được giữ lại để phục vụ cho đến khi hết thời gian keep-alive.
  • Event: Tương tự như Worker, có nghĩa là cũng sử dụng thread để phục vụ các request thay vì dùng process, tuy nhiên với Event MPM, thread riêng biệt sẽ dùng để phục vụ request và được giải phóng ngay sau khi xử lý xong, không phục thuộc vào trạng thái kết nối HTTP. Điều này đã được đánh dấu ổn định với việc phát hành của Apache 2.4.

Tuy nhiên, việc xử lý các truy vấn từ client đến server bằng các thread, mỗi truy vấn client sẽ được server xử lý bằng một thread riêng biệt cho đến khi nó hoàn thành nhiệm vụ sẽ làm ổ cứng trên server sẽ mất nhiều thời gian hơn để giải phóng các thread đã hoàn thành nhiệm vụ, và việc tạo ra nhiều thread cũng sẽ làm server tiêu hao rất nhiều tài nguyên (CPU, RAM).

Do ra đời sau Apache, Nginx đã khắc phục được hạn chế trên của Apache do sử dụng các thuật toán xử lý không đồng bộ, đơn luồng và hướng sự kiện.

  • Hướng sự kiện có nghĩa rằng các thông báo hoặc tín hiệu được sử dụng để đánh dấu sự khởi đầu hay kết thúc của 1 process. Như vậy, các tài nguyên có thể được sử dụng bởi các process khác cho đến khi 1 process khởi tạo sự kiện được kích hoạt và tài nguyên có thể được phân bố và phát hành tự động. Điều này dẫn đến việc sử dụng tối ưu hóa bộ nhớ và CPU.
  • Không đồng bộ có nghĩa là các thread có thể được xử lý đồng thời, giúp tăng cường việc chia sẻ tài nguyên mà không bị chuyên dụng hoặc bị chặn.
  • Đơn luồng có nghĩa là nhiều client có thể được xử lý bởi 1 worker process duy nhất với các tài nguyên không bị chặn.
  • Nginx sinh ra các worker process, mỗi worker process có thể xử lý hàng ngàn kết nối bằng cách thực hiện một cơ chế lặp nhanh chóng để liên tục kiểm tra và xử lý các sự kiện.
  • Mỗi kết nối được xử lý bởi worker được đặt trong sự kiện vòng lặp. Bên trong vòng lặp, các sự kiện được xử lý đồng bộ, cho phép công việc được xử lý một cách không chờ đợi. Khi kết nối đóng lại thì worker process bị xóa khỏi vòng lặp.

Với phương thức xử lý kết nối này cho phép Nginx tiến đến quy mô vô cùng xa chỉ với nguồn lực hạn chế. Vì máy chủ là đơn luồng và không tạo ra process hoặc thread mới cho mỗi request mới nên tương đối là hiệu quả, giúp giảm thiểu tài nguyên cần sử dụng.

Xem thêm tuyển dụng Back-end hấp dẫn trên TopDev

3. Nội dung tĩnh và động

  • Các Apache server có thể xử lý nội dung tĩnh bằng cách sử dụng các phương pháp dựa trên file thông thường của nó. Hiệu suất của các hoạt động này chủ yếu phụ thuộc vào các module đa xử lý MPMs đã được trình bày ở trên.
  • Apache cũng có thể xử lý nội dung động bằng cách nhúng một bộ xử lý của ngôn ngữ trong câu hỏi vào trường hợp worker của nó. Điều này cho phép nó thực hiện nội dung động bên trong các web server của mình mà không cần phải dựa vào các thành phần bên ngoài. Các bộ vi xử lý động có thể được kích hoạt thông qua việc sử dụng các module có thể tự động load được.
  • Nginx không có khả năng xử lý các nội dung động mà chỉ phục vụ các nội dung tĩnh.
  • Để xử lý các request PHP và các request khác đối với nội dung động, Nginx phải gọi đến một bộ vi xử lý bên ngoài để thực thi và đợi khi kết quả được gửi trở lại, sau đó sẽ chuyển các kết quả này đến client. Đối với người quản trị, điều này có nghĩa là cần phải cấu hình giữa Nginx và bộ vi xử lý dựa trên những giao thức mà Nginx có thể kết nối được, bao gồm: http, FastCGI, SCGI, uWSGI, memcache. Điều này có thể là hơi phức tạp.

4. Cấu hình

  • Các file .htaccess được sử dụng trong việc cấu hình máy chủ Apache. Công dụng của file .htacess này bao gồm: rewrite URL, hạn chế truy cập, ủy quyền và xác thực, thậm chí là chính sách bộ nhớ đệm.

file htaccess

Ưu điểm:

  • Thực thi ngay lập tức: Vì htaccess được đọc trên mọi yêu cầu, những thay đổi được thực hiện trong những tập tin này có hiệu lực ngay lập tức, trái ngược với các tập tin cấu hình chính mà đòi hỏi các máy chủ được khởi động lại thì các thiết lập mới có hiệu lực.
  • Hỗ trợ người dùng không có đặc quyền: cho phép người dùng cá nhân có khả năng thay đổi cấu hình trang web của họ trong khi các tập tin cấu hình máy chủ chính không cần phải được thay đổi.

Nhược điểm:

    • Giảm hiệu suất: cụ thể, khi được cấu hình để sử dụng .htaccess, thì Apache sẽ tìm kiếm tất cả những folder có chứa .htaccess để thực thi, và nó sẽ thực thi tất cả những file .htaccess tìm được. Do vậy, sẽ làm website của bạn trở nên ì ạch một cách không cần thiết.
    • Bảo mật: việc cho phép người dùng cá nhân thay đổi cấu hình của một máy chủ có thể gây ra vấn đề liên quan đến bảo mật nếu không được thiết lập đúng cách.
  • Nginx không có file cấu hình .htaccess giống như ở Apache. Điều đó mang lại sự kém linh hoạt hơn nhưng cũng có lợi thế riêng của nó.
  • Cải tiến đáng chú ý nhất của .htaccess cũng như cấu hình phân cấp thư mục là giúp tăng hiệu suất. Tuy nhiên, việc tìm kiếm các thư mục có chứa .htaccess để thực thi nhiều khi khiến website của bạn trở nên ì ạch hơn. Bằng cách không cho phép ghi đè thư mục, Nginx có thể xử lý các request nhanh hơn bởi việc tìm kiếm trong 1 thư mục đơn và file đọc cho mỗi request.
  • Một lợi thế khác là về vấn đề bảo mật. Cấu hình phân cấp thư mục cho phép người dùng cá nhân thay đổi cấu hình có thể gây ra các vấn đề bảo mật. Nginx đảm bảo các quản trị viên duy trì quyển kiểm soát toàn bộ web server để ngăn ngừa các sai lầm bảo mật có thể xảy ra.

5. File và giải thích dựa trên URI

  • Do Apache được tạo ra chỉ để làm web server. Nó hoạt động chủ yếu với thư mục file hệ thống.
  • Nginx được tạo ra để làm cả web server và proxy server. Do cấu trúc cần được đáp ứng cho cả 2 vai trò này nên nó hoạt động chủ yếu với các URI, chuyển đổi các file hệ thống khi cần thiết.
  • Nginx không cung cấp cơ chế để xác định cấu hình cho 1 thư mục file hệ thống mà thay vào đó là phân tích URI của chính nó.
  • Nginx không kiểm tra file hệ thống cho đến khi nó đã sẵn sàng để phục vụ các request, điều này giải thích lý do tại sao nó không thực hiện một hình thức của các file .htaccess giống với Apache.

6. Module

  • Hệ thống module của Apache cho phép bạn tự động load hoặc không load module để áp ứng nhu cầu của bạn trong quá trình chạy các server. Phần lõi Apache luôn hiện diện, trong khi các module có thể bật hoặc tắt, thêm hoặc loại bỏ các chức năng bổ sung và gắn vào server chính.
  • Module của Apache là không giới hạn để thực hiện các nội dung động. Hơn nữa, chúng có thể được sử dụng để rewrite URL, chứng thực client, tăng độ bền cho máy chủ, đăng nhập, bộ nhớ đệm, nén, proxy, hạn chế tốc độ và mã hóa.
  • Nginx cũng thực hiện 1 hệ thống module nhưng lại khá là khác với Apache. Trong Nginx, module không load được, vì vậy chúng phải được chọn và biên dịch vào phần mềm lõi. Đối với nhiều người thì điều này không hề linh hoạt 1 chút nào. Tuy nhiên nó cũng có thể hữu ích với trường hợp bạn chỉ muốn thêm những chức năng bạn muốn vào server mà thôi.

7. Hỗ trợ, tương thích, tài liệu

  • Bởi vì Apache đã được phát triển từ rất lâu cộng với các tính năng mạnh mẽ của nó mà nguồn tài liệu của nó thực sự lớn, được hỗ trợ và tương thích với nhiều dự án, nhiều công cụ khác. Ngoài ra, các quản trị viên dường như cũng có nhiều sự quen thuộc với Apache hơn là các web server khác.
  • Nginx cũng đang nhận được nhiều sự hỗ trợ cũng như được sử dụng rộng rãi do sự hiệu quả mà nó mang lại, tuy nhiên, nó vẫn cần bắt kịp Apache ở 1 số lĩnh vực chủ chốt. Về tài liệu, trước đây, thật khó khăn để tìm tài liệu tiếng Anh về Nginx do nó được phát triển ở Nga. Ngày nay thì nguồn tài liệu đã được bổ sung đầy đủ và phong phú hơn.

III. Kết hợp Nginx và Apache

  • Rõ ràng, cả Apache và Nginx đều có những ưu và nhược điểm khác nhau, tùy vào nhu cầu sử dụng mà ta có thể lựa chọn web server nào cho phù hợp. Tuy nhiên, ta hoàn toàn có thể tận dụng thế mạnh của cả Apache và Nginx bằng cách kết hợp chúng với nhau.
  • Apache tốt hơn Nginx trong việc phục vụ các trang web động, nhưng Nginx lại tốt hơn Apache trong việc phục vụ các trang web tĩnh. Do đó, để tận dụng ưu thế của cả 2 web server này, khái niệm reverse proxy đã ra đời.
  • Ở đây, Nginx được sử dụng như 1 reverse proxy của Apache. Đối với nội dung tĩnh là lợi thế của Nginx, các file sẽ được Nginx phục vụ một cách nhanh chóng và trực tiếp cho client. Còn đối với nội dung động là lợi thế của Apache, Nginx sẽ chuyển cho Apache thực hiện sau đó trả kết quả về cho Nginx, rồi Nginx trả kết quả đó lại cho client. Nói 1 cách đơn giản hơn là dùng Nginx để xử lý tập tin tĩnh (CSS, JS, HTML, …) và dùng Apache xử lý các tập tin động (PHP,…).
  • Do bản thân Nginx rất đa nhiệm, nên việc kết hợp với Apache không hề gây ra ảnh hưởng tiêu cực nào, mà còn phát huy tối đa lợi thế của cả 2 web server này, giúp tiết kiệm tài nguyên và làm tăng tốc độ tải cho website. Hơn nữa, bằng việc giảm bớt các yêu cầu gửi đến Apache đòi xử lý sẽ làm giảm bớt sự tắc nghẽn khi các process hoặc thread của Apache bị chiếm đóng. Ngoài ra, bạn cũng có thể thêm các backend server nếu cần thiết để tăng hiệu suất và tăng khả năng phục hồi cho cấu hình.

Hy vọng bài viết này sẽ giúp bạn hiểu rõ hơn về Nginx và Apache, biết được những ưu nhược điểm của cả 2 để từ đó chọn được web server phù hợp với  trang web của mình. Đừng quên truy cập TopDev để cập nhật các kiến thức liên quan đến ngành IT và việc làm Apache mới nhất bạn nhé!.

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

Xem thêm:

Deploy ứng dụng load balancer sử dụng Nginx với Docker

Cài đặt Apache Kafka sử dụng Docker Compose

Các khái niệm cơ bản trong Apache Kafka

Tham khảo thêm các vị trí tuyển dụng ngành IT tại Topdev

CI CD là gì? Lợi ích sử dụng trong quy trình phát triển phần mềm

CI CD là gì

Bài viết được sự cho phép của tác giả Phạm Minh Khoa

CI là gì?

CI là Continuous Integration. Nó là phương pháp phát triển phần mềm yêu cầu các thành viên của team tích hợp công việc của họ thường xuyên, mỗi ngày ít nhất một lần. Mỗi tích hợp được “build” tự động (bao gồm cả test) nhằm phát hiện lỗi nhanh nhất có thể.

Cả team nhận thấy rằng cách tiếp cận này giảm thiểu vấn đề tích hợp và cho phép phát triển phần mềm nhanh hơn.

Các bước trong một kịch bản CI thường như sau:

  • Đầu tiên, developer commit code lên repo.
  • CI server giám sát repo và kiểm tra xem liệu có thay đổi nào trên repo hay không (liên tục, chẳng hạn mỗi phút 1 lần)
  • Ngay khi commit xảy ra, CI server phát hiện repo có thay đổi, nên nó nhận code mới nhất từ repo và sau đó build, chạy unit và integration test
  • CI server sẽ sinh ra các feedback và gửi đến các member của project
  • CI server tiếp tục chờ thay đổi ở repo

Mỗi lần developer làm xong task, họ phải chạy một private build (tức là chạy phần mềm trên local trước), check choác cẩn thận và commit code lên repo khi đã thấy ổn. Bước này xảy ra thường xuyên và ở bất kỳ thời điểm nào trong ngày. Việc build tích hợp sẽ không xảy ra khi những thay đổi này chưa ảnh hưởng đến repo (kiểu như bạn commit mà chưa được merge vậy).

Một trong những tuyên ngôn của CI là “Build Software at Every Change”. Mục đích là để tránh những câu kiểu như “Ớ, phần này chạy trên máy em bình thường mà”. Vấn đề sẽ được tìm ra sớm bằng cách build thường xuyên, và để CI hoạt động hiệu quả trong project, tốt nhất là developer phải commit code thường xuyên hơn. Đợi hơn một ngày để commit code lên repo có thể khiến việc tích hợp tốn thời gian và code mình dùng có thể không phải là code mới nhất.

  Những điều bạn cần biết về mô hình CI/CD với CircleCI

Lợi ích của việc sử dụng CI sẽ là:

  • Giảm thiểu rủi ro nhờ việc phát hiện lỗi và fix sớm, tăng chất lượng phần mềm nhờ việc tự động test và inspect (đây cũng là một trong những lợi ích của CI, code được inspect tự động dựa theo config đã cài đặt, đảm bảo coding style, chẳng hạn một function chỉ được dài không quá 10 dòng code …)
  • Giảm thiểu những quy trình thủ công lặp đi lặp lại (build css, js, migrate, test…), thay vì đó là build tự động, chạy test tự động
  • Sinh ra phần mềm có thể deploy ở bất kì thời gian, địa điểm

CD là gì?

Trong khi Continuous Integration là quy trình để build và test tự động, thì Continuous Delivery (tạm dịch là chuyển giao liên tục) lại nâng cao hơn một chút, bằng cách triển khai tất cả thay đổi về code (đã được build và test) đến môi trường testing hoặc staging.

Continuous Delivery cho phép developer tự động hóa phần testing bên cạnh việc sử dụng unit test, kiểm tra phần mềm qua nhiều thước đo trước khi triển khai cho khách hàng (production). Những bài test này bao gồm UI testing, load testing, integration testing, API testing… Nó tự động hoàn toàn quy trình release phần mềm.

Continuous Delivery được thực hiện bằng cách sử dụng Deployment Pipeline.

  Triển khai CI/CD với Gitlab

Deployment Pipeline chia quy trình chuyển giao phần mềm thành các giai đoạn. Mỗi giai đoạn có mục tiêu xác minh chất lượng của các tính năng mới từ một góc độ khác nhau để kiểm định chức năng và tránh lỗi ảnh hưởng đến người dùng. Pipeline sẽ cung cấp phản hồi cho nhóm trong việc cung cấp tính năng mới. Ở góc độ trừu tượng hơn, deployment pipeline là quy trình để chuyển phần mềm từ version control đến tay người dùng. Mỗi thay đổi đến phần mềm sẽ đi qua một quy trình phức tạp để được phát hành.

Có một khái niệm nữa là Continuos Deployment, và hai khái niệm này thường hay bị nhầm lẫn với nhau. Nếu Continuous Delivery là triển khai code lên môi trường staging, và deploy thủ công lên môi trường production, thì Continuous Deployment (cũng viết tắt là CD) lại là kỹ thuật để triển khai code lên môi trường production một cách tự động, và cũng nên là mục tiêu của hầu hết công ty.

Về cơ bản thì môi trường staging là môi trường giống với production, nên đã làm Continous Delivery được thì cũng làm Continous Deployment được. Tuy nhiên, thực tế lại không dễ dàng như vậy. Lý do thứ nhất là chúng ta có thể deploy tự động lên staging, nhưng liệu chúng ta có dám deploy tự động với production, cho dù là mọi cấu hình đều giống nhau thì thực tế staging và production server vẫn là hai server riêng biệt, và vì thế không thể đảm bảo mọi thứ chạy đúng trên staging sẽ chạy đúng trên production, thế nên deploy lên production thường phải làm thủ công để chắc chắn là các bước build, test được thực hiện chính xác. Lý do thứ hai đơn giản hơn, đó là rất khó để test tự động hoàn toàn, và bởi vậy khó mà tự động deploy được.

Dù Continous Deployment có thể không phù hợp với mọi công ty, nhưng Continuous Delivery thì tuyệt đối là yêu cầu cho việc thực hiện triết lý DevOps. Chỉ khi code được chuyển giao liên tục, chúng ta mới có thể tự tin rằng những thay đổi từ code sẽ phục vụ cho khách hàng sau chỉ vài phút với một nút ấn.

Đừng bỏ lỡ việc làm Backend hấp dẫn trên TopDev

Những lợi ích mà CI/CD mang lại là gì?

  • Giảm thiểu rủi ro không đáng có

Đây có thể là một lợi ích vô cùng hữu ích của CI/CD, nó cho phép làm giảm thiểu đi những rủi ro nhờ việc phát hiện và sửa lỗi sớm, giúp tăng chất lượng sản phẩm nhờ khả năng tự động kiểm tra và quan sát. Không những vậy, những quy trình thủ công lặp đi lặp lại hằng ngày cũng được giảm tải, thay vào đó là xây dựng và kiểm thử tự động mà không cần đến sự giúp đỡ của con người. Một đặc điểm nữa của CI CD chính là có thể deploy, triển khai phần mềm ở bất cứ địa điểm và thời gian nào.

  • Thay đổi code nhỏ

Một lợi ích vô cùng lớn của CI/CD chính là cho phép chúng ta tích hợp nhiều loại mã nhỏ cùng một lúc. Những thay đổi mã này được thực hiện một cách đơn giản và xử lý nhanh hơn so với những đoạn mã khổng lồ, từ đó làm giảm đi khả năng sinh ra những vấn đề liên quan đến việc thay đổi sau này.

Những sự thay đổi mã nhỏ này có thể được thực kiểm tra ngay sau khi chúng được tích hợp vào kho mã. Các nhà phát triển có thể dễ dàng nhận ra vấn đề trước khi lượng lớn công việc tăng lên một cách chóng mặt. Đây thực sự là một lợi thế đối với những nhóm phát triển lớn hoặc người làm việc từ xa giao tiếp được hiệu quả hơn.

  • Hạn chế những ảnh hưởng của lỗi hiệu quả

CI/CD được thiết kế với hệ thống sao cho khi có lỗi nào đó xảy ra thì những kết quả tiêu cực sẽ bị giới hạn trong phạm vi ảnh hưởng nhất định nào đó. Việc hạn chế các vấn đề này giúp làm giảm khả năng hư hỏng từ đó làm cho hệ thống được bảo trì và xử lý một cách dễ dàng hơn.Với hệ thống CI CD, có thể đảm bảo cho việc cách ly lỗi sẽ được phát hiện một cách nhanh chóng và dễ dàng thực hiện hơn. Chính vì vậy, hậu quả của các lỗi trong ứng dụng sẽ được giới hạn trong phạm vi ảnh hưởng của nó.

Hy vọng bài viết này về CI/CD là gì sẽ giúp ích cho quá trình setup CI/CD trong hệ thống của bạn, cũng như tăng tốc quá trình phát triển dự án. Nếu thấy bài viết hay và hữu ích, hãy chia sẻ cho các anh em khác để cùng trao đổi và giao lưu.

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

Xem thêm:

Đừng bỏ lỡ Việc làm Developer hấp dẫn trên TopDev

Giới thiệu Cypress – Testing Tool cho FrontEnd

Giới thiệu Cypress

Bài viết được sự cho phép của tác giả Phạm Minh Khoa

Cypress là gì?

Cypress là tool phục vụ cho UI Automation test và chính xác là dành cho web. Nó có chức năng tương đương với Selenium, nhưng được viết bằng javascript và có cách hoạt động hoàn toàn khác biệt.

Nó được giới thiệu là nhanh, đáng tin cậy hơn selenium và có thể dùng cho nhiều level test, từ Unit, Integration đến End-to-end Test. Vì nó được định hình là framework nên chắc chắn nó sẽ có nhiều tính năng tốt hơn selenium, cái đơn thuần là library.

Cypress là gì?

Cypress hỗ trợ chúng ta làm gì?

  • Thiết lập tests
  • Viết tests
  • Chạy tests
  • Debug tests

Đằng sau Cypress là một máy chủ Node.js. Quá trình Cypress và Node.js liên tục liên lạc, đồng bộ hóa và thực hiện các nhiệm vụ thay mặt cho nhau. Có quyền truy cập vào cả hai phần (front and back) cho phép khả năng phản hồi các sự kiện của ứng dụng trong thời gian thực, đồng thời hoạt động bên ngoài trình duyệt cho các tác vụ yêu cầu đặc quyền cao hơn.

  Selenium là gì? Một số kinh nghiệm làm việc với Selenium

Ai là người sẽ sử dụng Cypress trong dự án?

Thường thì những đối tượng sử dụng Cypress là developers hoặc QA khi xây dựng một ứng dụng Web có sử dụng Javascript framework.

Cypress cho phép người dùng thực thi rất nhiều loại test:

  • End-to-end tests
  • Integration tests
  • Unit tests Cypress có thể test bất cứ thứ gì chạy trên trình duyệt.

Ứng tuyển ngay các vị trí tuyển dụng Frontend trên TopDev

Sự khác biệt của Selenium và Cypress

Đối với Selenium

  1. Ở Client, code test sử dụng thư viện selenium sẽ được chuyển thành nội dung của những request gửi đến cho Driver của Browser.
  2. Những Driver này nhận request và thực thi trên Browser
  3. Sau đó, trả kết quả về cho Client.

Chốt lại: Selenium không tác động trực tiếp lên trang web của chúng ta, nó điều khiển thông qua Driver.

  Automation testing: Một số công cụ hữu ích cho tester

Đối với Cypress

  1. Nodejs process sẽ khởi tạo 1 browser với proxy.
  2. Browser này sẽ được hiển thị với 2 iframes. 1 cái là cypress (domain: localhost) và 1 cái là application của chúng ta (domain riêng). Bởi vì các iframes trên browser không thể trao đổi hoặc tương tác lẫn nhau nếu khác domain nên 1 script được cài vào trong application để đổi domain của app thành localhost. Từ đó, cypress có thể access đến các object khác trong app như DOM, Window, LocalStorage…
  3. Cypress cũng tương tác với Nodejs để có thể xin cấp quyền từ hệ điều hành (OS) cho các tác vụ như chụp ảnh hoặc quay video.
  4. Vì browser được khởi tạo cùng với proxy nên cypress quản lý được network ra vào của browser đó, từ đó edit được request và response.

Ứng tuyển ngay việc làm Tester HOT tại TopDev!

Ưu, nhược điểm của Cypress

selenium với cypress

Tất nhiên tùy vào bài toàn của từng project mà 2 test tool này được chọn và sử dụng với các mục đích khác nhau. Ngoài ra các bạn có thể tham khảo so sánh npm trends ở link dưới đây:

https://www.npmtrends.com/cypress-vs-selenium-webdriver-vs-testcafe

Hy vọng rằng bài viết này sẽ giúp bạn hiểu rõ hơn về Cypress cũng như những điểm khác nhau của Selenium và Cypress. Đừng quên theo dõi TopDev để cập nhật các việc làm FrontEnd mới nhất nhé.

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

Bạn có thể xem thêm những bài viết hay dưới đây:

Kinh Nghiệm Phỏng Vấn Tester Thành Công Được Áp Dụng Nhiều Nhất

NUnit – Thực thi kiểm thử tự động với mã từ Selenium IDE

9 Câu Hỏi Phỏng Vấn Frontend Developer Có Thể Bạn Chưa Biết

Xem thêm các việc làm CNTT hấp dẫn tại TopDev

IOS Developer là gì? Tổng quan về iOS Developer

iOS Developer la gi

Trong thời đại công nghệ 4.0 hiện nay, nhu cầu tuyển dụng Developer luôn ở mức cao. Đặc biệt, sự phát triển mạnh mẽ của hệ điều hành iOS thì vị trí iOS Developer càng thu hút được nhiều sự quan tâm từ các bạn trẻ. Vậy bạn đã biết gì về iOS Developer? Công việc cụ thể của lập trình viên iOS là gì? Hãy cùng TopDev tìm hiểu dưới bài viết này nhé!

iOS Developer là gì?

ios developer la gi

iOS không còn quá xa lạ với người dùng Việt, đây là hệ điều hành chạy trên các dòng điện thoại iPhone của Apple. Android và iOS là hai hệ điều hành đang thống lĩnh trên thị trường, được nhiều nhà sản xuất phần mềm quan tâm.

Với hệ điều hành này, người dùng có thể thoải mái tương tác thông qua các thao tác trên màn hình cảm ứng. Những thao tác này được các lập trình viên thiết lập trước và không ngừng được cải thiện, nâng cấp để tăng khả năng xử lý và trải nghiệm cho người dùng.

Đây cũng chính là một phần công việc của các iOS Developer. Các iOS Developer sẽ sử dụng ngôn ngữ lập trình Swift để thiết kế, phát triển phần mềm tương thích với hệ điều hành của Apple.

  Kiểu dữ liệu, biến, hằng trong ngôn ngữ Swift

Công việc của lập trình viên iOS

Một lập trình viên iOS thường thực hiện những công việc như thế nào? Dưới đây là một số công việc các iOS Developer thường làm:

  • Lên ý tưởng, thiết kế và xây dựng ứng dụng mới liên quan đến hệ điều hành iOS.
  • Thảo luận và lên ý tưởng với các Developer khác để phát triển ứng dụng.
  • Viết mã để kiểm tra tính năng và khả năng hoạt động của ứng dụng.
  • Phát hiện lỗi và sửa lỗi để tối ưu hiệu suất hoạt động ứng dụng.
  • Không ngừng theo dõi và nâng cấp các tính năng mới cho ứng dụng.

Các kỹ năng cần có của một iOS Developer

Khả năng làm việc với mô hình Agile

Một lập trình viên iOS cần phải làm việc thành thạo với mô hình Agile. Áp dụng mô hình này giúp cải thiện tốc độ bàn giao dự án, tăng hiệu suất công việc và công việc đi theo kế hoạch rõ ràng. Một iOS Developer am hiểu mô hình Agile sẽ có khả năng làm việc tốt hơn, dễ dàng thăng tiến.

mô hình agile

 

Thành thạo các kỹ năng về UI, UX và không gian lý luận

UI là một yếu tố liên quan đến giao diện của ứng dụng, thu hút người sử dụng ứng dụng của bạn. UX sẽ liên quan đến vấn đề về trải nghiệm của người dùng trên ứng dụng. Công việc của các lập trình viên iOS là phải tạo ra được một ứng dụng vừa có giao diện bắt mắt và vừa phải dễ sử dụng.

Kỹ năng Networking

Một ứng dụng không thể hoàn thành chỉ với một lập trình viên mà cần sự trao đổi, thảo luận của cả team. Vì vậy, kỹ năng networking sẽ giúp cho công việc của các iOS Developer thuận lợi hơn, công việc đạt được hiệu quả như mong muốn. 

  5 bài học quí giá về việc phát triển ứng dụng iOS

Nhu cầu tuyển dụng lập trình viên iOS hiện nay

Sự phát triển mạnh mẽ của công nghệ, đặc biệt là các thiết bị di động đã kéo thu nhu cầu về nhân lực ngành công nghệ tăng cao. Cùng với đó, Apple là một “gã khổng lồ” trong giới công nghệ với dòng điện thoại iPhone chạy hệ điều hành iOS đang ngày càng “bành trướng” thị trường của mình. Chính vì thế, cơ hội việc làm cho các lập trình viên iOS Developer vô cùng rộng mở.

Không chỉ riêng gì Việt Nam, nguồn nhân lực lập trình viên iOS luôn là “cơn khát” với các công ty công nghệ. Nếu bạn đang tìm kiếm một việc làm iOS thì nhất định không thể bỏ qua TopDev. Tại TopDev, bạn sẽ dễ dàng tìm được các công việc iOS Developer với mức lương và đãi ngộ siêu hấp dẫn.

Đừng bỏ lỡ việc làm Swift HOT trên TopDev!

Mức lương của lập trình viên iOS

muc luong lap trinh vien ios

Với nhu cầu tuyển dụng cao nên mức lương cho vị trí iOS Developer cũng ở mức cao. Mức lương trung bình của một lập trình viên iOS rơi vào khoảng 14 – 16 triệu đồng/tháng với người có kinh nghiệm 1 – 2 năm. Còn đối với sinh viên mới ra trường chưa có kinh nghiệm thì mức lương khởi điểm khoảng 8 – 10 triệu đồng/tháng. Những người có thâm niên trong nghề thì đạt được mức lương trên 40 triệu đồng/tháng là điều không quá khó. Tùy vào năng lực, kinh nghiệm, chuyên môn của mỗi người mà sẽ có mức thu nhập khác nhau.

Có thể thấy, iOS Developer là một nghề đầy hứa hẹn trong tương lai. Đặc biệt, khi Việt Nam đang trên đà phát triển mạnh mẽ về kinh tế, đặc biệt là trong lĩnh vực công nghệ thông tin.

Tóm lại

Với những chia sẻ trên, mong rằng bạn đã có thêm thông tin về nghề iOS Developer cũng như những kỹ năng, yêu cầu của công việc này. Hãy lên kế hoạch cho mình để bắt đầu chinh phục con đường trở thành một lập trình viên giỏi trong tương lai bạn nhé.

Hoặc, bạn có thể tham khảo tin tuyển dụng iOS Developer trên TopDev, để có thể hiểu rõ hơn về những yêu cầu, nhiệm vụ của một lập trình viên iOS. Chúc các bạn tìm được công việc ưng ý.

Xem thêm:

Quản lý realm database theo hướng micro-service trong iOS

Hệ điều hành Android là gì? Lập trình với Android

Lập trình IOS: Làm sao để viết code swift đúng chuẩn thế giới?

Tìm việc làm IT lương cao, đãi ngộ hấp dẫn trên TopDev!

Python và cách tiết kiệm dung lượng cho phần mềm nhúng

Python và cách tiết kiệm dung lượng cho phần mềm nhúng

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

Khi tôi bắt đầu bước chân vào mảng IoT đầu năm 2016, tôi bắt đầu lân la tiếp xúc với cộng đồng làm IoT Việt Nam (trên Facebook là chính). Ở Việt Nam, lực lượng tech làm IoT đa phần là dân điện tử đi lên, thế nên tôi hay gặp những câu hỏi như “nên dùng ngôn ngữ nào để lập trình nhúng” từ những bạn sinh viên mới. Tôi cũng ngạc nhiên khi thấy các bạn kháo nhau dùng NodeJS, theo phong trào.

Nếu cần dùng các ngôn ngữ biên dịch như C++, Go thì không nói. Nhưng nếu dùng ngôn ngữ thông dịch thì Python nên được dùng hơn NodeJS/JavaScript. Một khía cạnh nên tính đến là độ lớn file cần lưu trữ. Các board máy tính nhúng chạy Linux thường dùng thẻ nhớ, hoặc bộ nhớ flash trong (còn có cách gọi khác là NAND Flash, SPI Flash, eMMC) để thay thế ổ cứng (HDD) nên có dung lượng khiêm tốn. Nếu cách lưu trữ không phù hợp, có khi thư viện đã ngốn hết không gian lưu trữ đáng lẽ phải dành cho chương trình và dữ liệu (data).

  Để học tốt Python

Thứ nhất, cách quản lý các gói thư viện phụ thuộc của NodeJS cực kỳ tốn dung lượng, với sự trùng lắp các file thư viện.

node_modules

Hình bên trên là ví dụ về cách lưu trữ thư viện khi cài bằng yarn. Tình hình còn tệ hơn nếu cài bằng npm, vốn có truyền thống không thèm phân giải mối ràng buộc phiên bản (dependency version resolve) mà cứ lồng các gói phụ thuộc vào nhau, dẫn đến câu châm biếm sau:

heaviest

Ghi chú: Có vẻ, gần đây, sau khi nhận nhiều châm biếm thì npm đang cải thiện vụ quản lý thư viện này.

Xem thêm các việc làm Python hấp dẫn tại TopDev

Thứ hai, NodeJS không hỗ trợ phân phối gói thư viện ở dạng binary. Đối với cả Python và NodeJS, có nhiều thư viện được viết bằng C/C++. Khi cài đặt những thư viện này thì phải có bước biên dịch mã nguồn C/C++ đó thành file binary (*.so hay *.dll). Nếu ngôn ngữ đó không có quy chuẩn về phân phối thư viện biên dịch trước ở dạng binary, thì trình quản lý gói, sẽ phải download source code và tiến hành biên dịch ngay trên máy người dùng cuối. Và để làm việc đó thì máy người dùng cuối phải cài trước trình biên dịch, code generator (như Swig), các source code của thư viện C/C++ mà gói thư viện Python/NodeJS kia phụ thuộc vào. Như vậy là dung lượng khiêm tốn của máy tính nhúng lại phải dành chỗ cho những thứ nặng nề này.

  Viết ứng dụng tra số điện thoại thuộc Quốc gia nào bằng Python

Python giúp cắt bỏ những thứ nặng nề kia bằng cách định ra một phương pháp đóng gói và phân phối qua file wheel, trong đó các thư viện viết bằng C/C++ sẽ được biên dịch trước, file nhị phân thành phẩm (cùng các file metadata phụ trợ) sẽ được đóng gói và xuất bản trên kênh phân phối chính thức của Python (https://pypi.org/). Khi cài đặt trên máy người dùng cuối thì pip (trình quản lý gói của Python) chỉ việc download file đã dịch này, không phải download bộ source code C/C++, người dùng cũng không phải cài trình biên dịch và mớ mã nguồn. Vừa tiết kiệm không gian lưu trữ, vừa tiết kiệm thời gian biên dịch. Đặc biệt, vì các máy tính nhúng dùng CPU ARM, hơi yếu nên thời gian biên dịch cực kỳ lâu. Nếu bạn triển khai cho nhiều khách hàng, tức là phải cài phần mềm trên nhiều board, thì thời gian tiêu phí cho quá trình biên dịch càng lớn.

Ghi chú: Có một vài thư viện NodeJS cũng thấy nỗi nhức nhối này và họ đã workaround, bằng cách phân phối một script “installer” chứ không phân phối bản thân thư viện. Khi người dùng cài gói, script này sẽ chạy và download file binary biên dịch sẵn từ website của tác giả thư viện về. Nguồn download là website của tác giả chứ không phải kho chính thức của NodeJS (https://www.npmjs.com/).

Tham khảo tuyển dụng python Hà Nội lương cao trên TopDev

Gần đây, khi tham gia vào dự án SUSI.AI Smart Speaker, một nhiệm vụ của tôi là giảm tổng dung lượng của phần mềm trên Raspberry Pi. Tổng dung lượng ở đây là tính tất cả những thứ phải cài đặt trên Raspperry Pi (bao gồm cả hệ điều hành). Trước khi tôi tham gia, dự án đã có một script install.sh để tiến hành cài tự động các phần mềm cần thiết, cho phép người mới vào dự án có thể bắt tay lập trình luôn. Có điều, do thiếu người mạnh dẫn dắt từ đầu nên dự án trở nên lộn xộn, ngay cả file install.sh cũng không chạy thành công. Trước khi file install.sh đó được sửa (mà người phụ trách là tôi) thì một bạn thành viên đề xuất sẽ copy thẻ nhớ (chạy Raspberry Pi) của anh ta ra một file image. Tất cả những thành viên mới chỉ việc nạp image đó vô thẻ nhớ của mình rồi bắt đầu công việc. Thế nhưng, khi copy ra xong thì file đó nặng tới 16GB! Cho dù có nén kiểu gì thì dung lượng đó quá lớn một cách lố bịch. Đóng góp vào con số khủng khiếp đó là một đống những phần mềm công cụ, mã nguồn thư viện. Dó có liên quan đến AI nên phải dùng đến một số thư viện tính toán đại số, và ở dạng mã nguồn thì nó rất lớn. Chưa kể, thành viên đó lại không thạo Linux, nên dùng một công cụ Windows để tạo image thẻ nhớ, khiến không có một phương pháp tạo image tối ưu (đục bỏ phần dữ liệu rơi rớt của những file đã xóa). Đây cũng là một trong các lí do mà tôi luôn khuyên các bạn làm IoT, lập trình nhúng phải chuyển sang Linux. Sau vài tháng miệt mài sửa file install.sh, chuyển các thư viện sang dạng đóng gói binary, thậm chí đóng góp code vào cho một thư viện bên thứ ba, viết script để build hệ điều hành một cách tự động (khi chúng tôi cập nhật code mới) thì dung lượng image đã giảm đáng kể, nay còn 781MB sau khi nén.

Ngoài ra, trong quá trình làm việc tại AgriConnectFOSSASIA thì tôi cũng build trước một số ứng dụng và thư viện thành dạng binary cho ARM, để tiết kiệm thời gian cài đặt, triển khai trên BeagleBone, Raspberry Pi. Các kho này là public nên ai có nhu cầu tương tự cũng có thể tận dụng: https://repo.fury.io/agriconnect, https://repo.fury.io/fossasia.

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

Xem thêm các bài viết liên quan:

Tuple Python là gì? Tìm hiểu về tuple python

Hướng dẫn từng bước lập trình web với Python

Chuyển đổi Unicode dựng sẵn & tổ hợp với Python

Tìm việc làm lập trình mới nhất trên TopDev

Cài đặt và sử dụng Storybook cho ReactJS

cai dat va su dung Storybook

Bài viết được sự cho phép của tác giả Phạm Minh Khoa

Trong bài viết trước đây mình đã giới thiệu về Storybook, các bạn chưa đọc có thể xem lại ở link dưới đây:

Giới thiệu về StoryBook cho dự án FrontEnd

Hôm nay mình tiếp tục hướng dẫn các bước để cài đặt và sử dụng Storybook trong dự án ReactJS.

Cài đặt Storybook

Storybook có thể cài đặt dễ dàng bằng cách chạy dòng lệnh dưới đây ở thư mục root của project (lưu ý là sử dụng với project đã có, lệnh dưới sẽ không tạo ra 1 project mới)

# Add Storybook:
npx sb init

Storybook sẽ check các dependencies sẵn có trong project của bạn (file package.json) và thực hiện cài đặt để cung cấp cho bạn 1 cấu hình tốt nhất có thể. Dòng lệnh trên sẽ thực hiện các công việc sau:

  • Cài đặt các dependencies cần thiết
  • Cài đặt những mã (scripts) cần thiết cho việc build và chạy Storybook
  • Thêm cấu hình mặc định cho Storybook
  • Tạo ra 1 số stories mẫu để bạn có thể xem và chạy thử

Sau khi chạy xong thì 1 thư mục stories chứa các stories mẫu sẽ được tạo ra nằm trong thư mục src trong project của bạn.

 

  React là gì? Lộ trình trở thành lập trình viên ReactJS
  Những câu hỏi phỏng vấn React thường gặp

Chạy Storybook

# Starts Storybook in development mode
npm run storybook

Chạy storybook cho project của bạn bằng lệnh trên, kết quả nhận được sẽ như hình dưới đây nếu mọi thứ làm việc ok.

Setup Storybook

Giờ chúng ta sẽ tìm cách hiển thị component trong project của mình lên storybook. Ví dụ chúng ta có 1 component là YourComponent, tạo các file .stories.js.stories.mdx dùng để hiển thị component đó lên storybook và hướng dẫn cách sử dụng chúng.

// YourComponent.stories.js|jsx

import { YourComponent } from './YourComponent';

// This default export determines where your story goes in the story list
export default {
  /*  The title prop is optional.
  * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
  * to learn how to generate automatic titles
  */
  title: 'YourComponent',
  component: YourComponent,
};

// We create a “template” of how args map to rendering
const Template = (args) => <YourComponent {...args} />;

export const FirstStory = {
  args: {
    // The args you need here will depend on your component
  },
};
<!-- YourComponent.stories.mdx -->

import { Meta, Story } from '@storybook/addon-docs';

import { YourComponent } from './YourComponent';

<!-- The title prop determines where your story goes in the story list -->
<Meta title="YourComponent" component={YourComponent} />

<!-- We create a “template” of how args map to rendering -->
export const Template = (args) => <YourComponent {...args} />;

<!--  The args you need here will depend on your component -->
<Story
  name="FirstStory"
  args={{}}>
  {Template.bind({})}
</Story>

Lưu lại và xem kết quả trên storybook của chúng ta (storybook hỗ trợ hot reload nên không cần chạy lại nhé các bạn)

Các bạn có thể xem full source code demo storybook ở đây nhé.

https://github.com/Akishina/reactjs-storybook

Cảm ơn mọi người đã đọc bài.

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

Theo dõi những bài viết mới nhất của TopDev nhé:

Học ReactJS trong 15 phút

Xây dựng một ứng dụng trò chuyện bằng ReactJS trong 10 PHÚT (Phần 1)

Hướng dẫn sử dụng ReactJS Props và State

Xem thêm các việc làm Reactviệc làm ReactJS hấp dẫn tại TopDev

 

Nên đăng tin tuyển dụng ở đâu? Cần lưu ý gì khi đăng tin tuyển dụng

Nên đăng tin tuyển dụng ở đâu

Nên đăng tin tuyển dụng ở đâu cho hiệu quả khi nhu cầu của doanh nghiệp ngày càng gia tăng? Làm thế nào để vừa tuyển được người tài vừa tiết kiệm chi phí nhất? Có thể thấy, việc tìm được một ứng viên chất lượng thì nhà tuyển dụng cần phải lên chiến lược cụ thể. Chọn đúng nơi, đúng nền tảng để đăng tin tuyển dụng là bước đầu tiên giúp nhà tuyển dụng tiếp cận được đối tượng cần tuyển. Bài viết này, TopDev sẽ giải đáp cho bạn tất cả các vấn đề trên.

Nhu cầu đăng tin tuyển dụng chất lượng ngày càng cao

Sau hơn 2 năm đại dịch, nhu cầu tuyển dụng nhân sự của các doanh nghiệp đã bắt đầu tăng trở lại. Các ngành nghề như: Thương mại điện tử, Công nghệ thông tin, Thiết kế đồ họa, Kỹ thuật ô tô, Logistic & Quản lý chuỗi cung ứng,… đang rất khát nhân lực. Đặc biệt, trong thời điểm cuối năm nay khi tình hình kinh tế đang có nhiều biến động thì vấn đề tuyển dụng nhân sự chất lượng cao lại càng cấp thiết.

Nhiều công ty, doanh nghiệp đã phải bỏ ra một ngân sách rất lớn để giải quyết vấn đề tìm kiếm và đào tạo nhân sự. Có thể thấy, việc tìm được một kênh tuyển dụng chất lượng với tiềm năng nhân sự dồi dào, sẽ giúp ích rất nhiều cho quá trình tuyển dụng của doanh nghiệp. Vậy các doanh nghiệp nên đăng tin tuyển dụng ở đâu cho hiệu quả?

nhu cầu tuyển dụng

Nên đăng tin tuyển dụng ở đâu? Tham khảo 5 kênh tuyển dụng chất lượng

Những ưu nhược điểm của các kênh này là gì? Lựa chọn kênh nào sẽ phù hợp với nhu cầu tuyển dụng của bạn? Mời bạn tiếp tục theo dõi các thông tin dưới đây.

Đăng trên các trang tuyển dụng

Website tuyển dụng là một trong các kênh hiệu quả nhất giúp doanh nghiệp tuyển dụng nhân sự. Một website tuyển dụng chất lượng sẽ thu hút hàng triệu lượt truy cập mỗi ngày, bạn sẽ dễ dàng tiếp cận được với các ứng viên tiềm năng.

Việc để đăng tuyển trên các website này cũng không quá khó, chỉ vài thao tác đơn giản là bạn đã có thể đăng ký thành công. Bên cạnh đó, tùy vào trang web mà sẽ tính phí đăng tuyển hoặc là miễn phí. Nhưng với những trang tính phí thì nguồn nhân sự thường sẽ chất lượng hơn, các ứng viên giàu kinh nghiệm chuyên môn và các kỹ năng cần thiết.

  Trang web tuyển dụng IT uy tín - Cầu nối nhà tuyển dụng và người tìm việc

Đăng tin tuyển dụng trên Facebook

tuyển dụng trên facebook

Facebook là một mạng xã hội với lượng người dùng cực khủng và cũng là nơi tuyệt vời dành cho các nhà tuyển dụng nhân sự. Để tiếp cận đúng đối tượng ứng viên, các nhà tuyển dụng thường đăng tin tuyển ở các hội nhóm việc làm. Hoặc xây dựng trang tuyển dụng cho công ty và chạy quảng cáo tiếp cận ứng viên.

Một ưu điểm khi đăng tin tuyển dụng trên Facebook là sự đa dạng về hình thức đăng. Bạn có thể đăng bài ở dạng tin tức, hình ảnh, video ngắn,… Khi đăng bài trên đây bạn cần đầu tư chỉn chu về mặt nội dung và hình ảnh để thu về nguồn ứng viên chất lượng.

Đăng tin tuyển dụng trên LinkedIn

Nên đăng tin tuyển dụng ở đâu? Tuyển dụng trên LinkedIn là lựa chọn tốt dành cho bạn. LinkedIn sẽ giúp bạn xây dựng profile công ty một cách chuyên nghiệp và miễn phí. Bạn có thể tham gia vào các hội nhóm thảo luận để đăng bài tuyển dụng ứng viên. Các ứng viên trên LinkedIn thường rất chất lượng, sẽ phù hợp với các doanh nghiệp cần tuyển nhân sự có nhiều kinh nghiệm chuyên môn.

Thông qua các sự kiện tuyển dụng, sự kiện chuyên ngành

Các sự kiện tuyển dụng, sự kiện chuyên ngành là cơ hội tuyệt vời cho các nhà tuyển dụng để tiếp cận đúng nguồn ứng viên. Bởi đa phần những người tham gia sự kiện này đều đang có nhu cầu tìm kiếm cơ hội việc làm. Nếu doanh nghiệp của bạn có thể chia sẻ những chính sách đãi ngộ hấp dẫn, môi trường làm việc tốt thì chắc chắn sẽ thu hút được nhiều ứng viên.

  50+ tiêu đề tuyển dụng nhân sự cực ấn tượng, thu hút lượng tương tác cao

Tuyển dụng thông qua các trường đại học

Mỗi năm có một số lượng lớn sinh viên ra trường, đây là nguồn nhân lực dồi dào cho các doanh nghiệp. Vậy nên, các chương trình liên kết với các trường đại học để tuyển dụng nhân tài được rất nhiều doanh nghiệp áp dụng. Bạn có thể đưa ra yêu cầu tuyển dụng các sinh viên có mức điểm tốt nghiệp tốt để dễ dàng đào tạo.

Cần lưu ý gì khi đăng tin tuyển dụng?

Để quá trình tuyển dụng đạt hiệu quả cao, thu hút được nhiều ứng viên chất lượng thì nhà tuyển dụng cần lưu ý những vấn đề sau:

Xác định đúng đối tượng

Xác định đúng đối tượng ứng viên giúp bạn chọn đúng kênh tuyển dụng, đáp ứng được các yêu cầu của vị trí đang tuyển. Việc này giúp bạn tiết kiệm được thời gian và chi phí tuyển dụng.

Trau chuốt nội dung đăng tuyển, cần rõ ràng và chính xác

Khi đăng một tin tuyển dụng, bạn cần cung cấp đầy đủ thông tin mà một ứng viên cần biết. Nếu đăng bài trên các website thì nên điền đầy đủ thông tin của công ty. Điều này thể hiện được sự chuyên nghiệp và sự quan tâm của doanh nghiệp đến quá trình tuyển dụng.

Thông tin liên lạc chính xác

Nhà tuyển dụng cần cung cấp các thông tin về số điện thoại, email, tên doanh nghiệp, địa chỉ doanh nghiệp,… để ứng viên dễ dàng gửi CV và tìm hiểu kỹ về doanh nghiệp trước khi đến phỏng vấn.

TopDev – Nền tảng tuyển dụng IT hàng đầu

TopDev.vn là một nền tảng tuyển dụng CNTT hàng đầu Việt Nam với trung bình 30,000+ lượt truy cập mỗi ngày. Đây sẽ là nơi tuyệt vời để đăng tin tuyển dụng cho các doanh nghiệp chuyên về ngành IT.

Tại TopDev, bạn sẽ dễ dàng tiếp cận đúng đối tượng ứng viên khi có đến 90% traffic là từ các lập trình viên. Thêm nữa, độ phủ sóng thương hiệu của bạn sẽ tăng cao khi các tin tuyển dụng được chia sẻ qua những trang mạng xã hội như Facebook, LinkedIn, hay Email do TopDev quản lý. Quá trình đăng tuyển cũng rất dễ dàng và nhanh chóng, TopDev sẽ luôn hỗ trợ bạn trên con đường tìm kiếm ứng viên tiềm năng.

Bạn có thể tham khảo dịch vụ và ưu đãi tại đây!

Tóm lại

Việc chọn kênh tuyển dụng nào cho phù hợp còn phụ thuộc vào vị trí tuyển dụng, đối tượng tuyển dụng, ngân sách và nhiều yếu tố khác nữa. Hy vọng rằng với những chia sẻ trên đã giúp các bạn biết được nên đăng tin tuyển dụng ở đâu cho hiệu quả và những vấn đề cần lưu ý khi đăng tin tuyển dụng.

Nếu bạn đang có nhu cầu tuyển dụng lập trình viên FrontEnd chất lượng thì đừng quên truy cập TopDev nhé. Đăng ký ngay hôm nay để nhận các ưu đãi cực hấp dẫn.

Xem thêm:

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

Ngôn ngữ lập trình PHP là gì? Tất tần tật những điều bạn cần biết về PHP

PHP là một ngôn ngữ lập trình rất phổ biến với dân IT, vậy ngôn ngữ lập trình PHP là gì? Vai trò của PHP trong việc phát triển các phần mềm? Những ưu, nhược điểm của ngôn ngữ PHP? Bài viết này chúng ta hãy cùng tìm hiểu kỹ hơn về ngôn ngữ lập trình PHP cũng như các kiến thức liên quan đến loại ngôn ngữ này nhé!

Ngôn ngữ lập trình PHP là gì?

Ngôn ngữ PHP là từ viết tắt của Personal Home Page nay đã chuyển thành Hypertext Preprocessor. Thuật ngữ này là một dạng mã lệnh hoặc một chuỗi ngôn ngữ kịch bản được dùng để phát triển các ứng dụng web chạy trên máy chủ.

Khi các lập trình viên PHP viết chương trình, chuỗi lệnh sẽ được xử lý trên server sau đó sinh ra mã HTML trên client. Dựa vào đó, các ứng dụng trên website sẽ hoạt động một cách dễ dàng.

Ngôn ngữ lập trình PHP

Ngôn ngữ PHP thường được dùng trong việc xây dựng và phát triển website bởi nó có thể kết nối dễ dàng với các website khác có sử dụng HTML. PHP cũng là ngôn ngữ lập trình có mã nguồn mở, tương thích với nhiều nền tảng khác nhau như MacOS, Linux, Windows,… PHP được nhiều người dùng đánh giá là dễ đọc nên đa số các lập trình viên sẽ lựa chọn học PHP trước khi bắt đầu vào nghề.

  Những câu hỏi thường gặp khi đi phỏng vấn lập trình php

Ứng dụng của ngôn ngữ PHP trong lập trình

Ngôn ngữ lập trình PHP thường tập trung vào việc thiết lập chương trình cho máy chủ, tạo các cơ sở dữ liệu, xây dựng nội dung website, nhận dữ liệu cookie. Chưa hết, bạn còn có thể thực hiện được nhiều thao tác, công năng khác khi sử dụng ngôn ngữ này.

Một số ứng dụng phổ biến của PHP trong ngành IT:

  • Thiết lập chương trình cho hệ thống máy chủ: Đây là một ứng dụng chủ yếu nhất của PHP. Các PHP Developer sẽ phải thực hiện các thao tác như phân tích ngôn ngữ lập trình PHP, xây dựng máy chủ web và trình duyệt web.
  • Tạo các dòng tập lệnh: Các lập trình viên sẽ tạo ra một dòng tập lệnh để vận hành chương trình PHP mà không cần đến máy chủ. Kiểu lập trình này được sử dụng trên các hệ điều hành phổ biến như Linux hay Windows.
  • Xây dựng các ứng dụng làm việc: Bạn có thể ứng dụng những điểm mạnh vốn có của PHP để xây dựng ứng dụng phần mềm. Các lập trình viên thường dùng PHP – GTK làm nền tảng xây dựng phần mềm vì đây là nhánh mở rộng của ngôn ngữ lập trình này và không có sẵn trong các bản phân phối chính thức hiện nay.
  • Hỗ trợ cho mọi loại cơ sở dữ liệu khác nhau: Khi một website có hỗ trợ cơ sở dữ liệu tốt sẽ giúp ích cho việc vận hành, sao lưu và đặc biệt là backup dữ liệu đề phòng trường hợp xảy ra an ninh mạng.

Ưu nhược điểm của ngôn ngữ lập trình PHP

Ưu điểm

PHP được sử dụng phổ biến bởi nhiều lợi ích mà nó mang lại. Dưới đây là một số ưu điểm cơ bản của ngôn ngữ PHP:

  • Mã nguồn mở và miễn phí: PHP sử dụng miễn phí nên giúp tiết kiệm đáng kể ngân sách dự án. Việc cài đặt và sử dụng ngôn ngữ này cũng rất dễ dàng, bạn chỉ cần học chăm chỉ trong 3 – 6 tháng là đã có thể sử dụng thuần thục.
  • Tính linh hoạt: PHP là một ngôn ngữ đa nền tảng, có thể hoạt động trên bất kỳ hệ điều hành nào (Windows, Linux, macOS,…). Hơn nữa, PHP còn có thể kết hợp với nhiều ngôn ngữ lập trình khác để xây dựng các tính năng công nghệ một cách hiệu quả nhất.
  • Hệ thống thư viện phong phú, tính cộng đồng cao: Do sự phổ biến của ngôn ngữ PHP nên việc tìm các thư viện code hay hàm liên quan đến PHP sẽ cực kỳ đơn giản. Chưa kể, bạn sẽ nhận được sự trợ giúp từ các diễn đàn, đội nhóm chuyên sâu của PHP giúp việc học tập hay làm việc trở nên dễ dàng.
  • Cơ sở dữ liệu đa dạng: PHP cho phép kết nối với hầu hết các cơ sở dữ liệu khác như mySQL, SQLite, PostgreSQL, MS-SQL,…

ưu nhược điểm của ngôn ngữ lập trình php

Nhược điểm 

Mặc dù sở hữu nhiều lợi ích nhưng ngôn ngữ PHP vẫn có một số hạn chế nhất định, trong đó vấn đề bảo mật được nhiều người quan tâm nhất. Bởi bản chất của PHP có mã nguồn mở nên các lỗ hổng của mã nguồn sẽ bị công khai ngay sau khi chúng được tìm thấy. Và các lỗ hổng này có thể bị khai thác cho các mục đích xấu trước khi chúng ta kịp sửa chữa.

Bên cạnh đó, ngôn ngữ lập trình PHP chỉ hoạt động được trên các website và giao diện không được gọn gàng, đẹp mắt. Độ bảo mật và hiệu suất của ngôn ngữ này cũng chưa tốt.

Đừng bở lỡ việc làm PHP Hồ Chí Minh

Sự khác biệt giữa PHP với các ngôn ngữ lập trình khác

Ngôn ngữ lập trình PHP không chạy trên một trình duyệt mà chủ yếu tương thích với một máy chủ web. Nếu bạn mở một trang web bất kỳ, máy chủ sẽ chạy tập lệnh PHP được liên kết sau đó trả lại website cho bạn.

Với HTML: Ngôn ngữ này được dùng để tạo cấu trúc cơ bản của một trang web. Hầu hết các trang web hiện nay đều cần sử dụng ngôn ngữ này để xây dựng website.

Với CSS: Sử dụng với mục đích trang trí cho website thêm sinh động, đẹp mắt. Các lập trình viên sử dụng nhiều hiệu ứng khác nhau giúp website bạn trở nên ấn tượng và thu hút người dùng.

Với Javascript: Các lập trình viên sẽ sử dụng ngôn ngữ này đặt các phép tính, điều kiện khác nhau để kiểm tra khả năng phản ứng của website trong điều kiện thực tế.

Thu nhập của lập trình viên PHP là bao nhiêu?

Mức lương của các lập trình viên tại Việt Nam khá cao so với các ngành nghề khác. Nếu bạn là một lập trình viên PHP chưa có nhiều kinh nghiệm thì mức lương sẽ dao động từ 14 – 16 triệu đồng/tháng. Còn đối với những người đã trên 1 năm kinh nghiệm, mức lương trung bình có thể hơn 24 triệu đồng/tháng.

mức lương lập trình viên php

Có thể thấy, mức lương của nghề lập trình PHP là vô cùng hấp dẫn, bạn sẽ được trả lương rất cao nếu như thật sự có năng lực tốt. Các nhà tuyển dụng sẵn sàng bỏ ra số tiền lớn để chiêu mộ được nhân tài về lập trình PHP. Tuy nhiên, đây chỉ là mức lương để bạn tham khảo, mức lương này có thể tăng cao hơn hoặc thấp hơn tùy vào quy mô công ty, vị trí, yêu cầu công việc,…

Kết bài

Như vậy, bài viết này đã giúp bạn trả lời được câu hỏi ngôn ngữ lập trình PHP là gì và những kiến thức xoay quanh ngôn ngữ này. Với PHP bạn có thể dễ dàng xây dựng bất kỳ loại trang web nào một cách hiệu quả và nhanh chóng.

Nhu cầu tuyển lập trình viên PHP vẫn đang rất cao, mức thu nhập khá hấp dẫn. Nếu bạn quan tâm đến công việc này, hãy truy cập TopDev để lựa chọn cho mình công việc phù hợp nhé!

Xem thêm:

Kết nối DB ORACLE từ PHP trên CENTOS 7, 8

Thói quen viết code an toàn trong khi xây dụng ứng dụng PHP

Giới thiệu framework Vue.js

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

Trích xuất thông tin khác nhau từ hai Entity

trích xuất thông tin 2 entity

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

Trong quá trình phát triển các sản phẩm phần mềm, việc kiểm thử là bước vô cùng quan trọng. Không có kiểm thử thì phần mềm phát triển không đủ sự tin tưởng.

Hiện nay với sự phức tạp của các nghiệp vụ do đó các Entity trong các sản phẩm phần mềm ngày càng trở lên phức tạp :

  • Có rất nhiều trường (field) > 20 fields
  • Lưu trữ vật lý tại nhiều bảng khác nhau hoặc nhiều loại DB khác nhau
  • Cấu trúc của một Entity thường sẽ phức tạp: chứa nhiều object khác, array object,…

Khi viết iteration test thông thường chúng ta sẽ chỉ thực hiện assert cho một vài trường nghĩ là sẽ thay đổi sau khi gọi qua API điều này là đúng nhưng chưa đủ.

Ví dụ khi ta lập trình gọi API cho phép thay đổi giá của sản phẩm nhưng không may trong quá trình đó lại thực hiện cập nhật nhầm một thuộc tính nào đó như số lượng tồn kho. Việc này là rất nguy hiểm thường sảy ra khi code của project đã quá lớn và là người mới join vào quá trình phát triển chưa nắm rõ. Khi thực hiện testing nếu chỉ thực hiện việc assert cho trường giá thì vẫn chưa đủ.

Một cách dễ dàng có thể khắc phục là thực hiện compare toàn bộ 2 entity dưới dạng jsonExpected sẽ được query từ DBactual sẽ được lưu trong 1 file text. Nếu 2 object này giống nhau hoàn toàn thì có thể chắc chắn được API chúng ta đang hoạt động đúng.

Thư viện sử dụng có thể là:

        <dependency>
            <groupId>org.skyscreamer</groupId>
            <artifactId>jsonassert</artifactId>
            <version>1.5.0</version>
        </dependency>

Hoặc dùng chính project để thực hiện compare này.

Cách này khá dễ thực hiện nhưng sẽ có một số nhược điểm :

  • Khi ta thêm, xóa trường trong Entity thì tất cả các file json sẽ bị ảnh hưởng và bắt buộc phải thay đổi theo.
  • Khi đọc test thì người đọc sẽ rất khó biết được API thực sự thay đổi điều gì

Project này đề xuất phương pháp compare 2 json object, trích xuất sự khác biệt và lưu nó dưới dạng một cấu trúc json để dễ đọc hiểu.

Cấu trúc json được đề xuất như sau:

{
  "updated": {
  },
  "inserted" : {
  },
  "deleted": {
  }
}

Project sẽ sử dụng thuật toán DFS để duyệt qua và thực hiện compare 2 Json. Project sử dụng Json thay vì reflection vì Json sẽ dễ đọc hơn khi thực hiện lưu kết quả của compare.

  Kiểm thử ứng dụng Web – Ứng dụng Web là gì?
  Thực thi phương thức kiểm thử NUnit với Command Line

Chứa các field mang giá tri nguyên thủy, có thay đổi giá trị trước và sau updated.

Chứa các field mang giá trị là object hoặc array được thêm mới vào object

Các field mới xuất hiện tại object sau khi thực hiện action, trước đó object không tồn tại field này.

Chứa các field mang giá trị là object hoặc array được xóa đi trong object sau khi update

Chi tiết về cách sử dụng tham khảo các test được viết sẵn :

Ví dụ ta có object sau :

Entity trước khi thực hiện action.

{
  "employee":
  {
    "id": "1212",
    "fullName":"John Miles",
    "age": 35
  },
  "dem" : 16
}

Entity sau khi thực hiện action

{
  "employee": {
    "employId": "12122",
    "fullName": "John 1",
    "age": 35,
    "contact": {
      "email": "john@xyz.com",
      "phone": "9999999"
    }
  }
}

Sau khi thực hiện compare sẽ được kết quả như sau :

 var diffJson = new DDiffJsonBuilder()
                .insertBuilder( new InsertObjectBuilder())
                .updateBuilder(new UpdateObjectBuilder())
                .deleteBuilder(new DeleteFlattenKeyBuilder())
                .build();

diffJson.diffScan(beforeObject, afterObject);

var output = diffJson.toJsonFormatString();
{
  "updated": {
    "employee": {
      "fullName": "John 1"
    }
  },
  "inserted": {
    "employee": {
      "employId": "12122",
      "contact": {
        "email": "john@xyz.com",
        "phone": "9999999"
      }
    }
  },
  "deleted": {
    "employee.id": 1,
    "dem": 1
  }
}

Với Object nhỏ thì việc thực hiện chạy qua DiffJson thì không nhận thấy được ưu điểm nhưng nếu là một Object lớn và phức tạp, khi thực hiện API chỉ thay đổi vài trường thì sẽ thấy được lợi ích.

Tìm ngay việc làm Tester Hồ Chí Minh HOT tại TopDev!

2.3. Exclude fields

Khi thực hiện API có một số trường chúng ta không muốn compare như updated timestamp, trường timestamp này có thể có ở tất cả object nên việc loại trừ được các trường này cũng rất cần thiết.

Before Object :

{
  "employee":
  {
    "id": "1212",
    "updateTime" : 132245124312,
    "fullName":"John Miles",
    "age": 35
  },
  "dem" : 16,
  "createTime" : 12412412412
}

After Object :

{
  "employee": {
    "employId": "12122",
    "fullName": "John 1",
    "updateTime" : 13225124312,
    "age": 35,
    "contact": {
      "email": "john@xyz.com",
      "phone": "9999999"
    }
  },
   "createTime" : 1241312412
}

Code excludes timestamp

JsonNode beforeObject = DJacksonCommon.loadJsonFromFile("before_timestamp.json");
        JsonNode afterObject = DJacksonCommon.loadJsonFromFile("after_timestamp.json");
        var diffCompare = new DDiffJsonBuilder()
                .insertBuilder( new InsertObjectBuilder())
                .updateBuilder(new UpdateObjectBuilder())
                .excludeCompareFieldPath("createTime")
                .excludeCompareFieldPath("employee.updateTime")
                .deleteBuilder(new DeleteFlattenKeyBuilder())
                .build();

        diffCompare.diffScan(beforeObject, afterObject);

        String output = diffCompare.toJsonFormatString();
        System.out.println(output);

Output Object :

{
  "updated": {
    "employee": {
      "fullName": "John 1"
    }
  },
  "deleted": {
    "employee.id": 1,
    "dem": 1
  },
  "inserted": {
    "employee": {
      "employId": "12122",
      "contact": {
        "email": "john@xyz.com",
        "phone": "9999999"
      }
    }
  }
}

Một tính năng nữa của DDiff là có thể xác định được object nào đã bị xóa, thêm vào, update trong json array

Before Object :

{
  "plants": [
    {
      "plantId": "1",
      "name": "plant1"
    },
    {
      "plantId": "2",
      "name": "plant2"
    },
    {
      "plantId": "3",
      "name": "plant3"
    }
  ],
  "demtv": 11
}

After Object :

{
  "plants": [
    {
      "plantId": "1",
      "name": "plant11"
    },
    {
      "plantId": "3",
      "name": "plant3"
    },
    {
      "plantId": "4",
      "name": "plant4"
    }
  ],
  "demtv": 11
}

Code for object have array:

        JsonNode beforeObject = DJacksonCommon.loadJsonFromFile("array_json_sample/before_have_array_plant.json");
        JsonNode afterObject = DJacksonCommon.loadJsonFromFile("array_json_sample/after_have_array_plant.json");

        diffJson.registerObjectKeyInArrayByPath("plants","plantId");
        diffJson.diffScan(beforeObject, afterObject);

        String output = diffJson.toJsonFormatString();

Output Object :

{
  "updated": {
    "plants": [
      {
        "plantId": "1",
        "name": "plant11"
      }
    ]
  },
  "inserted": {
    "plants": [
      {
        "plantId": "4",
        "name": "plant4"
      }
    ]
  },
  "deleted": {
    "plants.plantId.2": 1
  }
}

3. Tổng kết

Các cách dùng kỹ hơn về thư viện này vui lòng tham khảo tại thư mục test. Test của Project đạt đến 83% line vậy nên có thể tin tưởng để sử dụng.

Bài viết gốc được đăng tải tại demtv.hashnode.dev

Xem thêm:

Hàng loạt việc làm IT hấp dẫn trên TopDev đang chờ bạn ứng tuyển.

Hướng dẫn xây dựng chức năng thay đổi avatar người dùng WordPress

Hướng dẫn xây dựng chức năng thay đổi avatar người dùng WordPress

Bài viết được sự cho phép của tác giả Võ Quang Huy

Chào mọi người! Ở trong bài viết trước mình đã hướng dẫn các bạn xây dựng được trang thông tin người dùng. Trong bài viết này, mình sẽ hướng dẫn các bạn code thêm chức năng thay đổi avatar người dùng WordPress.

Chức năng upload hình ảnh

Khi người dùng muốn thay đổi hình ảnh đại diện, thì trước tiên người dùng phải upload được hình ảnh.

Bạn hãy thêm đoạn code upload hình ảnh dưới đây của mình vào file functions.php của theme bạn nhé.

Bạn có thể đọc qua đoạn và tìm hiểu trên tài liệu của WordPress các hàm mình đã sử dụng.

Nếu bạn không hiểu, bạn chỉ cần quan tâm function trên sẽ hỗ trợ người dùng upload hình ảnh ở bên ngoài giao diện. Và giá trị trả về của function trên là một array gồm:

  • url: Đường dẫn của hình ảnh sau khi đã được tải lên thư viện media của WordPress
  • id: ID của hình ảnh
  Hướng dẫn viết theme WordPress toàn tập - phần 1
  Chia sẻ kinh nghiệm sử dụng trình duyệt web an toàn

Tạo trang thay đổi avatar người dùng

Phần này sẽ giống như những bài viết trước trong series Custom tài khoản WordPress. Mình sẽ tạo một page có tiêu đề là Thay đổi avatar và đường dẫn là domain/thay-doi-avatar. Sau khi tạo page xong mình sẽ tạo một file PHP trong theme của mình có tên là page-thay-doi-avatar.

Sau khi hoàn thành các bước trên, các bạn hãy copy đoạn code dưới đây vào file PHP các bạn vừa mới tạo nhé.

Đây là giao diện các bạn sẽ nhận được khi sử dụng đoạn code trên. Bạn có thể sử dụng CSS để thay đổi lại sao cho đẹp hơn tuỳ vào bạn nhé.

Như mọi khi, mình đang sử dụng theme twentytwenty nên giao diện có thể sẽ khác bạn. Đừng lo lắng nhé.

giao diện thay đổi avatar người dùng

Giải thích một chút

Giống như các bài viết cũ. Ở đây mình cũng sử dụng câu lệnh điều kiện ở dòng 7 để kiểm tra người dùng đã đăng nhập chưa. Và ở dòng 19, mình vẫn tiếp tục sử dụng hàm wp_nonce_field với mục đích bảo mật.

Ở dòng 24, mình sử dụng hàm wp_get_current_user để lấy ra được thông tin của người dùng hiện tại đang đăng nhập. Từ đó mình sẽ lấy đựa ID người dùng và truyền vào trong hàm get_avatar_url. Hàm này sẽ trả về địa chỉ URL avatar mặc định của người dùng ở dòng 29.

Còn ở dòng 25, mình sẽ sử dụng một hàm đó là get_user_meta. Hàm này sẽ trả về một dữ liệu mà mình sẽ tạo ở phần tiếp theo, cụ thể mình sẽ tạo một user meta mới để lưu trữ URL avatar mà người dùng đã upload.

Từ dòng 26 đến 30 là mình sẽ dùng câu lệnh if else kiểm tra xem người dùng đã upload dữ liệu avatar mới chưa? Nếu chưa up thì sẽ hiển thị avatar mặc định của WordPress.

Còn lại chỉ là các thẻ HTML cơ bản. Các bạn có thể thay đổi lại layout cho phù hợp nhé.

Gửi dữ liệu lên server

Sau khi người dùng chọn ảnh từ máy tính và xác nhận, thì chúng ta phải gửi hình ảnh đó lên server. Như những bài viết trước, mình sẽ sử dụng AJAX để xử lý việc này. Nếu các bạn chưa tìm hiểu qua AJAX là gì thì có thể thao khảo các bài viết AJAX trong WordPress nhé.

Đoạn code dưới đây sẽ hỗ trợ bạn gửi dữ liệu lên server bằng AJAX. Hãy thêm vào file footer.php của theme bạn, nếu đã khai báo jQuery rồi thì xoá dòng đầu tiên đi.

Đừng bỏ lỡ việc làm Front-End hấp dẫn trên TopDev!

Xử lý dữ liệu trên server

Khi dữ liệu đã gửi lên server, thì tiếp theo chúng ta phải xử lý chúng. Các bạn hãy thêm đoạn code bên dưới đây vào file functions.php nhé.

Giải thích một chút

Đầu tiên mình sẽ khai báo 3 biến. $file_upload là biến mình dùng để nhận file mà người dùng đã upload lên server. $user_id là biến mình dùng để lấy được ID của người dùng hiện tại dang đăng nhập. Ở đây mình sử dụng hàm get_current_user_id để làm điều đó. Còn biến $avatar_data sẽ là một mảng, nó sẽ nhận giá trị trả về của chức năng upload hình ảnh mà mình đã đề cập ở phần đầu tiên.

Ở dòng 7 sau khi mình kiểu tra biến $file_upload tồn tại và có giá trị, thì mình sẽ gán dữ liệu đã nhận được từ hàm mình đã viết là hk_user_upload_image vào biến $avatar_data.

User meta là gì?

Để các bạn có thể hiểu sâu hơn, mình sẽ giải thích về user meta một chút. Mặc định profile của người dùng sẽ có các trường dữ liệu như Họ, Tên, Tên hiển thị, Trang web, Tiểu sử,… Tuy nhiên nếu bạn muốn thêm các trường dữ liệu mới cho người dùng thì phải làm thế nào? Lúc này các trường dữ liệu mới cho người dùng được gọi là user meta.

Bạn có thể thêm một user meta mới bằng hàm add_user_meta. Cập nhập lại user meta bằng hàm update_user_meta. Và lấy giá trị của user meta ra sử dụng bằng hàm get_user_meta. User meta sẽ là một cặp meta_key và meta_value. Với meta_value sẽ lưu trữ giá trị dựa trên meta_key.

Áp dụng user meta

Ý tưởng của mình là sẽ tạo một user meta mới có key là custom_avatar, và custom_avatar này sẽ truyền vào giá trị là địa chỉ URL của hình ảnh mà người dùng đã tải lên.

Từ dòng 12, mình sẽ kiểm tra xem custom_avatar đã tồn tại chưa? Nếu đã tồn tại rồi thì mình sẽ sử dụng hàm update_user_meta để cập nhập lại dữ liệu. Nếu chưa tồn tại thì mình sẽ tạo một user meta mới, có key chính là custom_avatar để lưu trữ giá trị URL hình ảnh mà người dùng đã upload.

Vì khi gửi dữ liệu lên server mình dùng dataType là json. Nên cuối cùng mình sử dụng hàm wp_send_json_success để trả về dữ liệu cho phía client.

Thay đổi avatar mặc định của người dùng WordPress

Mặc định WordPress sử dụng Gravatar để cho phép người dùng cập nhập avatar. Mình không phủ nhận sự tiện lợi của Gravatar nhưng không phải người dùng nào cũng biết và sử dụng nó.

Để thay đổi avatar mặc định của WordPress thành avatar mà người dùng đã upload, bạn hãy thêm đoạn code dưới đây vào file functions.php

Đây là kết quả mà bạn sẽ nhận được tại giao diện quản trị của WordPress. Hình ảnh người dùng sẽ được thay đổi dựa trên upload của họ.

custom avatar admin wordpress

Lời kết

Vậy là bài viết của mình đã kết thúc rồi. Đây là một chủ đề theo mình nghĩ là khá phức tạp. kết hợp nhiều kiến thức lại với nhau.

Hy vọng rằng qua bài viết này các bạn có thể hiểu được và tự code được cho mình một tính năng tương tự như vậy. Không chỉ dừng lại ở việc upload ảnh đại diện cho người dùng, mà có thể là upload ảnh cho bất kì nơi nào, tuỳ thuộc vào nhu cầu hoặc ý tưởng của bạn.

Nếu bạn đang tìm kiếm cơ hội việc làm, hãy tham khảo ngay việc làm IT mọi cấp độ trên TopDev nhé!

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

Xem thêm:

Tạo kho lưu cho các gói thư viện Python

tạo kho lưu cho thư viện python

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

Python là ngôn ngữ chính cho hệ thống backend của AgriConnect. Với đội ngũ giàu kinh nghiệm về Python, luôn đẩy sự khai thác, “bóc lột” Python đến mức cao nữa, cao nữa, nên quá trình vận hành của AgriConnect thường dẫn đến những nhu cầu “không giống ai”. Một trong số đó là nhu cầu dựng một kho chứa gói thư viện Python “tại nhà”. Bài dưới đây xin chia sẻ kinh nghiệm như thế.

Khi hệ thống của AgriConnect vận hành, tác vụ cài đặt các gói thư viện Python được thực hiện lặp đi lặp lại rất nhiều lần. Chúng đến từ:

  • Hệ thống chạy test tự động, kích hoạt mỗi khi có code mới được đẩy lên Git.
  • Việc deploy bản cập nhật đến các server nội bộ đặt rải rác ở các trang trại khách hàng.

Đa số các máy mà quá trình cài đặt thư viện Python diễn ra, đều nằm ở Việt Nam, nên việc để pip kéo phần mềm từ kho chính thức của Python (https://pypi.org/) làm tôi thấy chưa được tối ưu. Không những phí thời gian truyền tải (đường xa), làm chật chội đường truyền đi ra nước ngoài mà còn tạo áp lực lên hạ tầng của PyPI. Tôi không muốn tạo gánh nặng về chi phí bảo trì lên họ, khi tôi đã được sử dụng dịch vụ miễn phí của họ. Ngoài ra còn có một lý do thiết thực khác là nhu cầu về sự đa dạng nền tảng cần hỗ trợ, ví dụ:

  • Quá trình test tự động, được chạy trong các Docker container, build từ Alpine Linux. Khác với các bản Linux phổ biến khác (Ubuntu, RedHat v.v..), bản Linux này sử dụng thư viện chuẩn C musl. Các gói thư viện Python build sẵn (dưới dạng file *.whl) có trên PyPI đều dành cho thư viện chuẩn C glibc nên không sử dụng được. Nếu build lại từ source trong container luôn thì cực tốn thời gian. Một host riêng là cần thiết để chứa các gói build sẵn này, nhưng dành cho musl.
  • Cloud server phục vụ các khách hàng không có nhu cầu dùng server nội bộ. Server này dùng Ubuntu thông thường nên không có vấn đề gì.
  • Các server nội bộ triển khai cho khách hàng, sử dụng BeagleBone, một loại máy tính Linux nhúng với CPU ARM. Phần lớn các gói thư viện Python build sẵn trên PyPI cũng đều không có bản dành cho ARM. Build các gói ngay trên BeagleBone, trong lúc deploy, là việc không thể, đơn giản vì quá tải (Tôi phải thuê server bare metal với CPU ARM từ Scaleway để làm công đoạn build, trước khi phân phối đến các board nhúng này).
  Sự khác nhau giữa Method và Function trong Python

Trước đây tôi tận dụng một số dịch vụ cloud, để chứa các gói Python này. Các dịch vụ gồm có: PackageCloudGemfuryCloudSmith. Ưu điểm của chúng:

  • Nhanh gọn, không phải setup server này nọ. Đăng ký là dùng được ngay thôi. Tất nhiên vẫn cần cài phần mềm client để upload gói lên.
  • Giao diện Admin để quản lý các gói (đang chứa các gói nào, phiên bản bao nhiêu, dành cho nền tảng nào, nội dung bên trong gồm file gì).
  • Có tài khoản miễn phí

Thế nhưng dần dần tôi thấy những dịch vụ kia vẫn còn trở ngại nhỏ:

  • PackageCloud có giới hạn dung lượng download mỗi tháng cho tài khoản miễn phí, và với hoạt động của AgriConnect thì chúng hết rất nhanh.
  • Gemfury không cho chia nhỏ các kho ra. Mỗi tài khoản chỉ có một kho để tống hết tất cả các gói vào, không tiện quản lý. Mỗi lần upload một gói mới lên (không trùng tên với gói đã có) thì phải vào website để chuyển gói đó sang chế độ public.
  • CloudSmith tốc độ upload gói rất chậm, khi upload một gói trùng với phiên bản đã có trên kho thì nó coi là lỗi và hiện rất nhiều báo lỗi trên trang quản lý.

Nên tôi quyết định tận dụng các server sẵn có (hầu hết đặt trong nước) đề làm kho lưu luôn.

  Flask python là gì? - Những điều cần biết

Tôi không có nhu cầu setup một trang với chức năng đầy đủ, y xì như PyPI. Cái tôi cần là:

  • Setup nhanh, không cần tạo database, người dùng, xác thực.
  • Upload bằng công cụ dòng lệnh sẵn có (ví dụ scplftp).
  • Có thể upload cùng lúc nhiều file (công cụ của CloudSmith không có chức năng này nên tôi phải dùng mẹo, kết hợp với fd-find).

Sau một lúc rà qua các phần mềm khác nhau thì tôi thấy dumb-pypi gần với ý đồ của tôi nhất. Đặc điểm của dump-pypi:

  • Dùng phương thức host file tĩnh để phục vụ download các gói. Điều đó có nghĩa tôi chỉ cần một web server thông thường, như Nginx. Chỉ đối xử các gói như file tĩnh nên không cần ngôn ngữ lập trình gì hết (không cần chạy một trang PHP chẳng hạn).
  • Để tạo một trang danh sách các gói mà pip có thể hiểu được thì dump-pypi sẽ giúp sinh ra một trang HTML tĩnh. Không cần có một trang web động, ví dụ PHP, để sinh ra danh sách này.
  • Vì chỉ host file tĩnh nên chỉ cần dùng bất cứ công cụ nào để upload file lên server, đặt vô đúng thư mục. Tức là tôi có thể dùng scp, tận dụng SSH để xác thực.

Chỉ có điều, trái với mong đợi của tôi, cách setup ban đầu của nó không nhanh tí nào. Lí do là tác giả ưu tiên tình huống lưu file trên S3 nên tài liệu tập trung vào nó hơn. Hướng dẫn với Nginx thì sơ sài, thậm chí cũ, chẳng biết dành cho Nginx đời nào mà đem cho Nginx mới (trên Ubuntu 19+) thì bị báo lỗi. Đó là lí do tôi phải ghi ra bài này.

Tham khảo việc làm Python Hồ Chí Minh hấp dẫn!

Giả sử tôi dùng thư mục /srv/PyPI làm kho lưu các gói. Do nhu cầu “hỗ trợ đa nền tảng” ở trên mà trong thư mục này tôi lại chia ra thêm 2 thư mục con:

  • glibc: Dành cho các gói *.whl được build cho hệ thống nào dùng glibc làm thư viện C chuẩn. Áp dụng cho cả CPU x86_64 và armhf.
  • musl: Dành cho các gói *.whl được build cho hệ thống nào dùng musl làm thư viện C chuẩn, tức là trong Docker container. Chỉ cần tương thích CPU x86_64.

Do tên các gói của Python không phân biệt - và _ nên ta phải cấu hình cho Nginx sao cho khi pip yêu cầu gói vietnam_provinces thì Nginx vẫn trả về vietnam-provinces. Để thực hiện được tính năng này thì ta sẽ viết một hàm Lua ngắn phụ trợ cho Nginx. Trước tiên, cần cài module Lua cho Nginx. Trên Ubuntu/Debian thì cài bằng lệnh sau:

sudo apt install libnginx-mod-http-lua

Tạo một file cấu hình virtual host cho Nginx. Ví dụ, trên Ubuntu thì tạo file /etc/nginx/sites-available/pypi.conf với nội dung như sau:

server {
    server_name pypi.agriconnect.vn;

    root /srv/PyPI;
    index index.html;
    sendfile on;
    autoindex on;

    location / {
        set_by_lua_block $canonical_uri {return string.gsub(string.lower(ngx.var.uri), '[-_.]+', '-')}
        try_files $uri $uri/index.html $uri/ $canonical_uri $canonical_uri/index.html =404;
    }

    location ~*  /.+/json$ {
        default_type "application/json; charset=utf-8";
    }

    listen 80;
    listen 443 ssl http2;
    ssl_certificate /etc/letsencrypt/live/pypi.agriconnect.vn/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/live/pypi.agriconnect.vn/pypi.agriconnect.vn.key;
}

Lưu ý rằng cấu hình này cũng bật HTTPS cho kho lưu của chúng ta (ví dụ pypi.agriconnect.vn), không thì sẽ phải nghe pip càm ràm khi tải gói qua HTTP trần.

Trong mỗi thư mục trên, ta lại sẽ bố trí các file như sau:

/srv/PyPI/glibc$ tree -L 1
.
├── gen.sh
├── packages/
├── packages.txt

Trong đó thư mục packages là nơi ta sẽ upload các file *.whl lên. File gen.sh là script mà ta sẽ chạy để sinh ra cấu trúc thư mục tương tự nhìn thấy trên PyPI qua con mắt của pip, để nó biết có thể download được gói nào từ server này.

Nội dung của gen.sh như sau:

#!/bin/sh

dumb-pypi --package-list packages.txt --packages-url ../../packages --output-dir .

Không biết vì lý do gì mà tác giả của dumb-pypi không cho nó tự nhìn vào thư mục packages để tự lập danh sác các gói, mà phải nhận đầu vào là một file chứa sẵn danh sách các gói, là file packages.txt. Mặc dù dumb-pypi hơi ngu (đúng với cái tên dumb) nhưng ta có thể sinh ra file đó rất dễ dàng như sau:

$ cd packages
$ ls > ../packages.txt

Mỗi lần upload gói mới, ta sẽ cần tạo lại file packages.txt, chạy lại ./gen.sh để sinh ra các thư mục như sau:

$ broot
/srv/PyPI/glibc
├──gen.sh
├──index.html
├──packages
│  ├──asyncpg-0.18.3-cp37-cp37m-linux_armv7l.whl
│  ├──Brotli-1.0.7-cp37-cp37m-linux_armv7l.whl
│  ├──cchardet-2.1.5-cp37-cp37m-linux_armv7l.whl
│  ├──cffi-1.13.2-cp37-cp37m-linux_armv7l.whl
│  └──60 unlisted
├──packages.txt
├──pypi
│  ├──aiohttp …
│  ├──asyncpg …
│  ├──brotli …
│  ├──cchardet …
│  ├──cffi …
│  └──30 unlisted
└──simple
   ├──aiohttp …
   ├──asyncpg …
   ├──brotli …
   ├──cchardet …
   ├──cffi …
   └──32 unlisted

Từ đây trở đi, mỗi lần sử dụng pip, ta thêm tham số như sau:

pip install --extra-index-url=https://pypi.agriconnect.vn/glibc/simple

thì pip sẽ ưu tiên dò tìm và tải gói từ kho riêng của chúng ta.

Nếu ta không trực tiếp dùng pip, mà quản lý gói phụ thuộc bằng công cụ khác, như Poetry chẳng hạn, thì ta truyền cấu hình kho riêng qua biến môi trường, ví dụ:

export PIP_EXTRA_INDEX_URL=https://pypi.agriconnect.vn/glibc/simple
poetry add asyncpg
poetry install --no-root

Hình ảnh cho thấy pip đang download gói từ kho riêng:

pip_custom_repo

Nhân đây, pypi.agriconnect.vn là một địa chỉ kho thật và bạn có thể dùng chung nó với chúng tôi (chỉ được download thôi nhé) nếu có cùng đam mê với Python.

Cập nhật

Để đỡ công nhảy ra nhảy vào tạo danh sách gói, có thể đưa bước đó vào script gen.sh như sau:

#!/bin/bash

pushd packages
ls > ../packages.txt
popd
rm -rf pypi simple
dumb-pypi --package-list packages.txt --packages-url ../../packages --output-dir .

Hy vọng qua bài viết này sẽ giúp bạn biết cách tạo kho lưu cho các gói thư viện Python. Đừng quên truy cập Topdev để cập nhật các tin tuyển dụng IT mới nhất bạn nhé!

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