Home Blog Page 148

Tại sao code của tôi thường ngắn gọn như vậy

Tại sao code của tôi thường ngắn gọn như vậy

Bài viết được sự cho phép của tác giả Phạm Công Sơn

Cho đến nay tôi đã làm Coder cũng phải được 12, 13 năm. Bắt đầu đi code từ năm 2007 (Trong năm này tôi đã cưới vợ và sinh ngay một đứa con trai). Tuổi đời coder cũng tạm gọi là dài. Năm nay cũng 38 tuổi rồi, nếu so sánh với một cầu thủ bóng đá chuyên nghiệp thì có lẽ nghỉ hưu cũng đã từ lâu. Vậy mà mình vẫn còn miên man code và code, bug và bug.

  "Code dễ đọc" là như thế nào?

  "Mẹo bỏ túi" cho dân coder mới vào nghề

Skill chủ yếu vẫn là C#JqueryAsp.NetSql Server v.v… Và sau nhiều năm coder như vậy tôi có rất nhiều kinh nghiệm. So với những ngày đầu code một cách vô ý thức, bạ đâu code đó thì giờ đây cách code cũng đã thay đổi rất nhiều và với mỗi yêu cầu tôi thường phân tích kỹ, code sử dụng design pattern và code trừu tượng trước khi làm cụ thể một trường hợp nào đó.

Người ta thì sự nghiệp đầy đủ rồi mới lập gia đình. Còn tôi thì hơi ngược, năm 2007 là tôi chính thức bắt đầu đi làm sau khi cưới vợ. Lương tại thời điểm đó là 1 củ rưỡi. Và vào làm vẫn với tâm thế vừa làm vừa học hỏi. Tâm lý chung của các bạn mới ra trường thôi.

Hồi đó chủ yếu có mấy xu hướng, mấy đứa lập trình chỉ có hỏi nhau mày làm php, dotNet hay Java. Tôi từ FPT APTECH ra, cũng có học Java nhưng sau đó theo hẳn dotNet làm winform hoặc web asp.net. Vào công ty đập ngay dự án về winform, thấy cũng may mắn vì được học cái gì và làm luôn cái ấy. Trưởng dự án giao cho làm mấy Form danh mục như quản lý danh mục sản phẩm, loại sản phẩm. Cảm nhận đầu tiên là nó chả khác gì lúc đi học cả. Cũng tạo Form, kéo thả các input, button, viết sự kiện, truy xuất DataBase và lưu trữ. Và mấy Form sau thì copy nội dung của Form trước. Điều khác biệt mà lúc đó thấy “hay dữ” đó là có cái tool gen được ra các Entity có sẵn mấy hàm Insert, Update, Delete, còn sau đó trên Form có thêm xử lý gì thì tự viết hàm truy xuất. Thế thôi nhưng cũng thấy hay vãi đ* ra rồi. Và nghĩ đúng là đi làm nó khác.

Sau khi dự án làm bằng Winform kết thúc, tôi chuyển sang làm một dự án về WebFormfrown Cái này mình cũng được học và làm Project rồi nên cũng rất tự tin. Tuy vậy lúc mới bắt tay vào dự án cũng làm mấy danh mục trước tiên. Điều khác so với dự án trước là ông Leader ông ý có làm sẵn một Form danh mục rồi. Và ông ý bảo anh em nào được giao làm Form nào thì vào copy ra mà làm các form tương tự. smileyThế đấy, và hàng loạt các Form được sao chép nhau, có Form nào logic nó khác hoặc cần chỉnh thì viết thêm. Vậy mà cũng qua được mấy cái dự án.

Sau đó tôi chuyển tới một số công ty khác và đa số các công ty đều có cách làm việc như vậy. Nếu như các Module, Form nào na ná nhau. Mọi người đều copy lại và chỉnh sửa sao cho phù hợp. Không chỉ những Form quản lý mà còn nhiều các Form khác ví dụ như báo cáo. Code của dự án nào cũng khá là nặng. Và có một nhược điểm là nếu Form nào mà có lỗi thì hầu như phải chỉnh sửa lại ở tất cả các Form. Và cần thêm tính năng nào thì cũng phải mở từng đấy Form ra mà thêm.

Chính vì vậy đa số nhiều lập trình viên sau một thời gian đi làm cũng thường kêu là không có gì mới mẻ, làm đi làm lại một việc. Công việc hầu như không có sáng tạo. Đấy là cái tôi thấy, hầu như code không có thiết kế, không sử dụng design pattern và không tận dụng được tính chất OOP để kế thừa, đóng gói. Các hàm, biến static được sử dụng tràn lan vô tội vạ, code thì copy và không được viết thành thư viện.

Hãy thiết kế code, sử dụng design pattern, code trừu tượng trước khi đi vào cụ thể.

Quay trở lại các dự án thường chúng ta hay phải làm các danh mục trong đó có các tính năng như tìm kiếm, thêm, sửa, xóa, xuất excel. Form nào các bạn cũng phải làm một lưới hiển thị, làm sự kiện thêm mới, sửa, validate dữ liệu khi lưu, sự kiện xóa. Form nào cũng từng đấy bước không thể khác được.

Tôi ví dụ như làm một Form quản lý danh mục tin. Đây chỉ là ví dụ mô phỏng thôi nhé. Ta có thể có đoạn code như sau

public class ManageCategory
{
    public void ShowFormEdit(Category category)
    {
        // Hiển thị form cập nhật hoặc thêm mới
    }
    
    public void Save(Category category)
    {
        // Validate trước khi lưu
        // Thực hiện lưu
    }
    
    public void Delete(Category category)
    {
        // Validate xóa
        // Thực hiện xóa
    }
    
    // Lấy dữ liệu hiển thị lên lưới
    public string Keyword { set; get; }
    public List<Category> GetData(int pageIndex, int pageSize, string fieldOrder, string dir)
    {
        // ....
    }
    
    public void ExportExcel(List<Category> categories)
    {
        // Điền vào excel cho client tải xuống
    }
}

Rồi một Form quản lý loại sản phẩm

public class ManageProductType
{
    public void ShowFormEdit(ProductType productType)
    {
        // Hiển thị form cập nhật hoặc thêm mới
    }
    
    public void Save(ProductType productType)
    {
        // Validate trước khi lưu
        // Thực hiện lưu
    }
    
    public void Delete(ProductType productType)
    {
        // Validate xóa
        // Thực hiện xóa
    }
    
    // Lấy dữ liệu hiển thị lên lưới
    public string Keyword { set; get; }
    public List<ProductType> GetData(int pageIndex, int pageSize, string fieldOrder, string dir)
    {
        // ....
    }
    
    public void ExportExcel(List<ProductType> productTypes)
    {
        // Điền vào excel cho client tải xuống
    }
}

Như các bạn thấy thì Form nào chúng ta cũng phải làm từng đấy bước. Mà đấy là code server, chưa kể code javascript cũng vậy. Các Form mà cứ code đi code lại như vậy hoài rất mất công và sinh ra chán. Lúc gặp lỗi hoặc thêm chức năng thì Form nào cũng phải vọc vào mà sửa.

Vậy bây giờ chúng ta hãy nghĩ khác đi. Trừu tượng nó thành như này

public abstract class Manage<T>
{
    public void ShowFormEdit(T t)
    {
        // Hiển thị form cập nhật hoặc thêm mới
    }
    
    public void Save(T t)
    {
        // Validate trước khi lưu

        BeforeSave();
        // Thực hiện lưu
    }

    protected virtual void BeforeSave(T t)
    {
        
    }
    
    public void Delete(T t)
    {
        // Validate xóa
        // Thực hiện xóa
    }
    
    // Lấy dữ liệu hiển thị lên lưới
    public vitural List<T> GetData(int pageIndex, int pageSize, string fieldOrder, string dir)
    {
        // ....
    }
    
    public void ExportExcel(List<T> list)
    {
        // Điền vào excel cho client tải xuống
    }
}

Và nếu là quản lý chuyên mục tin sẽ là như này

public class ManageCategory : Manage<Category>
{
    public string Keyword { set; get; }
}

Nếu là quản lý loại sản phẩm

public class ManageProductType : Manage<ProductType>
{
    public string Keyword { set; get; }

    protected override void BeforeSave(ProductType productType)
    {
        // Mở rộng validate thêm
    }
}

Chúng ta sẽ không phải code một lần mà lại phải code thêm một lần nữa. Bug ít đi, thêm tính năng cũng sẽ nhanh hơn. Để phát triển, tại lớp Generic các bạn có thể đặt sự kiện, phương thức virtualabstract để các lớp cụ thể override lại. Ví dụ như ManageProductType override lại BeforeSave để viết thêm validate

Tuy vậy để code được trừu tượng các bạn sẽ phải có nhiều kỹ năng và các kiến thức cơ bản là cực kỳ cần thiết. Và với tùy theo các Framework các bạn đang theo các bạn có thể viết các mô hinh cho phù hợp. Trên đây chỉ là code ví dụ mà thôi.

Ngoài ra không chỉ làm những Form quản lý danh mục mà chúng ta có thể mở rộng ra nhiều bài toán khác nhau. Với tôi sau nhiều năm kinh nghiệm, tôi đã làm nhiều yêu cầu với nhiều mô hình khác nhau. Tuy nhiên cũng có một vài lần làm trừu tượng với những yêu cầu lớn. Điển hình như tôi tham gia dự án Staxi (Một sản phẩm đặt xe tương tự như Grab, Uber), mô hình trừu tượng một khối kết nối. Từ đó kế thừa tạo ra các khối như tổng đài, server, App Client, mỗi mỗi khối có nhiệm vụ nhận, và truyền tín hiệu. Rồi dự án phân tích dữ liệu từ hộp đen. Cũng trừ tượng mô hình phân tích để kế thừa cho phân tích dữ liệu cho Taxi, Bus và Xe vận tải. Và rất nhiều dự án khác. Tôi sẽ chia sẻ trong những lần tới.

Hiện với cách code này tôi đang áp dụng cho dự án của tôi, chắc chắn sẽ publish dự án trong một ngày sớm nhất vì tôi còn đang hoàn thiện.

Tôi cũng show cho anh em xem một Form tôi đã thực hiện trong dự án: Quản lý tỷ giá ngoại tệ. Form này khá đơn giản

Tại sao code của tôi thường ngắn gọn như vậy

Đây là định nghĩa Entity, có Attribute validate trên mỗi thuộc tính. DataSource để lấy dữ liệu hiển thị trên lưới

Tại sao code của tôi thường ngắn gọn như vậy

Nội dung Html định nghĩa lưới hiển thị dữ liệu. Nút xóa gọi hàm Delete, có confirm khi xóa. Click vào tỷ giá gọi Hàm Edit hiển thị Form cập nhật

Tại sao code của tôi thường ngắn gọn như vậy

Toàn bộ nội dung của Form kế thừa tới ManageModule trong đó đã có toàn bộ các chức năng

Tại sao code của tôi thường ngắn gọn như vậy

Nội dung của Form cập nhật gồm các Input cần thiết

Tại sao code của tôi thường ngắn gọn như vậy

Nội dung file js định nghĩa đã bao gồm toàn bộ thao tác trên lưới.

Trên đây là toàn bộ code cho một Form quản lý. Còn đây là kết quả

Tại sao code của tôi thường ngắn gọn như vậy

Đây là lưới hiển thị dữ liệu.Trên lưới có chức năng tìm kiếm, sắp xếp, xóa, sửa, thêm mới, cấu hình cột, xuất excel

Tại sao code của tôi thường ngắn gọn như vậy

Click vào thêm mới hoặc một dòng sẽ hiển thị Form cập nhật. Trên Form có sẵn các nút lưu

Tại sao code của tôi thường ngắn gọn như vậy

Form có sẵn chức năng giới thiệu tính năng

Tại sao code của tôi thường ngắn gọn như vậy

Có thể cấu hình cột được hiển thị theo ý muốn người dùng

Như vậy với code ngắn gọn như trên tôi đã có một Form nhập liệu đầy đủ mọi tính năng. Và như các bạn thấy. Tôi vừa thêm chức năng phím nóng được giới thiệu ở bài viết Hướng dẫn sử dụng Jquery Plugin Hotkeys – Tạo phím nóng trên trình duyệt web và chức năng giới thiệu ở bài viết Hướng dẫn sử dụng bootstrap tourist để làm trợ giúp cho phần mềm. Tôi thêm vào phần lớp Base nhưng tất cả các Form của tôi đều có luôn. Như vậy sẽ tăng tốc được khi làm các Form và tính năng mới.

Trên đây chỉ là một vài chia sẻ nhỏ. Hy vọng sẽ giúp ích được cho các bạn.

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

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

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

Repository design pattern hoàn thiện trong Laravel

Repository design pattern hoàn thiện trong Laravel

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

Trong bài viết này tôi sẽ chỉ cho bạn cách thiết lập Repository design pattern trong Laravel từ đầu. Tôi sẽ sử dụng phiên bản Laravel 5.8.3, nhưng phiên bản Laravel cũng không thực sự quá quan trọng. Trước khi chúng tôi bắt đầu code, có một vài điều bạn cần biết về repository design pattern.

Repository design pattern hoàn thiện trong Laravel

Repository Pattern là lớp trung gian giữa tầng Data Access và Business Logic. Repository design pattern cho phép bạn sử dụng các đối tượng mà không cần phải biết các đối tượng này được duy trì như thế nào. Về cơ bản nó là một sự trừu tượng hóa của lớp dữ liệu.

Điều này có nghĩa là Business Logic của bạn không cần phải biết cách lấy lại dữ liệu hay nguồn dữ liệu là gì. Business Logic dựa trên repository để lấy dữ liệu chính xác.

Một quan niệm sai lầm mà tôi thấy rất nhiều là các repository đang được thực hiện theo cách tạo hay cập nhật các bản ghi. Đây không phải là những gì mà repository nên làm. Các kho lưu trữ không nên tạo hoặc cập nhật dữ liệu, nhưng chỉ nên được sử dụng để truy xuất dữ liệu.

Tuyển dụng Laravel lương cao cho bạn

  18 designer hàng đầu dự đoán về xu hướng UI/ UX trong năm 2022
  30 tiện ích Chrome cho designer và dev

Hãy bắt tay vào việc code bây giờ.

Bởi vì tôi hướng dẫn các bạn làm từ đâu, đầu tiên ta phải tạo một project laravel trước.

php artisan config:clear

Đối với phần hướng dẫn này, tôi sẽ tạo ra một blog nhỏ. Bây giờ chúng tôi đã tạo một project, chúng tôi cần tạo Controller và Model cho blog.

php artisan config:clear

Cái này sẽ tạo BlogController trong tệp app/Http/Controllers

php artisan config:clear

Ghi chú: Lựa chọn -m sẽ tạo ra một Data Migration (chuyển đổi dữ liệu). File này có thể được tìm thấy trong database/migrations

Điều này sẽ tạo Model cho Blog của bạn và lưu trữ nó trong thư mục App / Models. Đây chỉ là một trong những cách để lưu trữ các Model của bạn, và là phương pháp mà tôi thích.

Bây giờ chúng ta đã có Controller và Model, đã đến lúc xem tệp chuyển đổi mà chúng ta đã tạo. Bây giờ blog cần một tiêu đề, nội dung và trường user_id; bên cạnh các trường timestamp (dấu thời gian) mà là mặc định của Laravel.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateBlogsTable extends Migration
{
   public function up()
   {
       Schema::create('blogs', function (Blueprint $table) {
           $table->bigIncrements('id');
           $table->string('title');
           $table->text('content');
           $table->integer('user_id');
           $table->timestamps();
          
           $table->foreign('user_id')
                 ->references('id')
                 ->on('users');
       });
   }

   public function down()
   {
       Schema::dropIfExists('blogs');
   }
}

Ghi chú: Nếu bạn đang dùng phiên bản cũ hơn Laravel 5.8, bạn nên thay thế dòng

php artisan config:clear

Thiết lập kho database:

Tôi dùng MySQL cho ví dụ này. Bước đầu tiên là tạo một cơ sở dữ liệu mới.

mysql -u root -p
create database laravel_repository;

Điều này sẽ tạo ra một database gọi là laravel_repository. Tiếp theo chúng ta phải thêm thông tin cơ sở dữ liệu vào tệp .env

DB_DATABASE=laravel_repository
DB_USERNAME=root
DB_PASSWORD=secret

Điều này sẽ tạo ra một database gọi là laravel_repository. Tiếp theo chúng ta phải thêm thông tin cơ sở dữ liệu vào tệp .env

Sau khi bạn đã thay đổi tệp .env, chúng tôi phải xóa bộ đệm cấu hình:

php artisan config:clear

Chạy chuyển đổi dữ liệu

Sau khi ta đã set-up xong phần database, ta có thể bắt đầu chạy phần chuyển đổi dữ liệu

php artisan config:clear

Điều này sẽ tạo blog với các trường tiêu đề, nội dung và user_id mà chúng tôi đã khai báo trong chuyển đổi dữ liệu.

Thực hiện repository design pattern

Với những gì ta đã làm, bây giờ chúng ta có thể bắt đầu thực hiện repository design pattern. Chúng tôi sẽ bắt đầu bằng cách tạo thư mục Repositories trong thư mục App. Tiếp theo chúng ta sẽ tạo thư mục Interfaces. Thư mục này sẽ được đặt trong thư mục Repositories mà chúng ta vừa tạo.

Trong thư mục Interfaces, chúng ta tạo lớp BlogReositoryInterface với hai phương thức:

  • Phương thức all sẽ trả về tất cả các blog
  • Phương thức getByUser sẽ trả về tất cả các blog mà được tạo bởi một user cụ thể.
<?php

namespace App\Repositories\Interfaces;

use App\User;

interface BlogRepositoryInterface
{
   public function all();

   public function getByUser(User $user);
}

Lớp cuối cùng mà chúng ta sẽ tạo là lớp BlogRepository,  lớp này sẽ triển khai lớp BlogRepositoryInterface. Chúng tôi sẽ thực hiện việc nay đơn giản nhất có thể.

<?php

namespace App\Repositories;

use App\Models\Blog;
use App\User;
use App\Repositories\Interfaces\BlogRepositoryInterface;

class BlogRepository implements BlogRepositoryInterface
{
   public function all()
   {
       return Blog::all();
   }

   public function getByUser(User $user)
   {
       return Blog::where('user_id'. $user->id)->get();
   }
}

Thư mục Repositories của bạn nên trông như thế này:

app/
└── Repositories/
   ├── BlogRepository.php
   └── Interfaces/
       └── BlogRepositoryInterface.php

Bây giờ bạn đã thành công tạo repository! Giờ ta sẽ bắt đầu sử dụng nó.

Sử dụng Repository

Để bắt đầu sử dụng BlogRepository, chúng ta nên đưa nó vào BlogController. Vì repository sẽ được chèn, nên sẽ dễ dàng trao đổi nó với một thực thi khác. Controller sẽ trông như sau:

<?php

namespace App\Http\Controllers;


use App\Repositories\Interfaces\BlogRepositoryInterface;
use App\User;

class BlogController extends Controller
{
   private $blogRepository;

   public function __construct(BlogRepositoryInterface $blogRepository)
   {
       $this->blogRepository = $blogRepository;
   }

   public function index()
   {
       $blogs = $this->blogRepository->all();

       return view('blog')->withBlogs($blogs);
   }

   public function detail($id)
   {
       $user = User::find($id);
       $blogs = $this->blogRepository->getByUser($user);

       return view('blog')->withBlogs($blogs);
   }
}

Như bạn có thể thấy mã trong controller ngắn và do đó có thể đọc được. Bạn không cần mười dòng mã để có được bộ dữ liệu bạn muốn, tất cả có thể được thực hiện trong một dòng mã nhờ vào repository. Điều này cũng rất tốt cho kiểm thử đơn vị, vì các phương thức của repository có thể dễ dàng kiểm tra qua.

Repository design pattern cũng giúp dễ dàng thay đổi giữa các nguồn dữ liệu. Trong ví dụ này, chúng tôi đang sử dụng cơ sở dữ liệu để truy xuất blog của mình. Chúng ta dựa vào Eloquent để làm điều đó cho. Nhưng giả sử ta tìm thấy một blog  API tuyệt vời ở đâu đó trên mạngvà chúng tôi muốn sử dụng API này. Tất cả những gì chúng ta phải làm là viết lại BlogRepository để sử dụng API đó thay vì Eloquent.

RepositoryServiceProvider

Thay vì chèn BlogRepository vào trong BlogController, ta có thể chèn BlogRepositoryInterface và sau đó để Service Container quyết định repository nào sẽ được sử dụng. Điều này có thể được thực hiện trong phương thức boot của AppServiceProvider, nhưng tôi thích tạo 1 provider mới cho việc này để giữ mọi thứ clean.

php artisan config:clear

Lý do ta tạo ra một provider mới cho việc này là vì mọi thứ trở nên thực sự lộn xộn khi dự án của bạn bắt đầu phát triển. Hãy tưởng tượng một dự án với hơn 10 model và mỗi model đều có repository riêng. AppServiceProvider của bạn sẽ trở nên không thể đọc được.

RepositoryServiceProvider của bạn sẽ như sau:

<?php

namespace App\Providers;

use App\Repositories\BlogRepository;
use App\Repositories\Interfaces\BlogRepositoryInterface;
use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(
            BlogRepositoryInterface::class, 
            BlogRepository::class
        );
    }
}

Hãy nhớ rằng việc hoán đổi BlogRepository với một repository khác dễ như thế nào.

Đừng quên thêm RepositoryServiceProvider vào danh sách các provider trong tệp config/app.php. Sau đó, chúng ta phải xóa bộ đệm cấu hình một lần nữa.

php artisan config:clear

Và bạn đã thực hiện thành công repository design pattern. Cũng không khó quá đúng không?

Link bài viết: https://itnext.io/repository-design-pattern-done-right-in-laravel-d177b5fa75d4

Dịch: Dương Nhật Minh

Bài viết gốc được đăng tải tại Tạp chí Lập trình

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

Xem thêm các tuyển dụng it đà nẵng hấp dẫn tại TopDev

Composition là cái chi chi

Composition là cái chi chi

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

Composition một cách trừu tượng mà nói là việc đưa hai (hoặc nhiều) thứ khác nhau vào một chỗ để nhận được một loại kết quả

  5 sai lầm thường thấy khi viết react component
  7 lí do để loại bỏ Functional Components của React

Composition trong toán học

Toán học cũng chưa thật sự liên quan nhiều đến frontend, tuy nhiên toán học là nơi đã phát sinh ra khái niệm này

Ví dụ có 2 hàm, một hàm là y = 2 * x, hàm thứ 2 là y = x + 10.

Composition 2 hàm này lại, kết quả của thằng này là input của thằng kia, chúng ta sẽ có hàm mới y = (2 * x) + 10Đó là tất cả khái niệm cần nắm

Function composition

Trong ngữ cảnh của functional programming, cũng không khác toán học, chỉ là được diễn tả bằng code

let date = getDate();
let text = formatDate(date);
let label = createLabel(text);
showLabel(label);

Code này có vài đoạn na ná nhau, chúng ta có nhận lấy một input, convert nó sang một loại khác, rồi lại lấy kết quả đó, convert tiếp.

Làm sao để lượt bỏ hết sự na ná đó?

let steps = [
    getDate,
    formatDate,
    createLabel,
    showLabel
]

Một “vài người” cho rằng code vậy sạch hơn. Viết một helper function để tin gọn hơn nữa

function runSteps(steps) {
  let result;
  for (let i = 0; i < steps.length; i++) {
    let step = steps[i];
    // làm tiếp các bước được móc nối vào
    result = step(result);
  }
  return result;
}

Nhờ sự trợ giúp của hàm runSteps chúng ta có thể viết lại

runSteps([
    getDate,
    formatDate,
    createLabel,
    showLabel
])

Nếu tổng số code bước phải làm là cố định, chúng ta muốn chạy y chang như vậy trên nhiều chỗ khác nhau, chúng ta tiếp tục đưa nó vào một function

function showDateLabel() {
  runSteps([
    getDate,
    formatDate,
    createLabel,
    showLabel
  ]);
}
// Giờ gọi ở bất kỳ đâu
showDateLabel();
showDateLabel();

Các bạn lập trình lại tiến một bước xa hơn, sao không rút gọn code hơn nữa bằng một hàm gọi là pipe

let showDateLabel = pipe(
  getDate,
  formatDate,
  createLabel,
  showLabel
);
// Giờ gọi ở bất kỳ đâu
showDateLabel();
showDateLabel();

Chúng ta dấu diếm phần implement của thể đó như thế này

function pipe(...steps) {
  // chạy hết tất cả các function cho tui
  return function runSteps() {
    let result;
    for (let i = 0; i < steps.length; i++) {
      let step = steps[i];
      result = step(result);
    }
    return result;
  }
}

Như vậy chúng ta đã đi rất xa, rất rất xa. Từ điểm xuất phát phải gọi lần lượt các hàm một cách thủ công, chúng ta chỉ định các bước cần chạy theo thứ tự một cách sạch sẽ hơn

// code cũ
let date = getDate();
let text = formatDate(date);
let label = createLabel(text);
showLabel(label);

// code mới
let showDateLabel = pipe(
  getDate,
  formatDate,
  createLabel,
  showLabel
);
showDateLabel();

Nếu có thắc mắc trong đầu: ủa vậy để mần chi? Phức tạp rườm rà vãi cả ra! Hãy cân nhắc xem giữa hay cách viết trên, cách nào bạn đọc dễ hơn?

Khi hiểu được pipe và function composition bạn sẽ thấy mọi thứ gọn gàng rành mạch thật tuyệt vời, nhưng không có nghĩa là không có nhược điểm, outsource cho pipe, chúng ta không còn thấy được rõ ràng dữ liệu đã đi ra-đi vào như thế nào.

Component Composition

Một ngữ cảnh khác chúng ta cũng thấy sự xuất hiện của “composition” là lập trình UI hướng declarative. React component là một ví dụ.

function App() {
  return <Screen />;
}
function Screen() {
  return <Form />;
}
function Form() {
  return <Button />;
}
function Button() {
  return <button>Hey there.</button>;
}

Đấy cũng gọi là composition vì chúng ta đứa những component vào trong những component khác, rồi nhận được kết quả là một tổng thể chứa tất cả component

Một dạng biến thể của composition trong component là slot (làm Vue bạn sẽ biết khái niệm này)

function Layout({ sidebar, content }) {
  return (
    <div>
      <div className="sidebar">{sidebar}</div>
      <div className="content">{content}</div>
    </div>
  )
}

Sau đấy đưa các giá trị cụ thể vào slot

function HomePage() {
  return (
    <Layout
      sidebar={<HomeSidebar />}
      content={<HomeContent />}
    >
  )
}
function AboutPage() {
  return (
    <Layout
      sidebar={<AboutSidebar />}
      content={<AboutContent />}
    >
  )
}

React sẽ không đặt hẳn một khái niệm riêng cho slot vì bạn có thể làm điều đó thông qua prop

Composition vs inheritance

Người đời thường đem composition để đối chiếu với inheritance, kế thừa gặp nhiều trong class và object hơn, composition gặp nhiều trong function

Một cách cụ thể, nếu viết code theo kiểu class, bạn sẽ có xu hướng dùng lại các behavior từ một class khác bằng cách extend nó (kế thừa). Tuy nhiên, làm vậy cũng có hạn chế là rất khó tùy chỉnh các behavior sau này. Ví dụ như tình huống muốn extend không chỉ một mà nhiều class

Đôi khi, miệng đời cũng đồn đại rằng việc dùng class khiến “bạn bị khóa cứng” trong thiết kế ban đầu vì việc thay đổi kiến trúc của các class thì rất chi là tốn công. Với việc dùng composition, thay vì extend, bạn dữ nguyên hiện trạng của một instance, sử dụng trực tiếp từ instance này và cũng có thể làm gì đó kết hợp với nhiều thứ khác, có nhiều đất diễn hơn.

Nói chung, ngành phần mềm đã bỏ việc model các UI component như một dạng kế thừa nhiều tầng nhiều cấp.

Không có nói inheritance lúc nào cũng “tệ”, nó chỉ không đủ “bén như dao lam”, sử dụng cần phải tiết chế, việc kế thừa đa cấp ở một độ sâu nhất định, đòi hỏi bạn đủ kiên nhẫn để giải quyết các vấn đề của nó.

If you write your code in a style that composes functions in some way before calling them, and there are other humans on your team, make sure that you’re getting concrete benefits from this approach. It is not “cleaner” or “better”, and there is a price to pay for “beautiful” but indirect code.

Tạm kết: Nếu bạn làm việc trong team, hãy đảm bảo mọi người nhất trí với nhau lợi ích mà nó mang lại từ cách làm này. Nó không liên quan gì tới việc “cleaner-better”, nó luôn có cái giá phải trả cho “beautiful” nhưng mà code không trực quan.

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

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

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

Product Owner là gì?

product owner là gì

Product Owner là người lên kế hoạch cho mọi thứ liên quan đến sản phẩm bao gồm cả việc User Research, làm việc với UX/UI Designer, lên kế hoạch cho việc ReleaseTimeline cho sản phẩm.

  Product Manager là gì? Chân dung của một Product Manager
  The Product Mindset — Tư duy làm sản phẩm

Product Owner là gì?

Product Owner hay được gọi là PO là một một thành viên trong Scrum Team, họ là người chịu trách nhiệm cho sản phẩm, là người đưa ra quyết định chính thức và cuối cùng cho việc chọn lựa tính năng của sản phẩm, giải quyết những vấn đề xoay quanh User, họ được xem như là “chủ sở hữu” sản phẩm nên có quyền hạn đưa ra quyết định thứ tự công việc, độ ưu tiên…Nói chung họ là người quyền lực nhất trong Scrum Team.

Product Owner là người lên kế hoạch cho mọi thứ liên quan đến sản phẩm bao gồm cả việc User Research, làm việc với UX/UI Designer, lên kế hoạch cho việc ReleaseTimeline cho sản phẩm.

Tuy nhiên Product Owner không có quyền hạn để yêu cầu team Developer phải làm như thế nào để hoàn thành một Sprint mà họ chỉ có thể giao phó, đưa ra yêu cầu mà họ muốn team Developer hoàn thành cho Scrum Master để Scrum Master truyền đạt lại cho team Developer.

product owner là gì
product owner là gì

Vai trò và trách nhiệm của Product Owner

Vai trò

Vai trò của Product Owner khá quan trọng trong quy trình Scrum, họ là người đại diện cho khách hàng để làm việc với team Developer. Nhiệm vụ chính của họ là quản lý và giải quyết các vấn đề tồn đọng liên quan đến sản phẩm, là người chịu trách nhiệm cho tất cả các kế hoạch của sản phẩm.

Product Owner là người duy nhất có quyền hạn thay đổi thứ tự trong trong các Backlog. Khi có vấn đề phát sinh xoay quanh sản phẩm, các Developer có quyền đặt ra câu hỏi và Product Owner phải là người giải đáp thắc mắc cho team Developer để team Developer có thể hiểu rõ hơn về tính năng mà Product Owner mong muốn ở một sản phẩm, từ đó cho ra đời những sản phẩm làm Product Owner hài lòng.

  3 bài học xương máu mà mỗi Product Manager đều phải trải qua.

  Bí kíp để trở thành một Product Manager giỏi

Sự hài lòng của Product Owner đôi khi cũng sẽ là sự hài lòng của khách hàng, một Product Owner giỏi sẽ là người có thể thấu hiểu được hết nhu cầu của khách hàng đối với sản phẩm và đáp ứng được tất cả yêu cầu mà khách hàng đưa ra.

product owner là gì
product owner là gì

Trách nhiệm

Quản lý backlog

Có trách nhiệm đưa ra phương án giải quyết vấn đề và các giải pháp đó phải thật sự hữu ích. 

Product Owner là người có thẩm quyền trực tiếp can thiệp và theo dõi xuyên suốt quá trình hoạt động tạo ra và nâng cấp sản phẩm thông qua việc tìm hiểu, phân tích dữ liệu, nhận feedback từ khách hàng. Sau đó các Product Owner cũng sẽ là người cho ra phương án giải quyết và quyết định cuối cùng mà họ cho là tối ưu nhất.

Thực hiện quy trình User Research, từ việc phỏng vấn đến việc lập bảng câu hỏi cho khách hàng để hiểu rõ hơn về các vấn đề xoay quanh sản phẩm.

Kết hợp với team UX/UI Designer để có thể sáng tạo hóa sản phẩm, đem lại sự mới lạ thu hút đối với User.

Để giúp team Developer có thể hiểu rõ yêu cầu của người Product Owner, thì các Product Owner giỏi sẽ có thêm bước làm SRC để team Developer hiểu và làm theo đúng yêu cầu của Product Owner, tránh trường hợp “lạc đề”.

Đưa ra các đánh giá về Backlog đã xong và sắp xếp chúng theo thứ tự ưu tiên cho các Backlog chưa được hoàn thành.

Lên kế hoạch dài hạn và ngắn hạn (timeline, thời gian Release…)cho các chiến dịch nhỏ để từng bước phát triển sản phẩm.

Không như team Developer và Scrum Master, đối với các sản phẩm đã hoàn thành và được Release, thì nhiệm vụ của team Developer và Scrum Master đã hết nhưng với Product Owner thì vẫn chưa xong.

Các Product Owner phải thường xuyên theo dõi, phân tích tình hình hoạt động của sản phẩm, sự hài lòng của khách hàng… Trong trường hợp sản phẩm gặp vấn đề hoặc khách hàng muốn tối ưu các tính năng hơn nữa thì Product Owner sẽ là người tiếp nhận ý kiến nhanh chóng nhất. 

Phân tích tầm nhìn cho sản phẩm

Việc chia sẻ và truyền tải định hướng tầm nhìn của sản phẩm ra sao, như thế nào một phần là trách nhiệm của Product Owner. Họ có nghĩa vụ phải lan tỏa thông tin về tính năng sản phẩm đến cho nội bộ doanh nghiệp, User và khách hàng.

Hiểu rõ sức ảnh hưởng, đối tượng các sản phẩm sẽ ảnh hưởng đến để đưa ra cái nhìn tổng quát và có đánh giá khách quan nhất từ đó có thể cho ra các phương án giải quyết hiệu quả để cải thiện và phát triển sản phẩm một cách tối ưu hơn nữa.

Làm việc, trao đổi với Scrum Master

Làm việc trực tiếp và có sức ảnh hưởng, quyền quyết định trong team Scrum Master, làm việc sâu sát với Scrum Master.

Tham gia vào các sự kiện trong team Scrum, là người động viên, thúc đẩy, đẩy nhanh tiến trình làm việc của team Scrum.

Là người thu nhận thông tin yêu cầu của khách hàng, doanh nghiệp và truyền tải những yêu cầu đó đến Scrum Master để cùng team Developer hoàn thành sản phẩm.

product owner là gì
product owner là gì

Yếu tố để trở thành một Product Owner giỏi

Trước đây, vị trí Product Owner thường được đảm nhiệm bởi những người có kinh nghiệm làm việc phong phú và nhiều năm trong nghề nhưng trong môi trường làm việc hiện đại ngày nay thì ngày có nhiều bạn trẻ có hoài bão, ước mơ “dấn thân” vào con đường trở thành một Product Owner chuyên nghiệp. 

Để có thể trở thành một Product Owner chuyên nghiệp và giỏi trong lĩnh vực của mình thì ngoài việc cố gắng bồi dưỡng kiến thức cho bản thân thì các bạn trẻ cũng nên hiểu rõ điểm mạnh và điểm yếu của mình từ đó khắc phục. Dưới đây là những yếu tố có ở một Product Owner giỏi mà bạn cần phải biết.

  Con đường trở thành Product Manager từ lập trình viên tại Amazon

  Tui muốn làm Product Manager (PM)! Biết PM là gì chưa mà đòi?

Hiểu biết về sản phẩm, thị trường mình đang phụ trách.

Có sự hiểu biết kỹ lưỡng về sản phẩm mà bản thân đang phụ trách là yếu tố đầu tiên và cũng quan trọng nhất mà một Product Owner bắt buộc phải có. Điều này giúp cho công việc của Product Owner trở nên hiệu quả hơn rất nhiều vì khi hiểu sản phẩm thì định hướng sản phẩm và kế hoạch sẽ chính xác hơn, đáp ứng được nhu cầu của thị trường hơn.

Trong thực tế, để có thể hoàn thiện được sản phẩm, có rất nhiều công đoạn cần phải đi qua và chưa chắc các sản phẩm sau khi hoàn thành sẽ được khách hàng đồng ý và được thị trường đón nhận. Do đó, một Product Owner có sự hiểu biết về sản phẩm lẫn thị trường sẽ có thể giảm thiểu rủi ro khi sản phẩm được Release.

topdev
product owner là gì

Dành nhiều thời gian cho công việc

Bất kì ngành nghề nào nếu muốn đạt được kết quả tốt cũng đều cần dành nhiều thời gian và tâm tư vào đó. Nghề Product Owner cũng vậy, vì là người phải chịu trách nhiệm cho toàn bộ quy trình phát triển sản phẩm, chính vì thế người làm Product Owner cần tập trung và dành thật nhiều thời gian cho công việc để có thể theo dõi tiến độ làm việc, các vấn đề phát sinh, cách giải quyết, kết quả đón nhận của User đối với sản phẩm…

Kỹ năng giao tiếp

Đây là kỹ năng phổ biến cần có trong các ngành nghề hiện nay, đối với Product Owner cũng vậy. Đối tượng làm việc của Product Owner khá rộng, từ khách hàng, doanh nghiệp đến các Product Owner khác và cuối cùng là team Scrum…họ phải giao tiếp khá nhiều bên liên quan để có thể truyền đạt được ý tưởng, mong muốn của mình. 

Chính vì thế, để có thể hoàn thành tốt công việc của mình, thuyết phục được những khách hàng khó tính và được các bộ phận khác support hết mình, thì kỹ năng giao tiếp và thuyết phục người nghe cũng rất quan trọng.

Quyết đoán

Là người gần như có quyền quyết định mọi chuyện trong team Scrum, một Product Owner cần có sự quyết đoán, dứt khoát và kiên định trong những cuộc họp Daily Sprint. Trong mỗi cuộc họp, chắc hẳn sẽ có rất nhiều luồng ý kiến trái chiều và nhiều ý tưởng được đề ra và người đưa ra quyết định cuối cùng không ai khác là Product Owner. Sự quyết đoán chắc chắn sẽ là yếu tố quyết định để giúp các Product Owner có thể đưa ra quyết định một cách nhanh chóng.

Một Product Owner giỏi là một Product Owner biết lắng nghe ý kiến từ mọi người, đặt mình ở vai trò User cùng với kinh nghiệm làm việc, sự quyết đoán sẽ có thể đưa ra quyết định phù hợp nhất cho sản phẩm.

Sự khác biệt giữa Product Owner và Product Manager là gì?

Product Owner chính là người phụ trách giải quyết những vấn đề của sản phẩm xảy ra khi User khi sử dụng sản phẩm. Trong trường hợp kết quả không được khả quan thì Product Owner sẽ tiến hành quá trình cải tiến, nâng cấp sản phẩm để giúp sản phẩm đạt được KPI kinh doanh đã được đề ra từ trước của công ty.

Đôi khi các Product Owner được xem là Product Manager của các sản phẩm nhỏ nằm trong các sản phẩm lớn.

Product Manager có chức vụ cao lớn và rộng hơn, họ là người giải quyết những vấn đề mang tính khái quát, tổng quan, liên quan đến các chiến lược lâu dài của sản phẩm như: làm product roadmap, tầm nhìn, định vị sản phẩm trong thị trường,.v.v…

Có thể bạn muốn xem thêm:

Xem thêm nhiều việc làm Product Owner hấp dẫn lương cao tại TopDev!

Dùng Emmet để Code HTML/CSS nhanh hơn

Emmet trong HTML CSS

Tác giả: Jesse Hall

Emmet là một trong những tính năng built-in ưa thích của mình với text editor VS Code, và nó cũng là extension có sẵn trên các nền tảng code editor khác. Với Emmet, bạn có thể đẩy nhanh tốc độ làm việc HTML & CSS, thậm chí còn được xem là cheat-code.

  Bỏ túi Cheatsheet React cho năm 2023 (kèm ví dụ thực tế)
  Tất tần tật các Frontend cheatsheets tốt nhất

Dùng Emmet trong HTML

Với Emmet thì việc tạo một HTML boilerplate diễn ra trong nháy mắt. Với HTML file, chỉ cần type ! bạn sẽ thấy Emmet hiển thị các gợi ý, sau đó chỉ việc Enter là đã có sẵn trang HTML blank cơ bản. Đây mình mới chỉ đang demo vài khả năng của VS Code và Emmet nên nếu chưa hiểu thì không sao, cứ đọc tiếp nhé.

Xem thêm Tạo React Boilerplate – Từ a tới z

Các tag cơ bản

Để tạo các thẻ – tag HTML thì chỉ cần gõ tên thẻ và Enter. Emmet sẽ đặt con trỏ chuột trong thẻ đó, lúc này có thể tiếp tục type bên trong thẻ rồi.

  • Thử type div sau đó Enter, hoặc h1 Enter, hoặc p Enter.
  • Ngoài ra thì cũng có: bq cho <blockquote>hdr cho <header>ftr cho <footer>btn cho <button>, và sect cho section.

Classes

Nếu bạn đã quen với CSS thì Emmet cũng dùng cách tương tự, dấu . để refer đến class. Để define class với thẻ thì chỉ cần thêm như thế này:

  • div.wrapper —> <div class="wrapper"></div>
  • h1.header.center —> <h1 class="header center"></h1>

ID’s

Làm với ID thì cũng khá tương tự:

  • div#hero —> <div id="hero"></div>

Ghép chuỗi

Ghép 2 cái trên thì ta có:

  • div#hero.wrapper —> <div id="hero" class="wrapper"></div>

Attributes – thuộc tính

Ta cũng có thể chỉ định attribute cho tag:

  • img[src="cat.jpg"][alt="Cute cat pic"] —> <img src="cat.jpg" alt="Cute cat pic" />

Content – nội dung

Để “bọc” content trong tag, chỉ cần bỏ chúng giữa 2 dấu ngoặc {}

  • p{This is a paragraph} —> <p>This is a paragraph</p>

Siblings & Children

Tương tự với siblings và children thì dùng ký tự dấu cộng + và dấu lớn hơn >

  • section+section —> <section></section><section></section>
  • ul>li —> <ul><li></li></ul>

Climbing up

Hình dung những gì đang build trong đầu vì lúc này bạn đang type tốc ký Emmet. Ví dụ này thì mình đang leo cây với ^.

div+div>p>span+em^bq

Kết quả

<div></div>
<div>
    <p><span></span><em></em></p>
    <blockquote></blockquote>
</div>

Ở đây mình muốn để blockquote nó xuất hiện ngang hàng – same level với paragraph. Vì thế nên mới cần climb up, nếu không thì blockquote sẽ bị nhét vào trong paragraph.

Nhóm

Nếu cấu trúc phức tạp thì bạn có thể nhóm thẻ – group tag thay vì dùng climb up. Ví dụ này mình tạo header và footer (không climb) sử dụng ngoặc đơn ().

div>(header>ul>li>a)+footer>p

Kết quả

<div>
    <header>
        <ul>
            <li><a href=""></a></li>
        </ul>
    </header>
    <footer>
        <p></p>
    </footer>
</div>

Phép nhân và ký hiệu $

Bạn có thể tạo tag theo cấp số nhân bằng (*) và đánh số các items theo thứ tự với ký hiệu dollar ($).

  • ul>li*5 —> <ul><li></li><li></li><li></li><li></li><li></li></ul>
  • ul>li{Item $}*3 —> <ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>

Thậm chí bạn có thể customize luôn thứ tự đánh số chứa chữ số 0, bắt đầu với số xác định và có thể đảo ngược lại.

Đệm số 0: ul>li.item$$$*5

Kết quả:

<ul>
    <li class="item001"></li>
    <li class="item002"></li>
    <li class="item003"></li>
    <li class="item004"></li>
    <li class="item005"></li>
</ul>

Bắt đầu bằng một số xác định: ul>li.item$@3*5

Kết quả:

<ul>
    <li class="item3"></li>
    <li class="item4"></li>
    <li class="item5"></li>
    <li class="item6"></li>
    <li class="item7"></li>
</ul>

Đảo hướng:ul>li.item$@-*5

Kết quả:

<ul>
    <li class="item5"></li>
    <li class="item4"></li>
    <li class="item3"></li>
    <li class="item2"></li>
    <li class="item1"></li>
</ul>

Đảo hướng từ một số xác định: ul>li.item$@-3*5

Kết quả:

<ul>
    <li class="item7"></li>
    <li class="item6"></li>
    <li class="item5"></li>
    <li class="item4"></li>
    <li class="item3"></li>
</ul>

Tag ngầm

Có một số thẻ tag không cần type ra mà có thể ngầm hiểu:

  • Một class lúc đầu không có tag thì sẽ được hiểu là <div>.

.wrapper —> <div class="wrapper"></div>

  • Class với thẻ emphasis sẽ được hiểu là <span>.

em>.emphasis —> <em><span class="emphasis"></span></em>

  • Class xác định bên trong list sẽ được hiểu là list item.

ul>.item —> <ul><li class="item"></li></ul>

  • Class xác định trong table được hiểu là <tr> còn trong row thì là <td>.

table>.row>.col —> <table><tr class="row"><td class="col"></td></tr></table>

“Kẹp” Tag

Có lúc bạn muốn kẹp thẻ tag vào những đoạn code có sẵn, Emmet có thể dễ dàng làm việc này. Đầu tiên, highlight đoạn code bạn cần add tag, và mở command pallet (F1) lên, search Emmet: Wrap with Abbreviation. Sau đó sẽ có dialog box để gõ element vào.

test —> <div>test</div>

Ngoài cách này thì cũng có thể dùng cú pháp Emmet tiêu chuẩn trong dialog này, wrap đoạn text với span.wrapper. Chức năng này không được gán vào phím tắt. Nên nếu bạn dùng tính năng này thường xuyên thì nên add shortcut cho nó.

Lorem Ipsum

“Lorem Ipsum” là đoạn text fake rất phổ biến được dùng để hiển thị random các giá trị dữ liệu trên trang. Chỉ cần gõ và lorem bấm Enter. Emmet sẽ tạo ra 30 từ ngẫu nhiên có thể dùng để dàn nội dung trong project.

Bạn cũng có thể tự cho số lượng chữ theo nhu cầu.

  • lorem10 sẽ cho bạn 10 từ random.

Gộp chung lại

Thử gộp chung những điều ở trên lại: ul.my-list>lorem10.item-$*5

Kết quả

<ul class="my-list">
  <li class="item-1">Lorem ipsum dolor sit amet.</li>
  <li class="item-2">Numquam repudiandae fuga porro consequatur?</li>
  <li class="item-3">Culpa, est. Tenetur, deleniti nihil?</li>
  <li class="item-4">Numquam architecto corrupti quam repudiandae.</li>
</ul>

Dùng Emmet trong CSS

Với CSS, thì Emmet có từng cái viết tắt cho từng property, mình sẽ không liệt kê chúng ra hết nhưng sẽ đưa ra những trường hợp được dùng nhiều nhất. Bạn có thể xem full list tại đây.

  Tìm hiểu về thuộc tính Writing Mode trong CSS

Position

  • pos —> position:relative; (mặc định relative)
  • pos:s —> position:static;
  • pos:a —> position:absolute;
  • pos:r —> position:relative;
  • pos:f —> position:fixed;

Xem thêm Tất tần tật về thuộc tính position trong CSS

Hiển thị

  • d —> display:block; (mặc định block)
  • d:n —> display:none;
  • d:b —> display:block;
  • d:f —> display:flex;
  • d:if —> display:inline-flex;
  • d:i —> display:inline;
  • d:ib —> display:inline-block;

Cursor

  • cur —> cursor:pointer;

Màu

  • c —> color:#000;
  • c:r —> color:rgb(0, 0, 0);
  • c:ra —> color:rgba(0, 0, 0, .5);
  • op —> opacity: ;

Margin & Padding: Đệm lề

  • m —> margin: ;
  • m:a —> margin:auto;
  • mt —> margin-top: ;
  • mr —> margin-right: ;
  • mb —> margin-bottom: ;
  • ml —> margin-left: ;
  • p —> padding: ;
  • pt —> padding-top: ;
  • pr —> padding-right: ;
  • pb —> padding-bottom: ;
  • pl —> padding-left: ;

Box Size

  • bxz —> box-sizing:border-box;

Xem thêm CSS Box Model – Các cách hiển thị element với thuộc tính display

Chiều rộng

  • w —> width: ;
  • h —> height: ;
  • maw —> max-width: ;
  • mah —> max-height: ;
  • miw —> min-width: ;
  • mih —> min-height: ;

Canh lề

  • bd —> border: ;
  • bd+ —> border:1px solid #000;
  • bd:n —> border:none;

Kết luận

Với Emmet bạn có thể tạo nên cấu trúc HTML phức tạp với chỉ một dòng, với CSS cũng làm được những điều tương tự. Tóm lại, Emmet khá đỉnh, dùng Emmet có thể giúp nâng cao năng suất và tốc độ viết HTML và CSS.

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

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

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

Trở thành “mảnh ghép” tài năng của VinID – Cơ hội lớn cho lập trình viên phát triển sự nghiệp

Trở thành “mảnh ghép” tài năng của VinID – Cơ hội lớn cho lập trình viên phát triển sự nghiệp

Được thành lập vào tháng 7 năm 2018, Công ty Cổ phần VinID ra đời với sứ mệnh liên kết toàn bộ hệ sinh thái VinGroup, trở thành “trợ thủ đắc lực” cho tất cả mọi người, mọi gia đình và mọi hộ kinh doanh. VinID luôn nỗ lực từng ngày để mang đến những trải nghiệm tốt nhất và nhiều lợi ích nhất cho người dùng, hướng đến mục tiêu “Vì một cuộc sống tốt đẹp hơn cho người Việt”.

Trở thành “mảnh ghép” tài năng của VinID – Cơ hội lớn cho lập trình viên phát triển sự nghiệp

VinID – Siêu ứng dụng gắn kết hệ thống sinh thái VinGroup

Công ty cổ phần VinID là công ty con trực thuộc VinGroup, tập đoàn đa ngành với vị thế dẫn đầu trong nền kinh tế cả nước.

Khởi nguồn từ các chương trình chăm sóc khách hàng từ Vingroup, VinID được biết đến là “chiếc thẻ quyền năng” giúp tối ưu quyền lợi cho khách hàng thân thiết của tập đoàn với vai trò là sản phẩm tích lũy điểm sau mỗi lần mua sắm tại các công ty thành viên của Vingroup như Vinmart, Vinmart+, Vinpearl,…. Đặc biệt, khách hàng sau khi tích lũy có thể sử dụng điểm đó để thanh toán cho các dịch vụ hoặc những lần mua sắm tiếp theo.

Ngoài chiếc thẻ cứng, khách hàng còn có thể sử dụng ứng dụng di động VinID, giải pháp hiệu quả cho người dùng trong trường hợp “để quên” hoặc không mang theo thẻ, thay thế hoàn toàn và tích hợp tất cả thao tác, hướng chủ thẻ đến việc mua sắm không tiền mặt đồng thời đem đến nhiều ưu đãi hấp dẫn.

 VinID Mobile App – “trợ lý đắc lực” cho chủ thẻ VinID

Với sự phát triển của thời đại 4.0, VinID trở thành hệ sinh thái số được xây dựng với nền tảng công nghệ ưu việt kết hợp năng lực phân tích dữ liệu và thấu thiếu hành vi người dùng, hướng đến mục tiêu trở thành một trợ lý thông minh không thể thiếu với người Việt.

Đến nay, VinID đã triển khai nhiều mô hình và chức năng mới để bứt phá trở thành “siêu ứng dụng” giúp gắn kết mạng lưới toàn bộ hệ sinh thái của tập đoàn Vingroup.

Tích hợp nhiều tính năng riêng biệt, siêu ứng dụng VinID cho phép người dùng có thể:

  • Tích điểm, tiêu điểm trong hệ sinh thái Vingroup;
  • Mua hàng tươi sống thông qua tính năng Đi chợ online;
  • Ăn uống, mua sắm, nhận hàng tận nhà và tích điểm 7%;
  • Hưởng ưu đãi giảm giá mỗi ngày từ các thương hiệu lớn với VinID Voucher hay mua vé các sự kiện thể thao, giải trí nhanh chóng với VinID Ticket.
  • Sử dụng tính năng ví điện tử liên kết hệ thống 36 ngân hàng toàn quốc giúp người dùng dễ dàng mua sắm, thanh toán nhanh chóng, an toàn và tiện lợi.

Cùng với xu hướng phát triển mới, ví điện tử trên ứng dụng VinID ngày càng chiếm ưu thế hơn với những tiện ích đa dạng, phong phú, mang đến trải nghiệm tốt hơn cho người dùng.

Trở thành “mảnh ghép” tài năng của VinID – Cơ hội lớn cho lập trình viên phát triển sự nghiệp

VinID tìm kiếm nhân tài – Cơ hội đến với lập trình viên tài năng

Để các tiện ích trên siêu ứng dụng VinID được phát triển vượt trội và liên kết hệ thống sinh thái VinID một cách chặt chẽ, VinID liên tục chiêu mộ nhân tài công nghệ cùng góp sức.

Check ngay 2 “mảnh ghép” mà VinID đang tìm kiếm:

  • Product Owner không ngại khó với khả năng phân tích, tổng hợp vấn đề và đi đến những giải pháp tối ưu.
  • Back-end Engineer (Java/Golang) có từ 2 năm kinh nghiệm thực chiến, sẵn sàng chinh phục những dự án đầy thử thách.

VinID tự hào là nơi quy tụ anh tài, với các chuyên gia tại Việt Nam và từ quốc tế, đóng vai trò là mắt xích quan trọng đối với sự phát triển của công ty. Chính vì vậy, mỗi thành viên tại VinID đều được tạo điều kiện tối đa cho sự phát triển sự nghiệp, mang đến cơ hội thể hiện niềm đam mê và sức sáng tạo trong công việc.

Khám phá những đãi ngộ hấp dẫn tại VinID:

  • Mức lương cạnh tranh, xứng đáng với năng lực và công sức đóng góp;
  • Lương tháng 13 + thưởng thành tích, thưởng hiệu suất hậu hĩnh;
  • Được hưởng trọn ưu đãi khi sử dụng dịch vụ trong hệ sinh thái Vingroup: VinID, Vinmec, Vinpearl, Golf, Safari, Vinmart, Vinschool…
  • Được tham gia các khóa đào tạo chuyên sâu, nâng cao tay nghề, với cơ hội thăng tiến không giới hạn.

 Đồng thời trải nghiệm những điều thú vị đến từ tập đoàn hùng mạnh:

  • Được trực tiếp tham gia xây dựng siêu ứng dụng đẳng cấp quốc tế – VinID phục vụ cho mọi nhu cầu trong cuộc sống của người Việt;
  • Hòa mình vào môi trường làm việc tự do cho bạn thoải mái được là chính mình, tha hồ “vùng vẫy” với đam mê;
  • Làm việc trong không gian hiện đại cùng nhiều hoạt động, câu lạc bộ (bóng đá, chạy bộ,…), khu vực gym,… nâng cao sức khỏe.

Cơ hội mở ra trước mắt – Bạn còn chờ gì không mau chóng nhấn nút apply?

Xem ngay những tin đăng tuyển dụng IT mới nhất trên TopDev

Vai trò quan trọng của CTO (Chief Technology Officer)

Vai trò chính của giám đốc công nghệ là nhằm đảm bảo chiến lược phù hợp với mục tiêu chung của tổ chức/doanh nghiệp. Nhưng không có nghĩa, CTO sẽ chịu trách nhiệm giám sát bộ phận CNTT. Thay vào đó, điều họ thực hiện là pha trộn các nền tảng kiến thức về công nghệ của cá nhânkiến thức thông tin được cập nhật liên tục để cung cấp cho doanh nghiệp những giải pháp về chiến lược tốt nhất có thể. Có thể nói, CTO có một vai trò quan trọng cho sự gắn kết của công ty. Cùng TopDev phân tích sâu hơn tầm quan trọng của CTO qua bài viết sau đây.

CTO – Chief Technology Office là gì?

CTO – Giám đốc công nghệ (hay Giám đốc kỹ thuật) – là người giữ vị trí quản lý cấp cao trong một doanh nghiệp. Đồng thời, họ chuyên phụ trách các vấn đề về công nghệ và kỹ thuật; điều hành hoạt động nghiên cứu và phát triển (R&D). Thông qua việc giám sát chặt chẽ các nhu cầu ngắn và dài hạn, CTO sẽ đưa ra quyết định nhằm giúp tổ chức đạt được mục tiêu. Thường thì CTO sẽ làm việc trực tiếp với giám đốc điều hành (CEO) của công ty.

Nhân tố quan trọng thể hiện tiềm năng của sự gắn kết

Sự gắn kết của CTO được thể hiện khi chính họ theo dõi đội ngũ kỹ thuật. Họ cũng là người cung cấp các hướng dẫn cần thiết cho nhân viên. Đồng thời là người hỗ trợ việc đảm bảo sự tối ưu hóa về mặt công nghệ.

CTO

Không nhất thiết mọi công ty đều cần có CTO. Nhưng nếu bạn đang điều hành một công ty khởi nghiệp với tiềm năng phát triển lớn thì CTO thật sự quan trọng. CTO đích thị sẽ là một “trung tâm dữ liệu chính về công nghệ” đấy.

Vai trò của CTO được thay đổi tương ứng với khả năng phát triển của công nghệ. Tuy vậy, một điều khó thay đổi là CTO luôn tồn tại một tiềm năng về sự gắn kết mạnh mẽ. Dù tập trung rõ ràng vào công nghệ thông tin nhưng vẫn đảm bảo được sự phù hợp; khả năng hoạt động của tổ chức và không quá bị ám ảnh bởi “cuộc đua về công nghệ”. Dù tập trung vào việc xây dựng chiến lược – một khía cạnh nhỏ nhưng vẫn bám chặt vào bối cảnh phát triển chung của doanh nghiệp, tức bức tranh tổng thể lớn hơn.

CTO – “Người anh” dẫn dắt về tầm nhìn và phương hướng hoạt động

Điểm khác biệt đồng thời cũng là vai trò quan trọng của CTO là việc tập trung vào tương lai. Tức là những gì cần thực hiện và thực hiện như thế nào.

  6 xu hướng giúp định hình những nhà lãnh đạo nhân sự tương lai
  4 cách thúc đẩy sự phát triển nhân viên tại công ty

CTO

CTO có tầm quản lý các giải pháp công nghệ hiện tại của công ty. Họ cần nhận thức được các công nghệ mới và những bài toán nhiều khía cạnh về: nguồn lực, ngân sách,… để áp dụng các giải pháp mới nhằm giải quyết mọi vấn đề. Ngoài những trách nhiệm này, các CTO cần phải có tầm nhìn xa về định hướng của công ty. Họ đưa ra các phán đoán, đánh giá về các mục tiêu tổng thể. Từ đó, họ biết cách công nghệ sẽ được áp dụng như thế nào khi tiến hành các quyết định quan trọng.

Ví dụ, công việc hằng ngày của “người anh” này là tham gia vào quá trình thảo luận. Đó là cách đưa ra các quyết định thật sự quan trọng. Mục đích chính là làm rõ các xu hướng công nghệ; tính khả thi nếu tiến hành áp dụng chúng. Ngoài ra, CTO còn phải dẫn dắt về các tầm nhìn; phương hướng hoạt động của những bộ phận khác nhau trong doanh nghiệp.

CTO –  “Đại diện về công nghệ hướng ngoại”

Không thể đánh đồng CTO là phải code siêu giỏi. Bạn cần hiểu rằng đã là một CTO thì họ đều đã lăn xả ở nhiều vị trí. Và dĩ nhiên, khả năng code của họ không thể đùa được. Thật quá ngớ ngẩn để so sánh năng lực code của một CTO. Vì thực tế cho thấy rằng những điều CTO cần tập trung nhiều hơn thế.

Xem thêm: HR & IT – “Cuộc chơi” hoàn hảo cho việc thu hút và giữ chân nhân tài

CTO

Dường như việc code giỏi hay không không còn quá quan trọng với CTO. Họ sẽ là đại diện về công nghệ hướng ngoại. Tức là trở thành bộ mặt công nghệ cho chính công ty của mình. Điều này đồng nghĩa CTO sẽ người là tham dự các hội nghị có liên quan. Tại sao lại như vậy? Đơn giản là vì họ không chỉ nắm bắt được các tin tức công nghệ quan trọng, mà còn đại diện cho các sáng kiến ​​công nghệ của công ty.

Chính việc tham dự tại các hội nghị, hội thảo chuyên môn, trò chuyện ngoại giao có ý nghĩa rất lớn trong việc mở rộng mạng lưới mối quan hệ. Điều này thúc đẩy sự hợp tác về các mục tiêu, dự án và mở ra nhiều cơ hội, lợi thế lớn trong tương lai. Tất nhiên, sự hợp tác nào cũng dựa trên nguyên tắc cộng tác và bình đẳng về lợi ích.

Lời kết

CTO có một vai trò điều hành quan trọng đối với việc tập trung và phát triển các mục tiêu công nghệ dài hạn. Mỗi CTO của mỗi quy mô tổ chức cần nắm bắt đúng tình hình. Và hơn hết là tầm nhìn chiến lược. Điều này sẽ thúc đẩy sự phát triển công ty diễn ra một cách tốt nhất. TopDev hi vọng bài viết có mang lại nhiều giá trị cho bạn đọc về vị trí CTO – Chief Technology Officer.

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

Xem thêm Top Việc làm ngành it trên TopDev

Phân biệt sự khác nhau giữa C và C++

Phân biệt sự khác nhau giữa C với C++

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

Khi học lập trình, hẳn nhiều lúc bạn nhầm lẫn giữa ngôn ngữ lập trình C với C++. Nhiều lúc người ta viết gộp lại thành C/C++. Điều này sẽ khiến bạn hiểu nhầm rằng 2 ngôn ngữ này là một. Tuy nhiên thực tế không phải thế, bạn cần phân biệt rõ hai ngôn ngữ này bởi có những dự án phần mềm chỉ viết bằng ngôn ngữ C.

C và C++ là gì?

C và C++ là hai ngôn ngữ lập trình khác nhau.

C là ngôn ngữ lập trình hướng cấu trúc được ra đời trước C++.

C++ là ngôn ngữ lập trình thừa kế, mở rộng từ C. Do đó tất cả những gì đúng với C thì cũng đều đúng với C++. Đây cũng chính là lý do vì sau người ta hay gộp chung lại thành C/C++

>>> Xem thêm: Lộ trình học lập trình C cho người mới bắt đầu

Điểm giống nhau giữa C và C++

Chính vì C++ được mở rộng từ C nên điểm giống nhau của chúng sẽ là tất cả những gì có từ ngôn ngữ C:

  • Có cùng cú pháp và cách viết code.
  • Cấu trúc code giống nhau
  • Bộ biên dịch code giống nhau (không phải 100%, tuy nhiên các bộ biên dịch/compiler mới đều hỗ trợ cả 2 ngôn ngữ)
  • Mô hình bộ nhớ giống nhau và đều khá gần với phần cứng
  • Sử dụng chung các khái niệm như stack, heap, file-scope, static variables …

Nhiều vị trí tuyển dụng C++ đãi ngộ tốt trên TopDev

C khác gì C++?

Điểm khác nhau giữa C và C++ chính là những điểm mà C++ được mở rộng thêm. (Các mở rộng của C++ phần lớn nhằm tới mục đích lập trình hướng đối tượng)

Dưới đây là chi tiết các điểm khác nhau giữa C với C++

C C++
Phát triển bởi Dennis Ritchie từ 1969 tới 1973. Phát triển bởi Bjarne Stroustrup vào 1979.
Không hỗ trợ lập trình hướng đối tượng. Hỗ trợ lập trình hướng đối tượng như: đa hình, đóng gói, kế thừa, đối tượng
Đuôi mở rộng file c là .c Đuôi mở rộng file C++ là .cpp (dùng .c cũng được)
Là cha của C++ Là con của C. Code C có thể chạy bởi C++ nhưng code C++ không thể chạy bởi C.
Có 32 từ khóa Ngoài 32 từ khóa của C còn bổ sung thêm nhiều từ khóa mới
C is a function driven language because C is a procedural programming language. C++ is an object driven language because it is an object oriented programming.
Không hỗ trợ xử lý exception trực tiếp Hỗ trợ xử lý exception

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

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

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

Kinh nghiệm làm việc được tính như thế nào?

Kinh nghiệm làm việc được tính như thế nào?

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

Chào các bạn,

Chuyện là trong lúc rảnh việc ở công ty, anh em mình thường có văn hóa nghiên cứu công nghệ mới. Trong một lần nghiên cứu về NodeJS, vừa làm xong chương trình “Hello world” thì một người nói vui rằng “thế là biết NodeJS rồi đó, giờ có thể tự tin ghi vào CV là có kinh nghiệm làm việc với NodeJS rồi“. Cả team phá lên cười, vì ai cũng hiểu rằng chương trình “Hello world” là bài học vỡ lòng của developer chứ ai lại coi nó là kinh nghiệm làm việc.

Ủa vậy dư lào mới được coi là có kinh nghiệm làm việc, 6 tháng hay 1 năm, hay phải nhiều hơn? Đây chính là câu hỏi nảy ra trong đầu mình ngay sau khi cười sảng khoái, thế nhưng cũng quên bẫng đi cho tới ngày hôm nay.

I. KINH NGHIỆM LÀM VIỆC CÓ ĐƯỢC TÍNH BẰNG SỐ NĂM?

Số năm làm việc có lẽ là thước đo kinh nghiệm được sử dụng nhiều nhất. Bạn đồng ý với mình điều này chứ? Bởi chúng ta vẫn gặp các tin tuyển dụng dạng như “Tuyển dev trên 1 năm kinh nghiệm”, hay như trong CV chúng ta (cả mình) cũng thường viết rằng có X năm kinh nghiệm làm việc với công nghệ ABC nào đó.

Thế nhưng việc “cân đo” kinh nghiệm bằng số năm liệu có chính xác? Theo mình thì không, nó chỉ là cách nhanh nhất để mô tả kinh nghiệm của bạn tới đối phương mà thôi, chứ nó không thể hiện rõ kinh nghiệm của bạn.

Ví dụ anh A nói rằng có 2 năm kinh nghiệm code PHP, nhưng trong suốt 2 năm anh A chỉ quanh quẩn xây dựng mấy cái web demo, chỉ cần chạy được, chẳng bao giờ phải quan tâm tới việc tối ưu query database, tối ưu thời gian phản hồi, và lượng kiến thức anh sử dụng để code PHP trong 2 năm đó hoàn toàn có thể học được trong vòng 2 tháng. Còn anh B (anh Bình đó :D) mới chỉ có 1 năm kinh nghiệm code PHP, nhưng anh thường xuyên phải giải quyết bài toán “hóc búa”, deadline gấp, đòi hỏi tốc độ phản hồi nhanh nên anh học được thêm rất nhiều “thủ thuật” mới phục vụ cho việc code cũng như cách làm việc sao cho hiệu quả.

Vậy rõ ràng nếu lấy số năm làm thước đo kinh nghiệm thì anh A (2 năm KN) ăn đứt anh B (1 năm KN). Nhưng so sánh dưới góc độ lượng kinh nghiệm thực tế tích lũy được thì anh B lại ăn đứt anh A.

Trường hợp giống anh A như ví dụ trên mình gặp khá nhiều. Nhiều nhất là ở các bạn sinh viên mới ra trường. Bởi trong trường ĐH, các bạn ý được học lập trình từ năm 1, năm 2, vậy nghiễm nhiên sau khi ra trường là có 2 – 5 năm code. Có bạn còn tự tin nhận mình là senior developer, deal lương $1000 nhưng khi phỏng vấn thì trượt ngay ở mấy câu hỏi dành cho junior developer.

  Bỏ túi những kinh nghiệm đi thực tập hay dành cho lập trình viên!

II. KINH NGHIỆM NÊN ĐƯỢC TÍNH THẾ NÀO?

Không được tính bằng năm, vậy nên được tính bằng gì? Thật ra thì mình cũng không rõ là có thước đo “offical” nào cho kinh nghiệm hay không, nhưng mình biết một khái niệm là THANG CẤP ĐỘ TƯ DUY BLOOM.

Kinh nghiệm làm việc được tính như thế nào?

Thang cấp độ tư duy Bloom là khái niệm được nhắc nhiều trong giáo dục, được sử dụng để xây dựng các mục tiêu giáo dục, hệ thống hóa các câu hỏi, các bài kiểm tra, đánh giá quá trình học tập.

Tuy là thang đo được áp dụng trong giao dục, nhưng khi áp sang để làm thước đo kinh nghiệm làm việc thì mình cũng thấy cũng hợp lý. Bởi mỗi lần rút kinh nghiệm cũng giống như bạn vừa học xong một bài học vậy.

Thang cấp độ tư duy Bloom được chia làm 6 cấp độ (từ dễ tới khó).

Cấp độ – Tên Miêu tả
1 – Nhớ Có thể nhắc lại các thông tin đã được tiếp nhận trước đó
2 – Hiểu Nắm được ý nghĩa của thông tin, thể hiện qua khả năng diễn giải, suy diễn, liên hệ, khái quát
3 – Vận dụng Áp dụng thông tin đã biết vào một tình huống, điều kiện mới
4 – Phân tích Chia thông tin thành những phần nhỏ và chỉ ra mối liên hệ của chúng tới tổng thể
5 – Đánh giá Đưa ra nhận định, phán quyết của bản thân đối với thông tin dựa trên các chuẩn mực, tiêu chí
6 – Sáng tạo Xác lập thông tin, sự vật mới trên cơ sở những thông tin, sự vật đã có

6 Cấp độ trên được thể hiện từ dễ tới khó, tức là người ta có thể dễ dàng đạt được cấp 1, nhưng để đạt được tới cấp 6 thì phải trải qua một chặng đường dài.

Một ví dụ thể hiện kinh nghiệm làm việc với PHP qua 6 cấp độ của thang đo Bloom:

Cấp độ – Tên Ví dụ
1 – Nhớ Nhớ được toàn bộ cú pháp của PHP, các khái niệm trong PHP.
2 – Hiểu Hiểu được cách sử dụng PHP, như khi nào thì lấy dữ liệu bằng $_GET, khi nào thì lấy dữ liệu bằng $_POST, phân biệt được $_SESSION với $_COOKIE.
3 – Vận dụng Vận dụng PHP để xây dựng một website
4 – Phân tích Phân tích ưu nhược điểm của PHP.
5 – Đánh giá Đánh giá PHP phù hợp để giải quyết các bài toán như thế nào.
6 – Sáng tạo Sáng tạo ra công nghệ mới giúp khắc phục nhược điểm của PHP.

Quay trở lại trường hợp code chương trình “Hello World” trên NodeJS mà mình nhắc tới ở đầu bài viết, thì mình mới chỉ đạt tới cấp độ “Nhớ” – cấp độ thấp nhất trong 6 cấp, cũng chẳng có gì to tát lắm và đấy cũng là lý do khiến cả team cười.

III. LỜI KẾT

Bài viết này mình muốn nhắn nhủ rằng “Kinh nghiệm thì không nên tính bằng số năm”, cũng như chia sẻ về 6 cấp độ tư duy Bloom để chúng ta cùng tự đánh giá lại bản thân, xem kinh nghiệm làm việc của mình thật sự đang ở đâu. Nếu kinh nghiệm ở khía cạnh nào cũng đạt mức 5 mức 6 mà công ty trả lương bèo quá thì có thể đề xuất tăng lương. Hay trước giờ luôn ảo tưởng sức mạnh tưởng mình là best nhưng thực ra không phải vậy thì nên khiêm tốn và chịu khó học hỏi thêm.

Bài viết được viết dựa trên kinh nghiệm và quan điểm cá nhân, sẵn sàng nhận mọi gạch đá.

Cảm ơn bạn đã đọc hết bài viết. Chào tạm biệt.

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

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

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

Ai cũng có thể viết code … tồi

Ai cũng có thể viết code ... tồi

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

Viết code không khó.

Một đoạn code Python với logic tầm thường ai cũng có thể viết, nhưng việc viết sao cho tốt thì hãy thử xem…

  "Code dễ đọc" là như thế nào?
  Vừa học vừa chơi! Top 15+ game lập trình miễn phí

Function get_groups(name) nhận vào 1 string, tìm kết quả ở 1 nguồn dữ liệu, và trả về kết quả cần thiết. Đây là một phiên bản ai cũng viết được:

def get_groups(name):

    all_groups = get_data_from_source()

    groups = []
    if name:
        for group in all_groups():
            if name.lower() in group['name'].lower():
                groups.append({group['name']: group['id']})
    else:
        # if user provide empty string, return list customers as default
        for group in all_groups():
            if 'customer' in group['name'].lower():
                groups.append(group['name'])

    if len(groups) > 0:
        return groups
    else:
        return "Group {} not found in groups".format(name)

Đoạn code nhìn qua tốt, chuẩn pep8, pythonic (for group in all_group() chứ không dùng range), tên đặt cũng dễ hiểu. Nhưng hãy xem thật kỹ code, nghĩ xem có gì không tốt trước khi đọc tiếp.

… … …

Function này trông có vẻ ổn, cho đến khi ta gọi function này và xử lý kết quả của nó:

  • nó có thể trả về 1 string, khi không tìm thấy
  • nó có thể trả về list của các dictionary, nếu người dùng đưa vào name khác rỗng
  • nó có thể trả về list của các string, nếu người dùng đưa vào string rỗng

Ai cũng có thể viết function, nhưng function trả về 3 kiểu dữ liệu khác nhau như vậy thì chỉ làm cho người dùng nó thêm khổ. Người gọi function này sẽ phải xử lý cả 3 trường hợp, hãy thử xem function sau là function DUY NHẤT gọi get_groups:

def handle_group_search(name):
    result = get_groups(name)

    if isinstance(result, str):
        print(str)
    else:
        groups = []
        if isinstance(result[0], dict):
            groups = [list(d.items())[0][0] for d in result]
        else:
            groups = result

    for n in result:
         print(n.lower())

Trước tiên, code này cũng phải rẽ 3 nhánh để xử lý 3 loại đầu ra khác nhau của get_groups. Người dùng function này không có cách nào khác ngoài đọc code để hiểu function sẽ làm gì.

Lập trình viên sẽ viết code rất khổ, nếu có những function như get_groups() có trên hệ thống. Giải pháp? Viết lại function này đảm bảo một tiêu chuẩn:

Mỗi function chỉ trả về 1 kiểu dữ liệu.

Nếu get_groups trả về [] hoặc 1 list chứa danh sách các tên của group, code gọi nó chỉ còn lại :

def handle_group_search(name):
    result = get_groups(name)

    if not result:
        print('Not found name {} in groups'.format(name))
    else: 
        for n in result:
            print(n.lower())

Một lý do khác mà get_groups là một function rất tệ, nó dùng kiểu dict để nhóm dữ liệu (group:id) rồi nhét vào list. Khi dữ liệu lưu vào dict mà không để tìm kiếm hay không có key cố định, nó chỉ là một nỗi đau. Để lọc ra name của groups, code sử dụng đã phải viết:

    groups = [list(d.items())[0][0] for d in result]

code trên biến dict 1 phần tử thành 1 list và truy cập lấy tên của key:

In [1]: d = {'Pymi': 17}

In [2]: list(d.items())
Out[2]: [('Pymi', 17)]

In [3]: list(d.items())[0]
Out[3]: ('Pymi', 17)

In [4]: list(d.items())[0][0]
Out[4]: 'Pymi'

Bạn thậm chí có thể viết dài hơn thế:

    groups = []
    for d in result:
        name = []
        for k, v in d.items():
            name.append(k)
        groups.extend(name)

Nếu get_groups trả về list của các tuple, code chỉ cần:

groups = [group[0] for group in result]

Thậm chí có thể tốt hơn nếu dùng namedtuple. (i.e: group.name)

Nếu nó trả về list cả các dict có key cố định, code chỉ cần:

groups = [d['name'] for d in result]

Lựa chọn kiểu dữ liệu phù hợp với mục đích sử dụng, chính là điều khiến code của bạn trở nên đẹp hơn, dễ hiểu hơn, dễ xử lý hơn.

Code không chỉ là kỹ thuật, code còn là một nghệ thuật. Và người tạo ra bug chính là nghệ sỹ.

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

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

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

Một số lầm tưởng về big data của software engineer

Một số lầm tưởng về big data của software engineer

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

Chào các bạn,

Bạn biết đấy mình đang tìm hiểu về big data trong thời gian này. Tuy cũng chưa được nhiều, nhưng bằng bấy nhiêu đã khiến mình nhận ra rằng trước giờ mình đã hiểu sai về big data. Nguyên nhân chủ yếu khiến mình nhìn nhận sai là do mình đang tìm hiểu nó dưới cái nhìn của một software engineer thay vì là một data engineer.

  26 công cụ và kỹ thuật trong Big Data có thể bạn chưa biết
  Dữ liệu lớn (Big Data) là gì? Đặc điểm và ứng dụng của Big Data

Trên blog phambinh.net, các bạn đọc giả chủ yếu cũng là software engineer hoặc có định hướng trở thành software engineer, để tránh các bạn bị hiểu sai về big data như mình, nên mình viết bài viết này để chia sẻ với các bạn những lầm tưởng của mình về big data trước kia.

1. COI DATABASE NẶNG LÀ BIG DATA

Mình thường chỉ làm việc với những database (mysql) có table tầm 1tr records đổ lại. Tổng dung lượng database cũng chỉ xấp xỉ 1GB. Đương nhiên đây đều là các database trên môi trường dev, còn database trên môi trường production thì nặng hơn, có điều mình … lại chưa được làm việc với database của production bao giờ.

Vì vậy mà khi tiếp tục với những database nặng cỡ tầm 50GB – nó thật sự khiến mình cảm thấy bối rối vì chưa làm việc với những database nặng như vậy bao giờ. Mình nghĩ với lượng dữ liệu thế này chắc không thể áp dụng những cách truyền thống được để giải quyết được, mà cần phải áp dụng các công nghệ của big data vào để xử lý.

Chú thích thêm: Trước đó mình chưa từng tìm hiểu thế nào là big data mà chỉ tự nghĩ rằng big là lớn, data là dữ liệu, vậy big data là dữ liệu lớn, mà cỡ 50GB thì là là lớn rồi. Cho nên auto hiểu luôn database 50GB là big data.

Cho tới khi mình tìm hiểu được big data là gì, thì mình mới thay đổi quan điểm này. Nhắc lại chút thì big data sẽ phải đáp ứng được 3V là: Volume – Variety – Velocity (Dung lượng – Độ đa dạng – Tốc độ). Trong khi đó 50GB vẫn có thể lưu ngon trên một máy tính – chưa đáp ứng được tiêu chí về Volume, database thì thường là có cấu trúc hoặc bán cấu trúc – chưa đáp ứng được tiêu chí về Variety.

Vì vậy bạn nào mà có quan điểm này giống mình thì thay đổi đi nha, 50GB vẫn còn nhỏ lắm, chỉ cần biết tối ưu chút thì với cách xử lý truyền thống vẫn xử lý phà phà.

2. COI BIG DATA LÀ SKILL CỦA SOFTWARE ENGINEER

Một số lầm tưởng về big data của software engineer

Bạn có nhìn thấy big data ở đâu không? Nó nằm ở giữa data engineer và data scientist chứ không hề liên quan tới software engineer. Điều này có nghĩa là bạn có thể yên tâm phát triển trên con đường trở thành software engineer mà không cần phải bận tâm tới big data nếu như bạn không thích nó.

Đương nhiên là bức ảnh trên cũng có phần quá đát (date) rồi, nhưng mình cũng có tham khảo qua nhiều tin tuyển dụng về software engineer thì không thấy có yêu cầu nào cần skill liên quan tới big data cả. Nếu như có tin tuyển dụng nào cần tới big data hay các công cụ xoay quanh big data như hadoop thì đều là tin tuyển data engineer.

Software engineer vs Data engineer

Software engineer là người tạo ra phần mềm, mỗi phần mềm sẽ đóng góp dữ liệu trong quá trình nó hoạt động vào một cái ao chung tạm gọi là Big data. Data engineer sẽ sử dụng dữ liệu trong cái ao này để thực hiện một yêu cầu nào đó dạng như: xuất báo cáo, vẽ biểu đồ, trích xuất dữ liệu để train cho model AI, trích xuất dữ liệu để làm database cho một ứng dụng khác,…

Data engineer sẽ sở hữu một ngách skill của software engineer và có không ít trong số họ đi lên từ software engineer.

3. NGHĨ RẰNG NGƯỜI DÙNG THÔNG THƯỜNG SẼ QUAN TÂM TỚI OUTPUT CỦA BIG DATA

Như mình đề cập ở trên, output của việc xử lý big data thường là một báo cáo, một tập tiêu chí và chỉ số, hay một tập dữ liệu nào đó, và dữ liệu khá vô nghĩa với người sử dụng thông thường.

Người dùng thông thường ở đây ám chỉ những người dùng mà cả hệ thống đang hướng tới và khai thác, như khách hàng mua hàng trên tiki, người dùng facebook, người dùng youtube,…

Ví dụ, một khách hàng mua hàng trên tiki sẽ chẳng quan tâm tới biểu đồ doanh thu của công ty trong 1 năm qua, họ chỉ quan tâm tới sản phẩm họ mua có tốt không và nhận hàng trong bao lâu. Một người đi xem phim hành động, họ chẳng quan tâm tới việc thể loại đó được bao nhiêu người khác quan tâm, họ chỉ quan tâm tới việc làm sao để mua vé mà không phải đứng đợi…

Output của big data thường là input của một ứng dụng khác, hoặc được sử dụng để ra quyết định thực hiện một chiến lược kinh doanh nào đó. Khác với output của các phần mềm do software engineer tạo ra, nó hướng trực tiếp tới người sử dụng thông thường.

4. “HIỆU NĂNG” CỦA BIG DATA GIỐNG VỚI “HIỆU NĂNG” CỦA PHẦN MỀM

Khi mình tìm hiểu về các công cụ xử lý big data, thỉnh thoảng sẽ gặp câu kiểu như “công nghệ XXX cho phép xử lý big data với hiệu năng cao“.

Xuất phát từ một software engineer, mình cho rằng hiệu năng ở đây ám chỉ tốc độ thực hiện rất nhanh, nhưng không phải. Cụm từ “hiệu năng” trong big data sẽ được hiểu là có khả năng tính toán trên một tập dữ liệu rất lớn, với độ chính xác cao, còn thời gian thì có thể là một vài tiếng hoặc thậm chí cả ngày mới ra kết quả cũng không sao.

Khi xử lý big data, yếu tố chính xác và đầy đủ thông tin được đặt lên hàng đầu, thời gian thì có thể đợi được.

5. TỔNG KẾT

Kể ra mới thấy góc nhìn của software engineer khác rất nhiều so với góc nhìn của data engineer, nhưng cũng may là mình đã sớm nhận ra chứ không cứ lao đầu học data theo hướng học lập trình thì có ngày sẽ đi vào ngõ cụt mất.

Một bài viết ngắn ngọn chia sẻ tới các bạn, hy vọng sẽ giúp ích cho cộng đồng.

Hẹn gặp lại.

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

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

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

Bí quyết giúp chinh phục mức lương mơ ước cho ngành IT

ngành IT

Ngành IT được xem là một ngành có mức lương khá ổn định. Nhưng theo bạn, đâu là mức lương đáng mơ ước? Mặt khác, sự thăng tiến về việc phát triển nghề nghiệp là điều mà bất kỳ nhân viên nào cũng mong muốn đạt được. Nhiều người thường suy nghĩ: Tại sao bản thân làm hoài nhưng vị trí vẫn thế? “Lúa” nhận vẫn lẹt đẹt là sao? Bao lâu nữa mình mới đạt được mức lương mơ ước?

Với những trải nghiệm từ thực tế, TopDev xin chia sẻ cho bạn về một số bí quyết để bạn có thể đạt được mức lương “xịn xò” nhé! 

Sự nắm bắt – Yếu tố quyết định sự thành công về lương

Dù ra trường với mức lương nào, bạn cũng phải nghiêm túc cần mẫn. Điều quan trọng lúc này là bạn luôn phải không ngừng học hỏi, chăm chỉ để hoàn thiện khả năng.

  Để thăng tiến, cần phải có chiến lược!

  Những lý do làm kìm hãm sự thăng tiến của bạn
 

ngành IT

Bước tiếp theo là xác định định hướng về vị trí của sự tăng tiến. Ví dụ, bạn muốn từ junior lên senior, từ nhân viên lên team leader. Hãy thử sức trải nghiệm nhiều dự án lớn nhỏ khác nhau. Đây là sự nắm bắt về một quỹ đạo phát triển chung của con đường/lộ trình thực tế về kinh nghiệm. Khi có kinh nghiệm, không ai từ chối trả lương cho bạn cả.

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

3 gợi ý giúp bạn tăng lương trong ngành IT 

TopDev sẽ gợi ý 3 cách giúp bạn dễ dàng tăng lương nhất trong ngành IT (có thể là một freelancer IT.) Đó là thăng chức, nhảy việclàm việc ở thị trường quốc tế.

Nếu cứ mãi làm ở một công ty, lương bạn sẽ tăng rất chậm. Có thể chỉ tăng từ 5-10% mỗi năm hoặc từ 20-40% nếu bạn được lên chức. Vì thế bạn có thể nên nhảy việc để đạt được mức lương mơ ước. Tuy nhiên, nhiều công ty vẫn có chế độ phúc lợi ổn định. Đồng thời, việc xây dựng lộ trình phát triển cho mỗi nhân viên ngày càng được quan tâm. Tất cả là do sự nhìn nhận của bạn về vị trí, mong muốn và chính năng lực hiện tại. Khi có sự nắm bắt tốt, bạn có một quyết định thông minh và phù hợp nhất.

Việc thăng chức và làm việc ở môi trường nước ngoài cũng tương tự. Nó thuộc về phần trăm bạn tự nắm bắt lấy cơ hội. Việc tận dụng và phát huy cũng rất quan trọng. Do vậy, hãy chuẩn bị cho mình những kiến thức, kỹ năng và sự trải nghiệm đủ “sức nặng” để có thể chớp lấy các cơ hội.

Điều quan trọng cần ghi nhớ: Hãy khiến bản thân trở nên “đắt giá” hơn

Không ai có thể từ chối trả cho bạn nhiều tiền khi bạn đã nỗ lực thay đổi. Điều đó khiến bạn biết cách khiến mình “có giá” hơn. Và là một nhân tố quan trọng cho bộ phận nhân sự của công ty.

Xem thêm: Băn khoăn ngành lập trình: Lựa chọn nào ở ngưỡng 30?

ngành IT

Đừng quá áp lực về công việc. Cũng đừng OT nhiều mà bỏ mặc sức khỏe. Việc biết cách cân bằng và hiểu giới hạn bản thân là điều đầu tiên trong hành trình thay đổi để làm bản thân có giá trị hơn. 

Vậy làm thế nào để bản thân “có giá” hơn? 

Đầu tiên, nếu bạn muốn nhận được một mức lương cao hơn thì tất nhiên là bản thân phải đảm nhận nhiều trách nhiệm hơn, làm những việc khó hơn, đòi hỏi kỹ năng và kinh nghiệm nhiều hơn. Đó có thể là những task/project to bự, siêu khủng đến từ đối tác, các hợp đồng lớn,… hay là những vấn đề trong việc trực tiếp thực hiện công tác đào tạo và phát triển năng lực các nhân viên với tư cách bạn là người quản lý, giám sát, Team Leader, Mentor,… Freelancer IT

Xem thêm: Mức lương lập trình viên 2022: Bạn xứng đáng mức lương bao nhiêu?

Tiếp theo đó là việc không ngừng nâng cao trình độ của bản thân thông qua việc tiếp thu, học hỏi. Cụ thể đó là những công nghệ, kỹ thuật mới, các kỹ năng mềm để có nền tảng tốt đồng thời update những cái mới phù hợp với xu hướng phát triển chung của thời đại công nghệ số. Nếu nói sâu một chút thì sẽ là rèn luyện kỹ năng code tốt hơn, học tiếng anh và tự trau dồi kiến thức tổng hợp. Đó là những thứ khiến bạn trở nên khác biệt so giữa nhiều nhân viên, hãy cố gắng vì mọi nỗ lực đều sẽ được ghi nhận.

Trạm dừng của cuộc sống không phải là tiền: Đừng theo đuổi ngành vì lương

Vấn đề lương bổng thật sự rất quan trọng. Nó là yếu tố quyết định việc bạn có lựa chọn đồng hành lâu dài cùng ngành nghề ấy hay không. Tuy vậy, sẽ đến một lúc nào đó bạn chợt nhận ta tiền sẽ không còn là tất cả. Nói như vậy không có nghĩa là bạn lại chìm đắm trong mộng tưởng về một thế giới tràn ngập sự hạnh phúc. Lương vẫn là thứ giúp bạn duy trì cuộc sống nhưng đừng quá bị nó ám ảnh.

 

Hãy thật sự đam mê, đủ những nhiệt huyết để theo đuổi một ngành nào đó. Đừng theo ngành chỉ vì nghĩ nó mang lại cho mình nhiều tiền. Cái gì cũng cần có sự đánh đổi cả. Nếu theo ngành IT (Freelancer IT) chỉ vì ham mức lương chục triệu như cách mà những định hướng, dẫn dắt của báo chí truyền thông đang thực hiện thì bạn sẽ sớm vỡ mộng thôi. Ai sẽ trả mức lương quá cao khi bạn còn nhiều thiếu sót về kinh nghiệm. Thậm chí là chưa kể đến việc hàng tá những áp lực bủa vây ngành IT hay Freelancer IT mà bạn cần phải đối mặt.

Ngược lại, nếu thật sự đam mê, bạn sẽ thấy cái sự code nó không hề mệt mỏi. Bạn sẽ có động lực tiếp thu những công nghệ mới; thích gặp gỡ những gương mặt, tên tuổi đầu ngành để học hỏi để gia tăng mối quan hệ. Tất cả đều giúp ích cho sự nghiệp phát triển của bạn về năng lực. Vì thế, đừng vội vàng mà hãy là một người luôn nỗ lực nhé! 

Lời kết

Nếu đã yêu thích và sẵn sàng lăn xả để đạt đến mục đích thành công trong bất kỳ ngành nghề nào thì bạn hãy trau dồi và rèn luyện những kiến thức, kỹ năng cần thiết ngay từ khi xác định nhé. Điều quan trọng là biết được mình mong muốn gì. TopDev chúc bạn sẽ thành công trên con đường phát triển nghề nghiệp của mình.

Đồng thời (Concurrency) và song song (Parallelism) khác nhau như thế nào?

Đồng thời (Concurrency) và song song (Parallelism) khác nhau như thế nào?

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

Rất nhiều người trong chúng ta đã nhầm lẫn hoặc mơ màng về 2 thuật ngữ đồng thời (Concurrency) và song song (Parallelism), thực ra 2 thuật ngữ này  rất khác biệt đồng thời không phải là song song (concurrency is not parallelism), vậy nó khác biệt nhau như thế nào?

  • Concurrency is about dealing with lots of things at once. 
  • Parallelism is about doing lots of things at once.

Chúng ta hãy dành ra ít phút để chiêm nghiệm về  2 từ dealing (sự thỏa hiệp) và doing (làm) trong 2 câu trên nhé, nó khá rối nhưng cũng không kém phần thú vị.

  10 xu hướng ứng dụng di động dự đoán sẽ thống trị năm 2024
  8 npm mẹo cực hay để gây ấn tượng với đồng nghiệp

Concurrency

Concurrency is about dealing with lots of things at once. 

Nó có ý nghĩa là trong một khoảng thời gian nào đó chúng ta có nhiệm vụ phải thực hiện và hoàn thành nhiều công việc, tuy nhiên chúng ta chỉ có thể thực hiện một công việc duy nhất tại một thời điểm ví dụ Trong khoảng thời gian 5 phút cuộc đời, chúng ta vừa code vừa lướt facebook để xem hình crush sự tập trung của chúng ta đã bị chi phối cực độ, chúng ta code được vài giây rồi lại xem hình crush mất vài phút sau đó lại quay lại code rồi lại xem hình crush, 5 phút cuộc đời trôi qua chúng ta đã làm được cho cuộc đời này là code và xem hình crush. Như vậy chúng ta đã làm 2 việc đồng thời (concurrency) trong một khoảng thời gian nào đó.

Đối với các chương trình máy tính cũng vậy các bạn có thể thấy hình bên dưới mô tả về đồng thời (concurrency) một CPU đang thực hiện 2 nhiệm vụ là Task 1 và Task 2  thì CPU sẽ xử lý Task 1 trong khoảng thời gian nào đó rồi lại quay sang xử lý Task 2 và cứ luân phiên đến khi hoàn thành cả 2 Task.

Paralellism

Parallelism is about doing lots of things at once

Nó có ý nghĩa là chúng ta có 2 hoặc nhiều nhiệm vụ phải làm trong một khoảng thời gian, cụ thể ở đây chúng ta có 2 nhiệm vụ và 2 nhiệm vụ đó sẽ được thực hiện một cách song song mà không có sự ngắt quảng.

Chúng ta là con người có một bộ não duy nhất để điều khiển các bộ phận khác trên cơ thể nên có ai vừa có thể vừa cột dây giày vừa đội mũ được không hay là vừa nghĩ đến crush và vừa nghĩ đến người yêu cũ cùng lúc trừ khi chúng ta có thêm đôi tay để vừa đội mũ vừa cột dây giày và có thêm 1 bộ não nữa để có 2 não 1 não nghĩ về crush và não còn lại sẽ nghĩ về người yêu cũ, kiểu đó giống như 3 đầu 6 tay thì mới làm được những điều song song (parallelism) như thế.

Cũng giống như với máy tính CPU giống như bộ não, để xử lý nhiều công việc một cách song song (parallelism) thì nó cần có thêm não là sẽ có thêm CPU, các bạn có thể xem ví dụ parallelism ở hình bên dưới có 2 CPU, CPU 1 xử lý cho Task 1 và CPU sẽ xử lý cho Task 2 một cách song song.

Dưới đây là hình ảnh về đồng thời (Concurrency) và song song (Parallelism).

Lý do tại sao tạo nhiều luồng chạy song song (Parallelism) mà vẫn không cải thiện được hiệu suất?

Tạo nhiều task vụ chạy song song thì phải xem phần cứng số core có đáp ứng được hay không, khi phần cứng chỉ chạy được 2 luồng mà chúng ta tạo ra 10 luồng thì tốc độ vẫn vậy là đúng rồi, khi mà phần cứng đáp ứng được 4 luồng mà chúng ta mới chạy mới có 2 luồng thôi, sau đó tạo thêm 2 luồng nữa thì sẽ thấy hiệu suất thay đổi, còn không thì vẫn vậy à.

Tóm lại:

Con người được tạo hóa ban tặng là chỉ có thể thực hiện công việc một cách đồng thời (concurrency) thôi.

Vậy đối với con người nếu muốn làm tốt một việc gì đó đạt hiệu suất cao nhất thì chúng ta hãy tập trung làm việc đó thôi chứ đừng code và xem hình crush sẽ không code tốt lắm đâu.

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

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

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

Hướng dẫn dùng biến trong CSS để làm dark/light mode

Hướng dẫn dùng biến trong CSS để làm dark/light mode

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

Cách đây mười năm, nếu bạn hỏi mình có thể đặt biến trong CSS thì câu trả lời sẽ là KHÔNG, bạn cần viết bằng các ngôn ngữ như SCSS, LESS để có thể xài biến.

Còn trong năm 2022, thì câu trả lời sẽ là CÓ.

Tại sao chúng ta lại muốn đặt biến màu sắc kích thước? Để khi chúng ta muốn thay đổi bộ mặt một website từ xanh lá chuối sang đỏ rực lửa, chỉ cần “búng tay” là có liền.

  5 điều phiền toái nhất của CSS
  Cách làm các slide và các hiệu ứng hover do JavaScript và CSS tạo ra

Ví dụ chúng ta theo trào lưu “light và dark theme” cho website, user có thể chọn kiểu sáng-sạch-sẽ hay đen-đuông-đuốc

Hướng dẫn dùng biến trong CSS để làm dark/light mode

Cú pháp đặt biến trong CSS, bắt đầu bằng dấu --, sau đó là tên biến

:root {
    --my-background-color: #fff;
    --heading-1-font-size: 15em;
    --another-variable: 20px;
}

Ví dụ sử dụng những biến đã khai báo

h1 {
    background-color: var(--my-background-color);
    font-size: var(--heading-1-font-size);    
}

Chúng ta đưa tất cả những giá trị cần thay đổi khi switch qua lại giữa 2 mode dark/light vào các biến số bên trong body

// Light theme
body {
    --bg-color: #F3F7F9;
    --bg-content-color: #fff;
    --bg-code: #fffbf3;
    --body-color: #444;
    --title-color: #111;
    --link-color: #6b17e6;
    --border-color:  rgba(0,0,0,.1);
    --space: 3.5rem;
    --content-width: 860px;
    --header-height: 80px;
    --radius: 5px;
}

Khi thay đổi giá trị sang dark mode

// Dark theme
body[data-theme="dark"] {
 	--bg-color: #0D2538;
 	--bg-content-color: #0f2d44;
 	--bg-code: rgba(0,0,0,.3);
 	--border-color:  rgba(255,255,255,.1);;
 	--body-color: #ced8de;
 	--title-color: #fff;
 	--link-color: #af9cef;
}

Chúng ta sẽ thêm một số hàm cần thiết vào trong window

// Mượn xài đỡ của overreacted.io
(function() {
    window.__onThemeChange = function() {};
    function setTheme(newTheme) {
        window.__theme = newTheme;
        preferredTheme = newTheme;
        document.body.setAttribute('data-theme', newTheme);
        window.__onThemeChange(newTheme);
    }

    var preferredTheme;
    try {
        preferredTheme = localStorage.getItem('theme');
    } catch (err) { }

    window.__setPreferredTheme = function(newTheme) {
        setTheme(newTheme);
        try {
            localStorage.setItem('theme', newTheme);
        } catch (err) {}
    }

    var darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
    darkQuery.addListener(function(e) {
        window.__setPreferredTheme(e.matches ? 'dark' : 'light')
    });

    setTheme(preferredTheme || (darkQuery.matches ? 'dark' : 'light'));
})();

Thao tác cuối cùng là một đoạn JS để trigger việc đổi mode

// Ví dụ hàm xử lý onClickChangeTheme sẽ được gắn vào một button

function onClickChangeTheme(mode = 'dark') {
  window.__setPreferredTheme(mode);
}

Chúng ta cũng có thể check được theme mà user đã chọn trước đó

 if (window.__theme == 'dark') // làm gì đó thật vi diệu

Kỹ thuật là như vậy, còn nếu bạn hỏi mình sẽ cập nhập trang blog này cho có 2 mode light/dark theme? Mình sẽ không làm, một số website như trang của mình thì việc switch màu như vậy không đem lại nhiều giá trị cho người đọc.

Bài viết gốc được đăng tải tại Vui Lập Trình

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

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

Project Manager là gì? Công việc của Project Manager

Project Manager là gì

Project Manager là gì? Có vai trò như thế nào trong một dự án? Bài viết dưới đây TopDev sẽ giới thiệu cho bạn rõ hơn về khái niệm PM là gì?

Project Manager là gì?

Project Manager (Quản lý dự án) là người chịu trách nhiệm lập kế hoạch, deadline, ngân sách và tài nguyên cho dự án. Họ đảm bảo rằng dự án hoàn thành đúng thời hạn, trong ngân sách và đạt được các mục tiêu đặt ra.

PM cũng là người chịu trách nhiệm toàn phần cho dự án, đảm bảo mọi người đang hoàn thành tốt nhiệm vụ được giao, theo dõi, báo cáo và update tiến trình và làm việc chủ yếu với các Leader Project.

tuyển dụng it
Project Manager là gì

Project Manager là người luôn là người có thể cân bằng mọi thứ nhưng họ không phải là người truyền động lực, theo dõi giúp đỡ sát sao từng thành viên như Leader Project hay Scrum Master nhưng lại có chung mục tiêu là hoàn thành tốt dự án được đề ra từ trước. Trong một số công ty, doanh nghiệp nhỏ 2 vị trí này hầu như được gộp lại làm 1 để tiết kiệm nhân lực.

  Khám phá sức hút Ekino – điểm dừng chân đáng mơ ước của các Technical Project Manager
  Mẫu bảng mô tả công việc Project Manager

Vai trò và nhiệm vụ của Project Manager

Vai trò của Project Manager

Project Manager đóng vai trò chủ trì trong việc lập kế hoạch, thực hiện, giám sát, kiểm soát tiến trình cho đến khi kết thúc các dự án. Vai trò chính của Project Manager là người có thể phân chia công việc hợp lý, cụ thể đến từng cá nhân, nhóm để có thể hoàn thành tốt được dự án đã đề ra theo đúng yêu cầu, tiến độ, đảm bảo các bước tiến hành luôn thuận lợi. Vai trò của người quản lý dự án có thể kết thúc khi đã hoàn thành dự án được giao.

Nhiệm vụ của PM

Nhiệm vụ của Project Manager bao gồm quản lý tổng thể nhưng họ hiếm khi trực tiếp tham gia vào các hoạt động thực sự tạo ra kết quả cuối cùng của sản phẩm. Project Manager cũng giám sát mọi dự án liên quan, các công cụ và kỹ thuật của dự án để đảm bảo dự án hoạt động tốt. 

Lập kế hoạch dự án

PM có trách nhiệm xác định mục tiêu dự án dựa trên yêu cầu từ các bên liên quan. Họ xây dựng kế hoạch chi tiết, bao gồm phân bổ nguồn lực, lịch trình, ngân sách, và các phương pháp để hoàn thành từng hạng mục. Việc đánh giá và quản lý rủi ro cũng là một phần quan trọng trong nhiệm vụ của PM, giúp chuẩn bị các biện pháp đối phó với những rủi ro tiềm ẩn.

Điều phối và quản lý nguồn lực

PM cần quản lý các nguồn lực của dự án như nhân sự, tài chính và trang thiết bị một cách hiệu quả. Việc phân công công việc cho các thành viên trong nhóm và theo dõi hiệu suất của từng cá nhân giúp đảm bảo rằng mọi nhiệm vụ đều được thực hiện đúng tiến độ và chất lượng. PM còn phải điều chỉnh nguồn lực linh hoạt khi có sự thay đổi hoặc khi phát sinh vấn đề mới.

Theo dõi và kiểm soát tiến độ

Trong suốt quá trình thực hiện dự án, PM phải giám sát tiến độ công việc hàng ngày, đảm bảo rằng mọi hoạt động đều được thực hiện theo đúng lịch trình. Khi có vấn đề phát sinh, PM cần nhanh chóng nhận diện và đưa ra các giải pháp kịp thời để tránh làm ảnh hưởng đến toàn bộ dự án. Bên cạnh đó, PM cũng phải đảm bảo rằng dự án luôn tuân thủ theo ngân sách đã được phê duyệt.

Quản lý giao tiếp

PM đóng vai trò cầu nối giữa nhóm dự án và các bên liên quan như khách hàng, nhà đầu tư, hoặc các đối tác. Nhiệm vụ của PM là đảm bảo thông tin được truyền đạt một cách minh bạch, rõ ràng, và liên tục giữa các bên. Điều này giúp duy trì sự hiểu biết chung về tiến độ dự án, các thay đổi, hoặc bất kỳ rủi ro nào có thể ảnh hưởng đến kết quả.

Quản lý rủi ro và thay đổi

PM cần có kỹ năng nhận diện, đánh giá và kiểm soát các rủi ro trong suốt quá trình thực hiện dự án. Điều này đòi hỏi sự linh hoạt trong việc điều chỉnh kế hoạch và các giải pháp sáng tạo để xử lý các tình huống không lường trước. Việc quản lý thay đổi, bao gồm các yêu cầu mới từ khách hàng hoặc sự điều chỉnh trong phạm vi dự án, cũng là một nhiệm vụ quan trọng mà PM cần xử lý.

Kiểm soát chất lượng

PM phải đảm bảo rằng mọi sản phẩm hoặc dịch vụ được tạo ra trong quá trình thực hiện dự án đều đáp ứng các tiêu chuẩn chất lượng đã đề ra. Điều này đòi hỏi sự theo dõi chặt chẽ trong suốt quá trình sản xuất và thực hiện, cũng như việc kiểm tra kết quả cuối cùng trước khi bàn giao.

Hoàn thiện và bàn giao dự án

Khi dự án hoàn thành, PM có trách nhiệm tổng kết và đánh giá hiệu quả công việc, đồng thời thực hiện các quy trình bàn giao sản phẩm cuối cùng cho khách hàng hoặc các bên liên quan. Điều này bao gồm việc đảm bảo tất cả các hạng mục được hoàn thành theo yêu cầu và không còn vướng mắc nào. PM cũng phải ghi nhận các bài học kinh nghiệm từ dự án để cải thiện cho các dự án tương lai.

Project Manager là gì
Project Manager là gì

Yếu tố để trở thành một Project Manager giỏi

Để trở thành một Project Manager giỏi thì cần có sự hiểu biết về việc:

  • Lập kế hoạch dự án từ khi hình thành đến khi thực hiện
  • Lên sơ đồ timeline
  • Thực hiện từng giai đoạn
  • Phân bổ và quản lý ngân sách
  • Giao tiếp
  • Khắc phục sự cố
  Bí kíp để trở thành một Product Manager giỏi

Khả năng lãnh đạo

Về bản chất Project Manager chính là trưởng nhóm của dự án đó, họ chịu trách nhiệm hoạch định hướng đi và tầm nhìn cho team và đảm bảo mọi người đều đang đi đúng hướng để đưa dự án vượt qua từng giai đoạn.

Tổ chức/hoạch định

Project Manager là gì
Project Manager là gì

Một Project Manager giỏi phải có kỹ năng lập kế hoạch, các bản kế hoạch được lập ra dựa trên những mục tiêu lớn đến những mục tiêu nhỏ để có thể dễ dàng đạt thành công trong dự án. Các Project Manager phải vạch ra các bước cần thiết để thực hiện và tạo một kế hoạch cụ thể hơn để hoàn thành dự án.

Project Manager sẽ phải xác định phạm vi, quy mô của dự án sau đó lên kế hoạch phân phối các nguồn lực cần thiết để hoàn thành dự án. Việc lập kế hoạch dự kiến về thời gian và ngân sách để hoàn thành dự án cũng rất quan trọng.

Giao tiếp

Đi đôi với khả năng lãnh đạo, kỹ năng giao tiếp xuất sắc là yếu tố quyết định thành công của bất kỳ nhà quản lý dự án nào. Bạn cần đảm bảo rằng tất cả các phòng ban, các bên liên quan đều được cập nhật về những diễn biến mới nhất của dự án, đảm bảo họ hiểu mọi thay đổi và nắm được tiến độ dự án. 

Bạn sẽ phải trình bày kế hoạch, thuyết phục cấp trên cung cấp đủ tài nguyên để bạn có thể hoàn thành công việc. Bên cạnh đó bạn còn phải giao tiếp, triển khai kế hoạch với các thành viên trong team, chính vì thế khả năng giao tiếp tốt sẽ là lợi thế mạnh của một Project Manager.

Quản lý rủi ro

Không phải lúc nào dự án của bạn cũng diễn ra suôn sẻ mà không gặp trở ngại nào, sẽ có lúc bạn sẽ gặp vấn đề với vô vàng các lý do khách quan làm trễ nãi dự án hoặc tệ hơn là hoàn thành dự án với kết quả tệ. 

Các dự án hiếm khi thành công ngay mà không có ít nhất một lần trục trặc hoặc thay đổi kế hoạch. Đó là lý do tại sao, bạn cũng cần phải là một nhà quản lý rủi ro bậc thầy khi ở vị trí Project Manager. 

Project Manager phải có tư duy, tầm nhìn, có khả năng dự đoán những gì có thể xảy ra và lên phương án B, C, D để cứu chữa kế hoạch, nên xây dựng tính linh hoạt trong kế hoạch dự án của bạn để tính đến những thay đổi bất ngờ. 

  Persol - Quy mô tầm cỡ và cơ hội rộng mở chào đón Technical Project Manager
Project Manager là gì
Project Manager là gì

Sự khác biệt giữa Project Manager và Scrum Master là gì?

Sự tương đồng

Điểm chung của cả Project Manager và Scrum Master là đều tập trung vào mục đích chính đó là hỗ trợ giải quyết các vấn đề xảy ra trong quá trình làm việc và cách tối ưu hóa các tiến trình sao cho đạt được kết quả tốt nhất, tạo điều kiện thuận lợi cho các thành viên có thể hoàn thành công việc hiệu quả.

Vì đảm nhận nhiệm vụ giống nhau, điều chịu trách nhiệm hỗ trợ team của họ hoàn thành tốt công việc nên thường các dự án chỉ cần có Project Manager hoặc Scrum Master chứ không cần sự hiện diện của cả hai.

Sự khác biệt

Dù có chung vai trò là chịu trách nhiệm hỗ trợ team của họ hoàn thành tốt công việc nhưng các Project Manager quản lý dưới góc nhìn của người quản lý còn Scrum Master thì quản lý dưới góc nhìn của một thành viên trong team.

Project Manager giúp quản lý tiến trình, nguồn lực, phạm vi dự án, tất tần tật về hoạt động của một dự án để đáp ứng các yêu cầu được đề ra. Trong khi, Scrum Master đảm nhận vai trò “khiêm tốn” hơn, các Scrum Master chỉ cần điều phối công việc, kết nối, đảm bảo cho các thành viên của nhóm scrum có thể hoàn thành tốt Sprint.

Học ngành nào để làm được PM?

Quản lý dự án (Project Management)

Đây là ngành học trực tiếp và liên quan nhất, giúp bạn nắm vững các công cụ, phương pháp và quy trình quản lý dự án như lập kế hoạch, phân bổ nguồn lực, quản lý rủi ro, và điều phối nhóm dự án. Bạn cũng sẽ học về các mô hình quản lý như Agile, Scrum, PMP, và PRINCE2.

Quản trị kinh doanh (Business Administration)

Ngành này cung cấp kiến thức toàn diện về cách quản lý và điều hành các dự án trong môi trường doanh nghiệp. Sinh viên học quản lý tài chính, lãnh đạo đội ngũ, chiến lược kinh doanh, và quản lý nguồn lực, những kỹ năng cần thiết cho PM khi điều phối dự án ở nhiều lĩnh vực khác nhau.

Công nghệ thông tin (Information Technology)

Các dự án về phát triển phần mềm, hệ thống thông tin hoặc công nghệ thường cần PM xuất phát từ lĩnh vực công nghệ thông tin. Ngành học này cung cấp kiến thức về lập trình, mạng, và hệ thống thông tin, giúp PM hiểu rõ quy trình kỹ thuật và quản lý các nhóm phát triển công nghệ.

Chứng chỉ của Project Manager

Trở thành nhà quản lý dự án được chứng nhận có thể mở ra nhiều cơ hội nghề nghiệp và công việc được trả lương cao hơn. Chứng chỉ PMP do Viện Quản Lý Dự Án Hoa Kỳ (Project Management Institute – PMI) cấp là một trong những chứng chỉ mà các Project Manager đều mong muốn đạt được.

Lợi ích của việc sở hữu chứng chỉ PMP rất nhiều vì đây là chứng chỉ được công nhận toàn cầu chính vì thế người có PMP sẽ có cơ hội thăng tiến cao, cơ hội ra nước ngoài làm việc, mức lương cao hơn khoảng 50% so với mức lương của các Project Manager không có chứng chỉ.

Có nhiều dự án quốc tế có yêu cầu bắt buộc các thành viên tham gia có chứng chỉ PMP, chính vì thế những người sở hữu chứng chỉ này sẽ có nhiều lợi thế hơn trong ngành.

Mức lương và cơ hội nghề nghiệp của PM

Mức lương của một Project Manager (PM) trên thế giới có thể khác nhau tùy thuộc vào nhiều yếu tố như kinh nghiệm, ngành nghề, và vị trí địa lý. Theo số liệu mới nhất từ Salary.com và Zippia, mức lương trung bình của một Project Manager trên thế giới dao động từ $69,000 đến $131,000 USD/năm:

  • Hoa Kỳ: Mức lương trung bình của một Project Manager là khoảng $96,320 USD/năm
  • Anh Quốc: Mức lương trung bình là khoảng £65,000 GBP/năm (tương đương khoảng $81,227 USD/năm)
  • Úc: Mức lương trung bình là khoảng 142,000 AUD/năm (tương đương khoảng $112,000 USD/năm)
  • Thụy Sĩ: Mức lương trung bình là khoảng 130,000 CHF/năm (tương đương khoảng $130,966 USD/năm)

Tại Việt Nam: Theo báo cáo thị trường IT năm 2024 từ TopDev, mức lương trung bình của một Project Manager tại Việt Nam dao động từ 1,640$ đến 2,450$/tháng, và có thể cao hơn tùy thuộc vào năng lực và kinh nghiệm cá nhân. Trong các ngành công nghệ thông tin hoặc xây dựng, mức lương này có thể lên đến 80 triệu VND/tháng hoặc thậm chí hơn.

Về cơ hội nghề nghiệp, PM là một vị trí rất được ưa chuộng và có nhiều cơ hội phát triển. Bạn có thể làm việc trong nhiều ngành như công nghệ thông tin, xây dựng, kinh doanh, và nhiều lĩnh vực khác.

Trên đây là một số thông tin về PM là gì, hy vọng qua bài viết bạn đọc sẽ hiểu rõ hơn về Product Manager, từ đó bạn sẽ có thêm thông tin để lựa chọn nghề nghiệp phù hợp hơn cho bản thân. Chúc bạn thành công!

Xem thêm nhiều việc làm Project Manager hấp dẫn, lương cao tại TopDev

Code game rắn săn mồi trên console bằng C++

Code game rắn săn mồi trên console bằng C++

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

Chắc hẳn tuổi thơ của mỗi chúng ta thì không còn xa lạ gì với tựa game Snake hay tiếng Việt là rắn săn mồi đúng không. Hôm nay chúng ta sẽ cùng code lại game đó trên console bằng C++.

Nếu bạn đang thắc mắc vì sao lại là console mà không phải một nền tảng nào khác, giao diện, đồ họa đẹp hơn thì đơn giản là vì nó dễ. Hơn nữa, mới bắt đầu học lập trình thì hầu hết mọi người đều học trên nền console app nên việc tiếp cận game bằng console app cũng trở nên vô cùng dễ dàng.

  Vừa học vừa chơi! Top 15+ game lập trình miễn phí
  7 game miễn phí giúp bạn nâng cao kỹ năng lập trình

Bạn nào thấy code game trên console chán quá thì có thể thoát ngay post này, xem code snake game bằng python trên kênh Youtube của mình nha. Link video tại đây, có code trên github dưới phần mô tả video.

Demo game

Trước khi bắt đầu để mấy bạn có hứng thú một chút thì cùng xem qua thành phẩm sau khi code xong nha!

Thì game này khá là đơn giản, chỉ bằng việc sử dụng các kiến thức cơ bản đã học trong C++, cũng như lên mạng tìm thêm 1 số hàm, thư viện hỗ trợ việc làm việc trên console nữa là được. Bây giờ hãy cùng xem cách tạo ra game này như thế nào nha!

Lưu ý là code của bài này khá dài nên mình sẽ không show hết ra được, các bạn có thể xem code trên Github nha.

Game hoạt động như thế nào?

Game rắn săn mồi đã quá phổ biến nên mình chỉ mô tả đơn giản. Trong game này, người chơi sẽ điều khiển con rắn đi ăn những quả táo, khi ăn thì con rắn sẽ ngày càng dài thêm. Người chơi sẽ bị thua khi đụng tường bao quanh hoặc con rắn tự cắn chính bản thân nó.

Đơn giản chỉ có vậy thôi, việc của chúng ta là làm sao để tạo ra được game đó. Thì chúng ta sẽ vẽ lại con rắn trên màn hình console sử dụng các ký tự. Khi con rắn di chuyển, chúng ta sẽ vẽ lại con rắn đó để thể hiện sự di chuyển của nó. Vì con rắn di chuyển liên tục nên chúng ta sẽ đặt nó trong một vòng lặp.

Đến đây thì chắc các bạn đã hình dung ra được cách code game này như thế nào rồi đúng không! Cùng bắt đầu thôi!

Tạo con rắn và vẽ lên màn hình

Vì game này là 1 game 2D nên đầu tiên, mình sẽ xây dựng struct Point biểu diễn 1 điểm trước. Con rắn của mình sẽ được thể hiện bằng một dãy các điểm này, thể hiện vị trí của nó trên mặt phẳng 2D. Do đó mình sẽ dùng vector để lưu con rắn, mình sẽ khởi tạo con rắn ban đầu luôn.

Bạn nào không biết vector là gì thì có thể xem lại bài viết của mình tại đây nha.

struct Point
{
	int x;
	int y;
};

vector<Point> snake = {
	Point{ WIDTH / 2 + 2, HEIGHT / 2 },
	Point{ WIDTH / 2 + 1, HEIGHT / 2 },
	Point{ WIDTH / 2, HEIGHT / 2 },
	Point{ WIDTH / 2 - 1, HEIGHT / 2 },
	Point{ WIDTH / 2 - 2, HEIGHT / 2 }
};

Để vẽ con rắn lên màn hình thì mình chỉ cần di chuyển con trỏ đến vị trí đó (dùng hàm gotoxy) và in ra là được. Hàm gotoxy thì các bạn xem trong code trên Github nha.

void drawSnakePart(Point p)
{
	gotoxy(p.x, p.y);
	// BODY là ký tự đại diện cho phần thân của con rắn
	cout << BODY;
}

void drawSnake()
{
	for (size_t i = 0; i < snake.size(); i++)
		drawSnakePart(snake[i]);
}

Di chuyển

Tất nhiên trong mặt phẳng thì chỉ có 4 hướng di chuyển thôi, mình sẽ quy định các hướng di chuyển đó bằng enum class. Đương nhiên là sẽ có 1 biến toàn cục để biết hướng hiện tại của con rắn.

enum class Direction
 {
	up,
	right,
	down,
	left
};

Direction direction = Direction::right;

Khi con rắn di chuyển, các bạn để ý phần đầu con rắn đi qua đâu thì phần đuôi chắc chắn phải đi theo đó. Ta sẽ quy định phần đầu con rắn là phần tử đầu tiên. Vậy để làm con rắn di chuyển, chúng ta sẽ cập nhật lại các giá trị tọa độ các phần của con rắn.

Cụ thể chúng ta sẽ dịch các phần tử về bên phải (con rắn đang bò theo phần đầu) và chừa chỗ trống cho phần đầu nhận giá trị mới. Giá trị tọa độ mới của phần đầu sẽ tùy theo hướng đang di chuyển.

void move()
{
	for (size_t i = snake.size() - 1; i > 0; i--)
		snake[i] = snake[i - 1];
	if (direction == Direction::up)
		snake[0].y -= 1;
	else if (direction == Direction::down)
		snake[0].y += 1;
	else if (direction == Direction::left)
		snake[0].x -= 1;
	else if (direction == Direction::right)
		snake[0].x += 1;
}

Tiếp theo, như mình đã nói ở đầu bài viết, khi con rắn di chuyển chúng ta sẽ vẽ lại chuyển động của nó. Do đó mình sẽ dùng một vòng lặp, giữa các lần lặp sẽ nhận điều khiển từ bàn phím, di chuyển con rắn và vẽ lại, sau đó chờ (để người dùng có thể nhìn thấy sự di chuyển đó).

Mình sẽ sử dụng các phím A, W, S, D để điều khiển con rắn.

while (true)
{
	// Nếu có nhấn phím
	if (_kbhit())
	{
		// Đọc phím vừa nhấn
		char ch = _getch();
		// lower để nhận được cả in hoa và in thường
		ch = tolower(ch);
		if (ch == 'a')
			direction = Direction::left;
		else if (ch == 'w')
			direction = Direction::up;
		else if (ch == 's')
			direction = Direction::down;
		else if (ch == 'd')
			direction = Direction::right;
		else if (ch == 'q') // Quit game
			break;
	}
	move();
	drawSnake();
	// Có thể xem REFRESH_RATE chính là tốc độ của con rắn
	// Nếu REFRESH_RATE càng nhỏ thì càng nhan và ngược lại
	Sleep(REFRESH_RATE);
	// Sau khi xong thì xóa để vẽ lần tiếp theo
	system("cls");
}

Giờ thì bạn có thể run thử app để xem kết quả. Cái cách cứ vẽ xong lại xóa, rồi lại vẽ lại toàn bộ con rắn này không được tối ưu lắm, chút nữa mình sẽ thực hiện 1 cách khác tối ưu hơn.

Giới hạn khu vực chơi

Tiếp theo chúng ta sẽ giới hạn khu vực chơi bằng cách vẽ ra các bức tường, mình gọi là box (thông cảm vì tiếng anh mình hơi kém ^^). Để vẽ ra các bức tường này thì cũng đơn giản, chỉ cần cho vòng lặp rồi in ra các ký tự thể hiện cho các bức tường thôi, sau đó chúng ta sẽ gọi hàm vẽ này trong vòng lặp lúc nảy để nó vẽ lại box mỗi lần con rắn di chuyển ở mỗi frame.

void drawBox()
{

	// WIDTH và HEIGHT là kích thước hộp được đặt trước
	for (size_t i = 0; i < WIDTH; i++)
		cout << '=';
	gotoxy(0, HEIGHT);
	for (size_t i = 0; i < WIDTH; i++)
		cout << '=';
	for (size_t i = 1; i < HEIGHT; i++)
	{
		gotoxy(0, i);
		cout << '|';
	}
	for (size_t i = 1; i < HEIGHT; i++)
	{
		gotoxy(WIDTH, i);
		cout << '|';
	}
}

// Và trong vòng lặp
move();
drawBox();
drawSnake();

Tiếp tục bạn có thể run app để check thử!

Tìm việc làm Game đãi ngộ tốt trên TopDev

Thêm logic cho game

Tiếp theo chúng ta cần xử lý các trường hợp con rắn tự cắn chính nó, đụng vào tường và nó không được quay đầu 180 độ.

Cái dễ làm trước, để tránh việc con rắn quay đầu 180 độ, mình chỉ cần kiểm tra lúc người dùng điều khiển con rắn xem là hướng vừa được chọn có đối với hướng hiện tại không thôi.

if (ch == 'a' && direction != Direction::right)
	direction = Direction::left;
else if (ch == 'w' && direction != Direction::down)
	direction = Direction::up;
else if (ch == 's' && direction != Direction::up)
	direction = Direction::down;
else if (ch == 'd' && direction != Direction::left)
	direction = Direction::right;
else if (ch == 'q') // Quit game
	break;

Tiếp theo xem con rắn có đụng tường hay không cũng đơn giản, bạn kiểm tra xem phần đầu của con rắn chính là phần tử đầu tiên, tọa độ của nó có trùng với box không.

bool isHitWall()
{
	return snake[0].x == 0 || snake[0].y == 0 || snake[0].x == WIDTH || snake[0].y == HEIGHT;
}

Phần cuối cùng là kiểm tra xem con rắn nó có tự cắn chính mình không, đơn giản chúng ta chỉ cần kiểm tra xem phần đầu nó có bị trùng với phần thân nào không, như vậy là nó đang cắn chính mình.

bool isBiteItself()
{
	Point head = snake[0];
	for (size_t i = 1; i < snake.size(); i++)
		if (head.x == snake[i].x && head.y == snake[i].y)
			return true;
	return false;
}

Và cuối cùng, nhớ thêm các logic này vào vòng lặp lúc đầu.

move();
if (isBiteItself())
	break;
if (isHitWall())
	break;
drawSnake();

Tương tự như lúc nảy, bạn có thể run app để check thử xem các logic trên đã hoạt động hay chưa.

Tối ưu hiệu năng

Như đã nói lúc nảy, cứ mỗi 1 khung hình lại phải vẽ lại 1 lần cả con rắn và cả box, mình sẽ xử lý chuyện này như sau: mình sẽ tránh việc sử dụng lệnh xóa màn hình để tránh phải vẽ lại toàn bộ, thay vào đó mình sẽ vẽ box chỉ 1 lần, vẽ toàn bộ con rắn 1 lần đầu tiên. Tiếp theo đó, mình sẽ vẽ thêm phần đầu mới cho con rắn và xóa bỏ phần đuôi cũ. Như vậy hiệu năng sẽ được cải thiện đáng kể.

Để làm được việc đó, mình cần 1 biến lưu phần đuôi cũ của con rắn, sau đó cập nhật phần đuôi cũ này trong hàm move. Sau đó mình sẽ viết hàm drawHeadnTail để thực hiện việc vẽ đàu và xóa đuôi cũ đi.

Point prevTail;

void move()
{
	// lưu phần đuôi cũ lại
	prevTail = snake.back();
	// code gores here
}

void drawHeadnTail()
{
	gotoxy(snake[0].x, snake[0].y);
	cout << BODY;
 // vẽ phần đầu mới
	Point tail = snake.back();
	gotoxy(prevTail.x, prevTail.y);
	cout << ' '; // xóa phần đuôi cũ đi
}

Chức năng cuối cùng – Ăn mồi

Như đã nói thì mồi ở đây mình sẽ cho là những quả táo. Mình sẽ tạo ngẫu nhiên những quả táo trong khu vực chơi, khi con rắn ăn được thì nó sẽ dài ra thêm và 1 quả táo khác được tạo ra và cứ thế tiếp tục.

Để tạo quả táo thì cũng đơn giản, mình chỉ cần gán tọa độ x, y của quả táo ngẫu nhiên trong khoảng x thuộc (0; WIDTH) và y thuộc (0; HEIGHT). Hàm sinh quả táo của mình như sau:

Point apple;

void genApple()
{
	srand(time(0));
	int x = rand() % (WIDTH - 1) + 1;
	int y = rand() % (HEIGHT - 1) + 1;
	apple = {
		x,
		y,
	};
	// Sau khi có tọa độ quả táo thì vẽ lên màn hình
	gotoxy(x, y);
	cout << APPLE;
}

Tiếp theo chúng ta sẽ kiểm tra xem trái táo đã được ăn chưa, chỉ cần kiểm tra xem đầu của con rắn của trùng với quả táo hay không là được.

bool isAteApple()
{
	return snake[0].x == apple.x && snake[0].y == apple.y;
}

Khi mà đã ăn được mồi thì phải tăng chiều dài của con rắn lên, mình sẽ thực hiện thêm 1 phần tử vào đuôi của con rắn. Phần đuôi này cũng đơn giản không kém, mình chỉ cần thêm lại phần đuôi trước đó vào thôi, mình sẽ code như sau:

void growing()
{
	snake.push_back(prevTail);
}

Như vậy là chúng ta đã viết xong các hàm cần thiết, giờ thì chúng ta chỉ cần thêm chúng vào vòng lặp của game là xong. Chúng ta sẽ kiểm tra nếu con rắn ăn được mồi thì cần phải tạo quả táo khác và tăng chiều dài con rắn lên. Mình sẽ thêm đoạn code sau:

if (isAteApple())
{
	growing();
	genApple();
}

Đến đây xem như game của mình đã hoàn thành. Việc còn lại chỉ là cho hiện điểm số, các menu start, hiện kết quả sau khi chơi xong… Phần này thì các bạn có thể xem code trong Github nha.

Lời kết

Như vậy là trong bài viết này mình đã hướng dẫn các bạn cách code game Snake đơn giản trên console. Thực tế thì chả ai lại đi làm game trên console cả, nhưng nó lại là lựa chọn hợp lý cho mọi sự bắt đầu của lập trình, trong đó có cả game.

Trong bài này mình viết mọi thứ hết trong một file và không code theo OOP (do mình lười quá “=))”). Các bạn có thể refactor code của mình lại theo OOP cho dễ quản lý, nâng cấp và nhìn professional hơn nha. Trên trang của mình có chuỗi bài viết về OOP, các bạn có thể search trên trang mình nha ^^.

Nếu các bạn có bất kỳ thắc mắc nào hoặc góp ý, đừng ngần ngại comment phía bên dưới bài viết để mình phát triển bài viết tốt hơn nha. Cảm ơn các bạn đã đọc bài viết!

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

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

Tìm việc IT lương cao, đãi ngộ tốt trên TopDev ngay!

Dưới 20 tuổi thì học lập trình như thế nào?

Dưới 20 tuổi thì học lập trình như thế nào?

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

Chào các bạn,

Dạo gần đây mình thấy có rất nhiều bạn trẻ quan tâm tới việc học lập trình, nhưng lại không biết bắt đầu từ đâu, nên mình viết bài này với mong muốn chia sẻ vài điều về “Cách học lập trình khi bạn dưới 20 tuổi”.

Lưu ý: Cách học dưới đây sẽ đem đến cho bạn nhiều trải nghiệm, nhưng lại tốn thời gian, nên sẽ phù hợp với các bạn:
– Có nhiều thời gian và sức khỏe
– Chưa đặt nặng vấn đề “cơm áo”
– Nhiệt huyết

Đó cũng là lý do tại sao bài viết này chỉ dành cho các bạn dưới 20 tuổi.

Dài dòng quá, bắt đầu thôi …

  10 câu nói cực hay về lập trình
  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java

BƯỚC 0: SUY NGHĨ TRƯỚC KHI BẮT ĐẦU

Mình gặp rất nhiều bạn vào nghề IT, hoặc học trường ĐH về IT rồi mới biết mình không hợp với nghề này. Đương nhiên không phải họ kém cỏi, mà đơn giản là các dòng code không làm cho họ cảm thấy thú vị, đáng nói hơn là không ít trong số họ từng có mong muốn được làm việc trong ngành này.

Kể ra như vậy không phải để dọa, mà để các bạn hãy suy nghĩ nghiêm túc trước khi bắt đầu học lập trình. Bởi nếu không thích, thì có nhét mấy, nhét nữa thì bạn cũng chẳng viết được vòng lặp for đâu. Bạn cũng không nên ép bản thân phải thích thì bạn không thích, vì bạn còn trẻ, bạn còn rất nhiều thời gian để khám xem bản thân mình thích gì.

– Tôi từng rất thần tượng những người đánh máy tính nhanh
– Tôi rất tò mò về thế giới công nghệ
– Tôi nhận thấy “phần mềm” sẽ làm thay đổi thế giới
– Tôi xem các video hướng dẫn học lập trình trên mạng, và tôi bị chúng cuốn hút

Vậy là tôi quyết định học lập trình

>> Đọc thêm: Để trở thành lập trình viên bạn cần gì

BƯỚC 1: XÁC ĐỊNH BÀI TOÁN

Bước này tập trung trả lời 2 câu hỏi sau

  • Câu hỏi 1: Bạn muốn tạo ra phần mềm gì?
  • Câu hỏi 2: Để tạo ra phần mềm đó, bạn cần học những công nghệ gì?

Câu hỏi 1: Bạn muốn tạo ra phần mềm gì?

Tại sao phải trả lời câu hỏi này

Thế giới lập trình nói chung rất rộng, bạn không thể nào học được hết. Thậm chí khi đã xác định được bạn sẽ theo học lập trình mảng nào (web, desktop, mobile), thì mảng đó cũng là cả một bầu trời kiến thức. Mặt khác việc học lập trình là để tạo ra phần mềm, cho nên để rõ ràng mục tiêu của việc học thì hãy trả lời câu hỏi “Bạn muốn tạo ra phần mềm gì“.

Làm sao để trả lời câu hỏi này?

Chẳng có công thức nào cả, chính bạn còn không biết thì ai biết.

Tôi muốn lập trình ra một website dạng blog cá nhân, để có thể viết bài, chia sẻ kiến thức cho mọi người.

Câu hỏi 2: Để tạo ra phần mềm đó, bạn cần học những công nghệ gì?

Tại sao phải trả lời câu hỏi này?

Một phần mềm có thể được tạo ra bằng những công nghệ khác nhau, bạn cần làm rõ đó là công nghệ gì để tiếp tục theo học.

Làm sao để trả lời câu hỏi này?

Hãy mô tả về phần mềm bạn muốn làm lên các nhóm, diễn đàn về lập trình, hỏi mọi người trên đó xem một phần mềm như vậy cần phải học những gì.

Tôi thấy mọi người bảo để tạo ra một website thì cần học html, css, javascript, php và mysql

BƯỚC 2: BẮT TAY VÀO HỌC

Sau khi lựa chọn được các công nghệ cần học, bạn hãy lên kế hoạch để học từng thứ một.

Lưu ý, đây là bước quan trọng nhất, quyết định kết quả của việc học lập trình, trong thực tế, rất nhiều bạn đã bỏ cuộc ở bước này.

– Tôi mất một tuần chỉ để hiểu HTML là gì trước khi thật sự code nó
– Tôi mất 4h đồng hồ chỉ để tìm ra lỗi “Tại sao ảnh không hiển thị – lý do là tôi viết sai thẻ <img src> thành <img scr>”
– Tôi mất cả ngày trời tìm lỗi, vì tôi không hiểu tại sao ‘1’ + ‘1’ lại bằng ’11’ trong js, kết quả tôi quên ép về string về dạng int
– Tôi mất vài ngày trời để khởi động xampp, vì skype chiếm cổng 80
– Tôi mất vài tuần trời để hiểu hiểu lập trình hướng đối tượng là gì, tại sao người ta ưa chuộng nó hơn hướng cấu trúc
– Tôi mất cả tháng trời để học mysql và cách thiết kế database: 1 – 1, 1 – n, n – n
– Sau nhiều lần gặp lỗi và search gooogle, tôi biết search bằng Tiếng Anh sẽ cho ra nhiều kết quả hơn Tiếng Việt
– Sau nhiều search google bằng Tiếng Anh, tôi biết rằng kết quả từ stackoverflow thường cho tôi câu trả lời
– Tôi tự nhận thấy rằng mình cần học thêm nhiều thứ nữa, và lại lên kế hoạch để học tiếp: giải thuật sắp xếp, giải thuật tìm kiếm, đệ quy, coding convention,…

>> Đọc thêm: Cách học một công nghệ mới hiệu quả

BƯỚC 3: BẮT TAY VÀO CODE

Hãy áp dụng tất cả các kiến thức mà bạn đã học được, tích lũy được trong thời gian qua để làm cái phần mềm mà bạn đã ao ước thực hiện bấy lâu.

– Tôi hăm hở tới nỗi, code liên tục 2 ngày trời mà không cần chạy thử, cho tới lúc chạy thử thì lỗi bung bét
– Tôi từng đập đi xây lại không dưới 20 lần cái blog cá nhân
– Tôi từng code từ 4h sáng tới 11h đêm liên tục (đương nhiên là vẫn ăn đủ 3 bữa)

LỜI KẾT

Bạn chỉ mất 3 phút để đọc hết bài viết này, nhưng có thể mất tới 3 năm để thực hiện hết các bước. Hãy kiên nhẫn và đừng từ bỏ, nếu định từ bỏ, hãy nghĩ tới lý do bạn bắt đầu.

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

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

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

Tech Lead là gì? Nhiệm vụ, vai trò của Tech Lead trong team

tech lead là gì

Tech Lead là gì? Nhiệm vụ, vai trò và tầm quan trọng của Tech Lead trong team là gì? Những câu hỏi này sẽ được TopDev giải đáp cho bạn ngay trong bài viết dưới đây!

Công nghệ thông tin là một ngành có khá nhiều thuật ngữ khó hiểu và từ chuyên ngành chỉ có những người trong ngành mới có thể hiểu hết nghĩa. Có thể bạn đã nghe qua các chức danh như Architect (Kiến trúc sư), Tech Lead (Trưởng nhóm kỹ thuật), Team Leader (Trưởng nhóm) và Engineering Manager (Giám đốc kỹ thuật) đôi khi gây ra nhiều sự nhầm lẫn về vai trò và trách nhiệm của các vị trí này trong team.

Trong bài viết này, TopDev sẽ gửi đến bạn đọc tất cả các thông tin liên quan đến chức danh Tech Lead trong ngành IT để người đọc có cái nhìn khách quan hơn và không còn bị nhầm lẫn về vị trí này.

Tech Lead là gì?

tech lead là gì

Tech Lead là một Software Engineer (kỹ sư phần mềm) chịu trách nhiệm dẫn dắt một nhóm và điều chỉnh hướng kỹ thuật. Họ là người theo dõi và đưa ra các hướng kỹ thuật tối ưu nhất, công việc chính của họ là xây dựng tầm nhìn, giải quyết các bất đồng và quản lý chất lượng kỹ thuật.

Một Tech Lead giỏi là người có khả năng đưa ra những phương án kỹ thuật hiệu quả, phù hợp, chấp nhận đầu tư vào các công cụ được cải tiến liên tục, hệ thống phát triển để đáp ứng nhu cầu công việc, hỗ trợ các thành viên trong team luôn đi đúng hướng, hiệu quả công việc cao.

Đôi khi vai trò của Team Leader sẽ được các thành viên luân phiên đảm nhiệm, nhưng đối với vị trí của Tech Lead thì không như vậy. Tech Lead có thể đồng lãnh đạo một team với các vai trò khác như Product Manager, Engineering Manager hay Team Leader. 

Khi đó Product Manager chịu trách nhiệm vào “Cái gì”, Engineering Manager hay Team Leader tập trung vào“ Phát triển con người và nhóm”, Tech Lead tập trung vào “Phát triển kỹ thuật” của các thành viên trong nhóm và hệ thống. Trọng tâm duy nhất của Tech Lead là dẫn đầu về chỉ đạo kỹ thuật và chất lượng cho nhóm, họ cũng có thể có thêm trách nhiệm tùy thuộc vào nhóm cụ thể.

  Mẫu bảng mô tả công việc vị trí Technical Leader

Vai trò và trách nhiệm của Tech Lead

Vai trò

Trong một team, tùy thuộc vào quy mô của từng dự án mà có 1 hoặc nhiều vị trí đảm nhận vai trò quản lý khác nhau. Đối với những dự án lớn, trong một team có thể có cả 3 vai trò như Product Manager, Engineering Manager và Tech Lead, mỗi vị trí sẽ đảm nhận những nhiệm vụ khác nhau. 

Trong trường hợp này, Tech Lead thường là người chịu trách nhiệm toàn bộ về mảng tech, họ sẽ tham gia nhiều hơn vào các cuộc thảo luận và quyết định về kiến ​​trúc code. Đồng thời Tech Lead cũng sẽ quan sát, quản lý chất lượng của codebase và sự phát triển kỹ thuật của team.

Có thể thấy dù cho trong nhóm có thêm bao nhiêu vị trí nữa thì Tech Lead vẫn luôn thực hiện đúng chức năng của mình đó là điều hướng và lãnh đạo về mặt kỹ thuật của team. Một Tech Lead giỏi sẽ đồng hành cùng team, code cùng team, hiện thực hóa các ý tưởng, giải quyết vấn đề, xác định rủi ro kỹ thuật và hơn hết là phải có niềm tin vào các thành viên của team.

Trách nhiệm

tech lead là gì

Tech Lead làm việc với tư cách là người quản lý dự án và sản phẩm thiên về khía cạnh kỹ thuật cho team Developer Software Systems hay Computer Systems. Họ làm việc với giám đốc điều hành công ty hoặc khách hàng từ đó xác định yêu cầu về các thông số kỹ thuật cho hệ thống, đảm bảo hệ thống đủ mạnh để đáp ứng nhu cầu về các quy trình kinh doanh của khách. 

Tech Lead cũng phát triển sản phẩm để phù hợp với kiến ​​trúc của công ty hoặc yêu cầu của khách hàng, làm cho việc tích hợp trở nên trực quan và đảm bảo tất cả các bộ phận hoạt động cùng nhau, Tech Lead tạo ra các sơ đồ của toàn bộ kiến ​​trúc mạng. Trách nhiệm của Tech Lead bao gồm:

  • Xây dựng mối quan hệ với các nhà cung cấp phần mềm và phần cứng
  • Chỉ ra những hạn chế với kiến ​​trúc kỹ thuật và sửa chữa chúng
  • Sử dụng Java và Apex để xây dựng phần mềm
  • Outsourcing một số task phát triển nhất định cho các công ty đối tác
  Con đường để bạn trở thành tech lead

Các kỹ năng cần có của một Tech Lead là gì?

Ngoài các kỹ năng mềm như kỹ năng giao tiếp, quản lý, tổng hợp thông tin… thì một Tech Lead cần có các thêm kỹ năng phụ hỗ trợ cho chuyên ngành của họ để có thể giúp hoàn thành tốt công việc của vị trí Tech Lead.

Development (Phát triển)

Develop là nền tảng của Tech Lead, Tech Lead cần biết cách viết mã và có thể nhận ra được một mã chất lượng tốt trông như thế nào. Tech Lead sẽ phải giúp đỡ team của mình khi gặp phải bất kỳ trục trặc về kỹ thuật nào mà họ gặp phải.

Architecture (Kiến trúc)

Develop chỉ là một phần công việc của việc xây dựng hệ thống, Tech Lead cần phải có hiểu biết rộng hơn về các phần mềm phù hợp với hệ thống tổng thể. Họ cần hiểu rõ về phương thức phần mềm được triển khai, quản lý và vận hành trong môi trường sản xuất.

Leadership (Khả năng lãnh đạo)

Một Tech Lead chuyên nghiệp cần có kỹ năng lãnh đạo mạnh mẽ, ngay cả khi họ không chịu trách nhiệm quản lý toàn phần của dự án. Các kỹ năng thuộc kỹ năng lãnh đạo như huấn luyện, tạo sức ảnh hưởng và ủy quyền là chìa khóa thành công của Tech Lead.

  Team Leader là gì? Những kỹ năng nào mà một Team Leader cần có?

Sự khác biệt giữa Tech Lead và Engineering Manager

Việc các công ty kết hợp vai trò Tech Lead và Engineering Manager là rất phổ biến. Mặc dù cả hai vai trò có một số điểm chung, nhưng mục tiêu công việc của 2 vai trò này lại khác nhau: Tech Lead chịu trách nhiệm về Hệ thống trong khi Engineering Manager chịu trách nhiệm về Con người.

Trong các công ty vừa và nhỏ hoặc nếu Tech Lead là một người có nhiều kinh nghiệm thì các Tech Lead có thể đảm nhận luôn vai trò của Engineering Manager trong những công ty đó. Trong trường hợp khi hệ thống và đội ngũ phát triển có quy mô và độ phức tạp cao, thì Tech Lead và Engineering Manager được đảm nhận bởi 2 người tách biệt.

Bảng so sánh

Tech Lead (Hệ thống) Engineering Manager (Con người)
Giỏi về kỹ thuật và đổi mới Lập kế hoạch nghề nghiệp, thăng chức và huấn luyện
Tích hợp kiến ​​trúc và hệ thống Lập kế hoạch và thuê nhân viên
Cố vấn công nghệ, áp dụng và liên kết Lập kế hoạch và phân phối team
Bản trình bày thiết kế hệ thống Tham gia vào các quyết định kỹ thuật
Hands-On Coding 30% – 70% thời gian Hands-On Coding 0% – 30% thời gian
Điều hướng Platform, Patterns và Practices Năng suất và chỉ số của team
SLA hệ thống, số liệu và giám sát Bảo vệ team

 

Có thể bạn muốn xem thêm:

Xem thêm việc làm Tech Lead hấp dẫn, lương cao tại TopDev!

Weekly UI – Hướng dẫn code giao diện trang sản phẩm đơn giản

Weekly UI – Hướng dẫn code giao diện trang sản phẩm đơn giản

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

Hôm nay ngồi rãnh rỗi tranh thủ viết tiếp serie Weekly UI cho các bạn newbie. Hôm trước hướng dẫn làm form đăng nhập UI đơn giản rồi, hôm nay chuyển hướng sang làm trang sản phẩm về giày có tên là Jogger. Và các bạn cũng nhìn thấy trên ảnh đại diện rồi. Không chần chừ nữa, sau đây mình sẽ vào bước phân tích nó nhé.

  "Mẹo bỏ túi" cho dân coder mới vào nghề
  18 designer hàng đầu dự đoán về xu hướng UI/ UX trong năm 2022

# Phân tích

Weekly UI – Hướng dẫn code giao diện trang sản phẩm đơn giản

Layout: Nhìn vào giao diện mình thấy có ba phần riêng biệt đó là header trên cùng gồm có menu, logo chữ Shoes và các icon bên phải, phần thứ hai là navigation bên trái có các liên kết và icon mạng xã hội nằm theo chiều dọc và cuối cùng là phần chính Slider chiếm phần lớn giao diện.

Đặt tên class: Đây là trang sản phẩm thì các bạn có thể đặt tên class là .single__product hoặc .product thôi cho gọn cũng được. Đây là class cha bọc lại khi chúng ta code HTML.

Icons: Mình dùng font-awesome, có hỗ trợ trong Codepen luôn, các bạn vào Codepen chọn phần Setting rồi hiện ra giao diện như hình dưới đây, các bạn gõ vào font-awesome hiện ra chọn sau đó nhấn Save & Close là xong.

Weekly UI – Hướng dẫn code giao diện trang sản phẩm đơn giản

Fonts: Mình dùng font chữ Montserrat và Lobster từ Google, các bạn vào Google Fonts chọn 2 fonts chữ này rồi sau đó chèn vào chỗ để code CSS trên Codepen như sau:

Hình chiếc giày: Mình đã tìm Google và tách ảnh ra sẵn cho các bạn luôn. Các bạn có thể nhấn vào đây để tải về nhé.

Trong giao diện này mình sử dụng đơn vị REM để code, các bạn có thể tìm hiểu đơn vị REM tại đây. Ngoài ra mình còn sử dụng pseudo class như :before, :after, về cấu trúc layout mình dùng flexbox, có một điểm chú ý ở đây là ở phần navigation có các chữ nằm theo chiều dọc. Các bạn dùng thuộc tính này writing-mode: vertical-lr; kết hợp với transform: rotate cho các icon . Các bạn có thể tham khảo thêm ở đây.

Như vậy mình đã phân tích kỹ càng cho các bạn xong. Và đây là kết quả code HTML và CSS các bạn có thể tham khảo nhé.

# HTML

# CSS

# Tạm kết

Vậy là xong. Các bạn có thể xem kết quả tại Codepen mình ở đây nhé. Một lưu ý cho các bạn khi đọc tại blog mình, các UIs mình làm cho các bạn xem với mục đích tham khảo là chính, không hoàn toàn chính xác. Các bạn có thể học cách mình phân tích, cách code, lấy tài nguyên, cách đặt tên… để cải thiện thêm về kiến thức, kinh nghiệm của bản thân nhé.

Ngoài ra ở giao diện trên có Slider nhưng mình không code cho nó chạy, chỉ làm HTML và CSS mà thôi, các bạn có thể thử sức bằng cách thêm một thư viện Slider nào đó vào rồi làm thử xem nhen. Chúc các bạn học tập tốt và một ngày tốt lành.

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

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

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

Công việc hằng ngày của một lập trình viên

Công việc hằng ngày của một lập trình viên

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

  10 Kỹ năng quan trọng cần có của Front-end để tìm công việc dễ dàng hơn
  10 hiểu lầm tai hại về lập trình

Chào các bạn,

Nhắc tới lập trình là nhắc tới các dòng code, nhắc tới các dòng code là nhắc tới lập trình viên, nhưng lập trình viên liệu có phải chỉ biết viết code? Trong bài viết này, mình sẽ chia sẻ với các bạn những công việc hằng ngày và điển hình nhất của lập trình viên.

Công việc hằng ngày của một lập trình viên

Lập trình viên có phải chỉ biết viết code

I. DAILY MEETING

Thực chất, daily meeting là một hoạt động của Scrum – một mô hình phát triển phần mềm được nhiều team áp dụng.

Daily meeting được mô tả là một cuộc họp ngắn diễn ra hằng ngày (thường vào buổi sáng), với mục đích báo cáo tổng quan tình hình công việc của team. Tùy vào văn hóa của team, mà cuộc họp này có thể có hình thức và nội dung khác nhau.

Như team mình, cuộc họp này được gọi là “Chào buổi sáng”, các thành viên trong team sẽ lần lượt báo cáo (tổng quát) về tình hình công việc của mình, như hôm qua đã làm gì, làm đến đâu rồi, có gặp khó khăn gì không, công việc hôm nay là gì… hoặc đơn giản đây là cơ hội tuyệt vời để … cà khịa nhau.

II. PHÂN TÍCH NGHIỆP VỤ

Với các công ty lớn, có mô hình làm việc rõ ràng thì phân tích nghiệp vụ sẽ có riêng một bộ phận đảm nhiệm. Nhưng với các công ty cỡ vừa, hoặc các team nhỏ thì lập trình viên đôi khi sẽ phải “đá” sang vai trò của BA (Business Analyst – Phân tích nghiệp vụ).

BA là người đứng giữa khách hàng và team phát triển sản phẩm (là team có các anh dev đẹp trai), có nhiệm vụ phân tích yêu cầu của khách hàng. BA thường phải trả lời các câu hỏi sau:

  • Yêu cầu của khách hàng có khả thi không? Ý là có làm được hay không, vì khách hàng đôi khi đòi những tính năng phi lý, nằm ngoài giới hạn của công nghệ.
  • Có nên làm tính năng đó hay không? Khách hàng đôi khi đưa ra các tính năng mà để triển khai thì rất tốn kém, nhưng giá trị đem lại thì không cao. BA cần phân tích và chỉ ra cho khách hàng.

Một số công việc điển hình khác của BA:

  • Chuyển đổi yêu cầu của khách hàng thành các đầu công việc cụ thể: Yêu cầu của khách hàng thường mơ hồ, chung chung, BA cần phân tích và làm rõ chúng, chuyển thành các đầu công việc cụ thể.
  • Phân tích rủi ro khi thay đổi (bổ sung) tính năng: Khi một tính năng mới được thêm vào hệ thống, BA cần phân tích xem nó ảnh hưởng tới hệ thống như thế nào.
  • Đưa ra các lời khuyên cho khách hàng: Khách hàng đôi khi rất “vô lý” đòi làm những thứ trên trời dưới bể mà chẳng đem lại lợi ích gì, BA cần phân tích, đưa ra các lời khuyên hợp lý cho khách hàng như “anh không nên làm thế, vì … thay vào đó anh nên làm thế này vì … “.
Công việc hằng ngày của một lập trình viên Hình ảnh cả team ngồi phân tích nghiệp vụ cho tính năng mới

III. VIẾT CODE

Lập trình viên biết code là điều đương nhiên, và “code của lập trình viên” là một chủ đề muôn thuở – dù đã tốn rất nhiều nước bọt nhưng vẫn chưa kể hết. Nên mình sẽ chỉ điểm qua một vài điều đáng chú ý phía sau công việc này:

  • Viết code = Ngôn ngữ lập trình + Tư duy lập trình: Ngôn ngữ lập trình học thì dễ, nhưng tư duy lập trình thì phải chịu khó rèn luyện. Nghĩa là để viết code, thì bạn nên tập trung vào tư duy lập trình nhiều hơn là việc học một ngôn ngữ lập trình.
  • Code chỉ là công cụ: Một phần mềm tốt thì bao gồm cả yếu tố “code tốt”, nhưng “code tốt” không có nghĩa là phần mềm tốt. Tức là để tạo ra một phần mềm tốt bạn cần tập trung nhiều kỹ năng hơn và việc “code sao cho tốt”.
  • Viết code là quá trình chuyển đổi ý tưởng con người thành công việc cho máy tính: Nghĩa là bạn phải có ý tưởng trước khi thực sự viết code.

IV. REVIEW CODE

Review code là công việc xem, đánh giá một đoạn code đó có tốt hay không? Tốt hay không tốt ở điểm nào? Cần chỉnh sửa ra sao? … Để đảm bảo việc review có hiệu quả, thì công việc này thường được thực hiển bởi leader hay những người có kinh nghiệm code, hoặc cũng có thể là các developer review chéo code của nhau, chứ ít khi “mình tự review code của mình”.

So với việc viết code, thì review khó và áp lực hơn, bởi:

  • Những dòng code đó không phải do bạn viết ra, bạn cần phải hiểu tại sao sao “nó lại được code như vậy”. Nói thật chứ code mình viết ra nay mai đọc lại còn chẳng hiểu, chứ nói gì đến đọc code của người khác.
  • Code sau khi được bạn review, mà vẫn có lỗi, thì lỗi đó là lỗi của bạn, bởi bạn đã không tìm ra lỗi đó trong lúc review.
  • Bạn phải suy nghĩ ở mức “high level” hơn so với người viết ra đoạn code đó thì mới có thể tìm ra các trường hợp mà đoạn code đó không xử lý được (hoặc xử lý kém).

V. TEST

Cũng giống như việc phân tích nghiệp vụ, các team nhỏ chưa chắc đã có vị trí tester (người kiểm thử và đảm bảo phần mềm chạy đúng), nên nhiều khi lập trình viên phải kiêm luôn vai trò của một tester.

Về cơ bản, vai trò của tester là nghĩ ra thật nhiều trường hợp và đảm bảo phần mềm phải chạy tốt trên tất cả các trường hợp đó.

Mặc dù các developer được khuyên là nên test chéo tính năng của nhau để kết quả test khách quan hơn, nhưng kết quả test từ một developer vẫn không thật sự “đáng tin cậy”. Vì họ thường tin tưởng đồng nghiệp, họ nghĩ rằng trường hợp này quá cơ bản nên chắc chắn đồng nghiệp của họ đã xử lý rồi, nhưng kết quả thì có thể không như vậy. Dẫu không hiệu quả, nhưng méo mó có hơn không, nhiều team vẫn không hề có vị trí tester rõ ràng.

VI. HỌP

Bạn có thể nghĩ “họp” là công việc của “cán bộ”, nhưng thực tế, các lập trình viên cũng phải tham gia rất nhiều các cuộc họp khác nhau:

  • Khi có dự án mới => họp.
  • Khi hoàn thiện một dự án => họp.
  • Khi có business không rõ ràng, cần thảo luận lại => họp.
  • Khi thảo luận với đối tác => họp.
  • Khi cần training công nghệ mới => họp.
  • Khi team có member mới là nữ => họp.

Tuần suất diễn ra các cuộc họp với mỗi team, mỗi công ty, mỗi thời điểm có thể khác nhau, nhưng chung quy lại họp là một trong những công việc diễn ra khá thường xuyên khi bạn là một lập trình viên. Không những vậy, vai trò của các anh dev trong mỗi cuộc họp cũng rất đa dạng, họ có thể là người làm chủ cuộc họp, hoặc là người nêu ý kiến, đôi khi là thư ký …

VII. TỔNG KẾT

Kể ra mới thấy công việc của lập trình viên đâu phải chỉ là code đúng không? Mà chưa kể khi có kinh nghiệm thì họ sẽ có xu hướng “code ít” hơn, và chuyển sang làm các công việc như thiết kế hệ thống, quản lý dự án, quan hệ khách hàng,… Nói chung code chỉ level cơ bản nhất của lập trình viên, và chẳng có lập trình viên nào code cả đời cả.

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

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

Xem ngay những tin đăng tuyển dụng IT mới nhất trên TopDev