Như vậy có thể thấy viết blog đã đem lại khá nhiều kỹ năng hữu ích đấy chứ. Vậy còn bạn, viết blog đã đem lại cho bạn những kỹ năng gì?
Kỹ năng viết: việc sử dụng câu chữ thế nào, dấu chấm, dấu phẩy của người viết sẽ được cải thiện rõ rệt qua thời gian dài viết bài (với điều kiện là các bạn viết một cách nghiêm túc). Nó thể hiện sự chuyên nghiệp cũng như tôn trọng người đọc của tác giả.
Kỹ năng đọc và tổng hợp: Đây cũng là một trong những kỹ năng quan trọng mà bạn sẽ thu được nhờ viết blog. Chắc chắn rằng bạn sẽ phải chép từ chỗ này một chút chỗ kia một chút cũng như tham khảo các nguồi tại liệu khác nhau để lấy ý tưởng, cuối cùng là kết hợp tất cả chúng lại với nhau để có một bài viết hoặc ý tưởng hay. Ngoài ra để có thể đọc được nhanh mà vẫn nắm bắt được nội dung chính của một bài viết, bạn sẽ dần hoàn thiện kỹ năng đọc của mình.
Kỹ năng trình bày, bố cục văn bản: một điều khá quan trọng đó là nếu nội dung bài viết rất hay nhưng trình bày, bố cục không hấp dẫn thì cũng không thể thu hút người đọc được. Do vậy, kỹ năng trình bày, bố cục văn bản để nâng cao chất lượng bài viết của bạn sẽ được nâng cao. Không ai muốn bài viết của mình mặc dù không tệ nhưng lại chẳng ma nào thèm đọc cả, đúng không?
Kỹ năng liên kết, ngoại giao: sau khi viết xong bạn sẽ có nhu cầu chia sẻ với người khác, một cách đơn giản để bạn mở rộng các mối quan hệ và bạn nhận được sự tôn trọng, nể phục từ những người đọc bài viết của bạn.
Kỹ năng sử dụng máy tính, Internet: cái này thì khỏi phải nói rồi, để có 1 bài viết hay thông tin đáng tin cậy bạn sẽ phải tìm hiểu vấn đề từ những nguồn khác nhau.
Ngoại Ngữ: Việc tham khảo, đọc, xem các tài liệu/video bằng tiếng Anh sẽ cải thiện kỹ năng đọc (Reading Skills) và nghe (Listening Skills) khá nhiều
Nhớ các kiểu số liệu: text, binary, numberic, money, datetime, bit, variant
Nhớ các các ràng buộc: default, check, unique, foreign, primary
Nhớ các kiểu toàn vẹn: entity, domain, referential, user
Nhớ các thuộc tính bổ trợ: identity, null
create table: tạo bảng
Tạo bảng với các cột
create table SinhVien (MaSV int,TenSV nchar(50))
Tạo với các ràng buộc
create table SinhVien (MaSV int primary key,TenSV nvarchar(50) not null,QueQuan int references DiaPhuong(MaDP))
drop table: xóa bảng
drop table SinhVien
alter table..add: thêm cột
Thêm cột bằng cách dùng lệnh alter table
alter table SinhVienadd QueQuan int
alter table..drop column: xóa cột
alter table SinhVien drop column QueQuan
alter table..alter column: thêm thuộc tính not null
alter table SinhVienalter column TenSV nchar(50) not null
alter table..add primary key: thêm khóa chính
Thêm ràng buộc khóa chính cần phải biến một cột null thành not null trước khi thêm. Nếu để lệnh chuyển đổi thuộc tính not null ngay cạnh lệnh thêm khóa chính thì phải chèn từ khóa go vào vì có thể lệnh trên chưa được thực hiện do đó lệnh dưới báo lỗi
alter table SinhVienalter column MaSV int not null
go
alter table SinhVien
add primary key (MaSV)
alter table..add foreign key: thêm ràng buộc khóa ngoài
alter table SinhVien add foreign key (QueQuan) references DiaPhuong(MaDP)
alter table..add default: thêm ràng buộc mặc định
alter table SinhVien add default 'khong ten' for TenSV
exec sp_help: xem thông tin bảng
exec sp_help SinhVien
Tham khảo các vị trí tuyển dụng SQL lương cao tại Topdev.
3) Trên bản ghi (record)
Nhớ thêm phần biểu thức điều kiện
Nhớ thêm phần ký tự thay thế
insert..values: thêm các bản ghi vào bảng
insert into SinhVien (MaSV, TenSV, QueQuan)values (1, N’Nguyễn Văn A’, 1)
insert..select: thêm các bản ghi từ bảng khác vào bảng
insert into DocGiaselect MaSV, TenSV, QueQuan from SinhVien
insert into DocGia
select MaGV, TenGV, QueQuan from GiaoVien
select..into: đưa kết quả lựa chọn vào bảng mới
select MaSV, TenSV, Dieminto SinhVienKha
from SinhVien
where Diem >7.0
delete: xóa các bản ghi từ bảng
delete from SinhViendelete from SinhVien where MaSV=1234
truncate: xóa toàn bộ bản ghi của bảng
truncate table SinhVien
update: sửa các bản ghi trong bảng
update SinhVienset NhomTruong =1
where MaSV <4
update SinhVien
set NhomTruong =4
where (MaSV >3 and MaSV <8)
4) Truy vấn (query)
Hỗ trợ truy vấn: distinct, top, as, identity
Phép toán tập hợp: in, like, between
Các hàm tổng nhóm: sum, max, min, avg
4.1) Truy vấn đơn giản
select *: Hiện tất cả bảng
select *from SinhVien
select: Hiện một số cột
select TenSV, DiemTBfrom SinhVien
select..where: Hiện một số dòng / bản ghi
select TenSV, DiemTBfrom SinhVien
where DiemTB >6.0
select..order by: Hiện và sắp xếp theo điểm rồi theo tên
select TenSV, DiemTBfrom SinhVien
order by DiemTB desc, TenSV asc // asc sắp sếp tăng dần, desc là giảm dần
select..distinct: Hiện danh sách giá trị không trùng lặp
select distinct QueQuanfrom SinhVien
select..top: Hiện các dòng đầu tiên trong bảng
select top 3 TenSV, DiemTBfrom SinhVien
order by DiemTB desc, TenSV asc
4.2) Truy vấn lồng nhau (nested query)
select..where (select)
Hiện tất cả những người trong bảng nhân viên có lương bằng lương lớn nhất của những người có trong công ty:
select TenNV, Luongfrom NhanVien
where Luong = (select max(Luong) from NhanVien)
select..where (in)
Hiện tất cả những người trong bảng nhân viên có lương lớn nhất hoặc lớn nhì của những người có trong công ty:
select TenNV, Luongfrom NhanVien
where Luong in (select top 2 Luong from NhanVien order by Luong)
Câu lệnh select trong sẽ tạo ra một tập hai giá trị (top 2) đó là lương lớn nhất và lương lớn nhì. Và câu lệnh select thứ nhất sẽ chọn ra những người mà lương nằm trong tập lớn nhất và lớn nhì
select..where (in sub)
Hiện ra tất cả những người có lương lớn nhất phòng của anh ta (không phải lớn nhất trong công ty mà lớn nhất trong phòng hoặc đơn vị mà anh ta thuộc về)
select nv1.TenNV, nv1.Luongfrom NhanVien as nv1
where nv1.Luong = (select max(Luong) from NhanVien where Phong=nv1.Phong)
Câu lệnh select trong sẽ trả về giá trị lương lớn nhất nhưng không phải lớn nhất trong toàn công ty mà lớn nhất trong phòng của nv1. Sau đó câu lệnh select ngoài cùng sẽ xác định xem nv1 có được chọn không bằng cách kiểm tra lương anh ta với lương lớn nhất của phòng anh ta.
4.3) Truy vấn tổng nhóm (subtotal query / grouping query)
select..group by: Thống kê theo tiêu chí
Hiện ra số lượng các nhân viên ứng với từng quê
select QueQuan, count(*)from NhanVien
group by QueQuan
Đếm số nam và số nữ trong công ty
select GioiTinh, count(*)from NhanVien
group by GioiTinh
Tính tổng thu nhập theo từng phòng
select Phong, sum(Luong)from NhanVien
group by Phong
select..having: Hiện ra một số nhóm phù hợp
Chỉ đếm số lượng người ở Hải Phòng và số lượng người ở Hà nội
select QueQuan, count(*)from NhanVien
group by QueQuan
having (QueQuan = ‘HP’, QueQuan = ‘HN’)
Chỉ hiện ra những phòng nào có tổng thu nhập lớn hơn 500000
select Phong, sum(Luong)from NhanVien
group by Phong
having sum(Luong) >5000000
Chỉ hiện ra những tỉnh nào có số lượng người lớn hơn 10
select QueQuan, count(*)from NhanVien
group by QueQuan
having count(*) >10
select..inner join: ghép các cặp bản ghi thỏa mãn điều kiện
Ghép bảng nhân viên và hiện ra tên nhân viên và tên địa phương
select NhanVien.TenNV, DiaPhuong.TenDP
from NhanVien
inner join DiaPhuong on NhanVien.QueQuan = DiaPhuong.MaDP
select..left outer join: lấy tất cả phía trái và ghép (nếu có) với phải
Lấy tất cả những nhân viên kể cả những nhân viên có quê quán không hợp lệ (nghĩa là mã quê quán không có trong bảng địa phương)
select NhanVien.TenNV, DiaPhuong.TenDP
from NhanVien
left outer join DiaPhuong on NhanVien.QueQuan = DiaPhuong.MaDP
select..right outer join: lấy tất cả phía phải và ghép (nếu có) với phía trái
Lấy tất cả những địa phương ghép với nhân viên, các địa phương không hợp lệ sẽ được ghép với bộ dữ liệu rỗng. Không hiện ra các nhân viên không có mã quê quán phù hợp
select NhanVien.TenNV, DiaPhuong.TenDP
from NhanVien
right outer join DiaPhuong on NhanVien.QueQuan = DiaPhuong.MaDP
select..full outer join: lấy từ hai phía và ghép nếu có
Lấy tất cả những nhân viên (nếu không có quê quán phù hợp thì ghép với bộ dữ liệu rỗng) và tất cả những địa phương kể cả không có nhân viên.
select NhanVien.TenNV, DiaPhuong.TenDP
from NhanVien
right outer join DiaPhuong on NhanVien.QueQuan = DiaPhuong.MaDP
select..cross join: trả về tất cả các cặp có thể ghép
Ghép từng nhân viên với tất cả các địa phương. Như vậy nếu có m nhân viên và có n địa phương thì bảng đích sẽ có m*n dòng. n dòng đầu cho nhân viên thứ nhất ghép với các địa phương. n dòng sau cho nhân viên thứ hai ghép với các địa phương. và tiếp tục như thế tới nhân viên thứ m.
select NhanVien.TenNV, DiaPhuong.TenDP
from NhanVien
cross join DiaPhuong
ref: Tham khảo thêm một số lệnh
Xem tất cả các CƠ SỞ DỮ LIỆU người dùng trong MÁY CHỦ
Mỗi khi một cơ sở dữ liệu được tạo ra, bảng sysdatabase trong cơ sở dữ liệu master sẽ chứa thông tin về bảng mới tạo ra đó. Do vậy chúng ta có thể liệt kê tất cả các cơ sở dữ liệu trong một máy chủ bằng cách liệt kê các bản ghi trong bảng sysdatabase
select *
from master.dbo.sysdatabases
where sid <>1
Xem tất cả các BẢNG người dùng trong CƠ SỞ DỮ LIỆU
Mỗi khi một bảng được tạo ra trong một cơ sở dữ liệu, thông tin về bảng đó sẽ được chứa trong bảng sysobjects của chính cơ sở dữ liệu chứa bảng vừa tạo. Vì vậy chúng ta có thể xem danh sách các bảng trong cơ sở dữ liệu bằng cách truy vấn bảng sysobjects. Các bảng do người dùng tạo có kiểu là ‘U’
select *
from Northwind.dbo.sysobjects
where xtype='U'
Trong ví dụ này, chúng ta lấy tất cả các bản ghi bảng sysobjects của cơ sở dữ liệu Northwind nhưng chỉ lấy những bảng người dùng, nghĩa là những bảng có xtype là ‘U’
Xem tất cả các CỘT thuộc về một BẢNG
Mỗi khi một cột trong bảng được tạo, bảng syscolumns trong cơ sở dữ liệu sẽ chứa thông tin về cột vừa tạo. Thuộc tính id của cột sẽ chứa định danh của bảng mà cột đó thuộc về. Vì vậy để xem các cột trong một bảng dữ liệu, chúng ta có thể truy vấn bảng syscolumns
declare @x intset @x = (select id from sysobjects where name='Employees')
select * from syscolumns where id = @x
Trong ví dụ này, ta khai báo biến @x kiểu int, sau đó lấy id của bảng Employees vào biến @x, rồi ta lấy tất cả các cột trong bảng syscolumns mà có id bằng @x, cũng có nghĩa là id của bảng Employees. Do vậy ta sẽ liệt kê được tất cả các cột trong bảng Employees
Sử dụng bảng tạm
Khai báo bảng, cập nhật bảng, và hiện bảng
declare @x table(MaSV int, TenSV nvarchar(20))
insert into @x values(1, N'Thưởng')
insert into @x values(2, N'Yến')
select * from @x
Khai báo bảng, tải bảng khác từ trong cơ sở dữ liệu lên bảng vừa khai báo, và hiện bảng
declare @x table(MaSV int, TenSV nvarchar(20))
insert into @x
select EmployeeID, firstname
from Northwind.dbo.Employees
select * from @x
Sử dụng biến tạm
declare @t moneyset @t = (select max(UnitPrice) from Northwind.dbo.products)
select * from Northwind.dbo.products where UnitPrice >= @t
ref: Các khái niệm cơ bản của cơ sở dữ liệu
Các mô hình dữ liệu (data model)
+ Mô hình thứ bậc (hierarchical)
+ Mô hình mạng lưới (network)
+ Mô hình quan hệ (relational)
Các vấn đề của lưu trữ
+ Sự dư thừa (redundance)
+ Sự nhất quán (consistence)
+ Tính toàn vẹn (integrity)
+ Sự an toàn (security)
+ Sự chia sẻ (sharing)
Các khái niệm cơ bản
+ Cơ sở dữ liệu (database)
+ Bảng (table) hoặc quan hệ (relation)
+ Bản ghi (record) hoặc dòng (row) hoặc bộ (tuple)
+ Trường (field) hoặc cột (column)
+ Mối quan hệ (relationship) được biểu hiện bằng bảng (table) hoặc khóa (key)
Mối quan hệ giữa các
+ Tại sao phải lưu mối quan hệ
+ Phương pháp lưu các mối quan hệ (dùng khóa, dùng bảng)
+ Khóa chính (primary key) và khóa ngoài (foreign key)
+ Vấn đề toàn vẹn tham chiếu (referential integrity)
Ngôn ngữ định nghĩa và xử lý dữ liệu
+ Thao tác trên các đối tượng như cơ sở dữ liệu, bảng, cột
+ Phần định nghĩa cơ sở dữ liệu và bảng: create, drop, alter
+ Phần cập nhật dữ liệu: insert, delete, update
+ Phần truy vấn dữ liệu: join, union, projection, selection, sort, group
+ Phần lập trình và thao tác: declare, set, use, go
ref: Liên quan tới định nghĩa bảng
Các vấn đề về toàn vẹn dữ liệu
+ Toàn vẹn thực thể (entity integrity): primary key, unique, identity
+ Toàn vẹn tham chiếu (referential integrity): foreign key, check
+ Toàn vẹn miền dữ liệu (domain integrity): default, foreign key, check, not null
+ Toàn vẹn người dùng (user integrity): rules, stored procedures, triggers
Các hỗ trợ với toàn vẹn
+ Ràng buộc kiểm tra (check constraint): phải thỏa mãn điều kiện nào đó
+ Ràng buộc mặc định (default constraint): phải có một giá trị mặc định
+ Ràng buộc duy nhất (unique constraint): các giá trị trong cột không được trùng lặp
+ Ràng buộc khóa ngoài (foreign key constraint): các giá trị phải hợp lệ với cột khóa chính tương ứng
+ Ràng buộc khóa chính (primary key constraint): phải duy nhất và không trống
+ Thuộc tính định danh (identity property): có thể được tăng tự động
+ Thuộc tính không trống (not null property): không được phép để trống
Các kiểu dữ liệu
Giá trị nhị phân: bit
Các số nguyên: bigint, int, smallint, tinyint
Các số thực xấp xỉ: float, real
Giá trị số thực chính xác: decimal, numberic
Giá trị tiền tệ: money, smallmoney
Giá trị hời gian: datetime, smalldatetime
Các chuỗi: char, varchar, text, nchar, nvarchar, ntext,
Các chuỗi nhị phân: binary, varbinary, image
Các kiểu khác: cursor, table, variant, timestamp, uniqueidentifier
Bài viết được sự cho phép của BBT Tạp chí Lập trình
Việc có kiến thức không đồng nghĩa với việc có kỹ năng và khả năng thực tế để áp dụng kiến thức đó vào việc tạo ra các ứng dụng phần mềm. Đây là lý do nghề thủ công trở lên quan trọng. —Pete McBreen, Software Craftsmanship
Bối cảnh
Bạn đang tìm kiếm vị trí làm việc trong đội ngũ thợ lành nghề giỏi nơi mang đến cho bạn những cơ hội học tập tốt hơn những gì bạn đang có.
Thật không may, nhóm này không có lý do gì để liều lĩnh thuê một người có thể không trực tiếp đóng góp vào việc xử lý khối lượng công việc của nhóm. Họ cũng có thể sẽ phải đối mặt với khả năng bạn không đủ sức để gián tiếp đóng góp, chẳng hạn như bằng cách tự động hoá một số công việc thủ công đơn giản.
Giải pháp
Hãy sở hữu và duy trì những kĩ năng cụ thể. Mặc dù một thợ học việc có thể hứa với nhóm rằng mình có khả năng học hỏi nhanh chóng, nhưng nếu bạn sở hữu khả năng cụ thể và nhìn thấy được về việc sử dụng các công nghệ và công cụ nhất định, thì nhóm có nhiều lí do hơn để tin rằng bạn đủ khả năng để đóng góp gián tiếp trước khi trưởng thành hơn.
Bạn sẽ cần nhiều hơn một chút so với số kỹ năng cụ thể mà trước đó bạn chuẩn bị cho các cuộc phỏng vấn với các bộ phận nhân sự và các quản lý trong các công ty. Những người khác sẽ trấn an thành viên trong nhóm rằng bạn hữu dụng và họ sẽ không cần “day care” (Patterns of Agile Software Development, trang 88). Một số ví dụ về các kỹ năng cụ thể là khả năng viết các file build cho một số ngôn ngữ thông dụng, hiểu biết về một số framework mã nguồn mở như Hibernate và Struts, kỹ năng thiết kế web cơ bản, JavaScript và các thư viện cơ bản trong ngôn ngữ bạn chọn.
Vấn đề là bạn sẽ thường yêu cầu các nhà quản lý – người đang thuê bạn – phải đánh cược vào việc chọn bạn. Các kỹ năng cụ thể (những cũng vừa đủ đơn giản để bạn có thể mang một ứng dụng nhỏ đến cho cuộc phỏng vấn) cho phép bạn thỏa hiệp với họ. Các kỹ năng cụ thể chính là câu trả lời của bạn cho câu hỏi: “Nếu hôm nay chúng tôi thuê bạn, bạn có thể làm gì vào sáng Thứ Hai nhằm mang lại lợi ích cho chúng tôi?”. Bằng việc hiểu rõ Ngôn Ngữ Đầu Tiên bạn sẽ tạo sự tín nhiệm và chứng minh cho nhóm của mình rằng bạn cực kì hữu dụng.
Khi bạn bắt đầu chuyển đổi sang vai trò của một nhân viên, bạn sẽ ít phụ thuộc vào những kỹ năng này, bởi vì khi đó bạn bắt đầu được thuê dựa trên danh tiếng, danh mục công việc của bạn và những phẩm chất quan trọng hơn hơn mà bạn mang đến cho một nhóm. Nhưng trước khi đến thời điểm đó, bạn cần làm nổi bật hơn các đức tính tốt của mình.
Dave lấp đầy khoảng trống
Giống như hầu hết những ai chuyển sang công việc lập chương trình “muộn màng”, tôi có nhiều trải nghiệm sống, nhiều hơn con số 6 tháng kinh nghiệm trung bình của các lập trình viên. Trong quá trình làm việc trước đây, tôi đã phát triển tất cả các kĩ năng giao tiếp và hiểu biết tâm lý. Khi tôi cố gắng trở thành lập trình viên, tôi gặp những người quá thích thú về những gì tôi đã làm, điều này khiến tôi thỉnh thoảng đánh giá quá cao các kĩ năng mềm này và nói quá nhiều về những chủ đề không phải chuyên môn. Chắc chắn là các kĩ năng này giúp tôi rất nhiều trong nhiều tình huống; tuy nhiên, tôi phải giảm những kĩ năng này đi để tập trung nhiều hơn vào việc phát triển các kĩ năng chuyên môn mà tôi còn thiếu. Tôi không thay đổi nghề của mình để có thể trở thành người trị liệu cho các lập trình viên, tôi thay đổi nghề nghiệp bởi tôi thích việc tạo ra phần mềm. -David H. Hoover
Hành động
Hãy thu thập những CV của những người có kĩ năng mà bạn trân trọng. Bạn có thể hỏi xin họ một bản sao hoặc tải CV từ trang web của họ. Với mỗi người, bạn cần xác định năm kỹ năng riêng biệt mà họ đề cập trong CV và tiến hành xác định những kĩ năng nào trong số đó ngay lập tức có ích cho nhóm mà bạn muốn tham gia. Soạn một kế hoạch và một dự án nhỏ để chứng minh rằng bạn đã có được những kỹ năng này. Thực hiện kế hoạch.
Tập thói quen thường xuyên soát kĩ CV của mình. Khi đó, hãy viết các kĩ năng cụ thể dưới dạng một danh sách riêng biệt. Bạn nghĩ sao nếu biết rằng nhiều nhà quản lý chỉ nhìn vào những điểm bạn nêu trong danh sách này thay vì tất cả kinh nghiệm mà bạn có?
Nó cũng na ná như ở trên nhưng chúng ta không còn await vào câu request, chúng ta cũng không cần dùng async function. Nếu bạn cảm thấy hơi hại não chổ này, thì nên làm thử cái demo nhỏ nhỏ này
Cách làm này có một cái tên khá ghê là Singleton Promise – chỉ dùng một promise duy nhất. Bởi vì chúng ta sẽ dùng cùng một Promise với cùng một userId nên khi có một race condition như cách viết bên dưới
Dapr là gì?
Việc xây dựng hệ thống ứng dụng phân tán ngày nay được xem là một trong những vấn đề rất phức tạp, nhất là với các dự án vừa và lớn. Trong quá trình vận hành, ứng dụng sẽ được bỏ vào Docker container để đóng gói, chạy và cũng cần các hệ thống để vận hành theo hướng cloud-native. Một trong những nền tảng hỗ trợ tốt vấn đề này là Kubernetes trên nền tảng Dapr.
Dapr hỗ trợ đắc lực trong việc đơn giản hóa quy trình làm việc với các dự án
Tại sao lại cần đến nền tảng Dapr?
Dapr là viết tắt của Distributed Application Runtime. Thông qua buổi nói chuyện hôm nay, mỗi khái niệm sẽ được làm sáng tỏ và giải thích cặn kẽ các vấn đề liên quan đến hệ thống phân tán, các vấn đề của nó và cách Dapr giúp đơn giản hóa các vấn đề khó khăn này.
Distributed
Như đã biết, các ứng dụng ngày nay đều mang tính Resiliency và Scalability. Đây là những vấn đề rất khó vậy mình phải làm như thế nào để giải quyết vấn đề này? Việc scale một ứng dụng ổn định, phân tán và scale-out các ứng dụng khi vận hành là một quá trình rất phức tạp.
Khi phát triển ứng dụng, nhất là với các ứng dụng phân tán, hệ thống sẽ kết hợp rất nhiều các bộ phận với nhau (văn hóa DevOps), các Developer, IT và DevOps phải phối hợp làm việc với nhau để phân phối được ứng dụng một cách thành công. Và khi phát triển ứng dụng mới như hiện giờ với Docker và Kubernetes thì các yêu cầu này càng khó và đòi hỏi cao sự chính xác hơn.
Nếu lúc trước có Docker đã khá khó thì giờ có Kubernetes còn khó và đa dạng hơn nên nó đòi hỏi phải có nhiều kiến thức ở các lĩnh vực như IT, networking, lập trình ứng dụng (kết hợp lại). Service Mesh còn gây bối rối hơn nữa vì một ứng dụng vừa có Kubernetes vừa có Service Mesh thì tính phức tạp sẽ còn tăng cao hơn nhiều.
Khi thiết kế ứng dụng chúng ta còn phải nghĩ đến việc chia các subnet cho network của ứng dụng như thế nào? Những câu hỏi đặt ra cần giải quyết là chúng ta phải chia subnet, vnet cho từng môi trường như thế nào, để làm sao hệ thống có thể chạy được trên nhiều nền tảng khác nhau và phân hoạch để đảm bảo tính bảo mật cho toàn hệ thống?
Application
Hiện nay khi xây dựng hệ thống doanh nghiệp, mọi người đều nghĩ về việc làm sao để một hệ thống “nói chuyện” với một hệ thống khác thông qua cơ chế event. Rồi đến việc phải sử dụng Actor-Model như thế nào, vì xây dựng ứng dụng doanh nghiệp thì một ứng dụng cần có và lưu trữ trạng thái (như thiết kế một hệ thống về payment chẳng hạn, theo dõi các đơn hàng đã checkout…), phải nghĩ đến các long running task để chạy tự động khi không có tương tác trực tiếp từ người dùng chẳng hạn. Và để tiết kiệm chi phí thì serverless cũng đang được nhiều doanh nghiệp cân nhắc.
Tất cả mọi vấn đề vừa đặt ra ngăn cản rất nhiều mô hình phát triển enterprise application vì chưa được hệ thống hóa một cách triệt để. Một điểm khác nữa là dù chúng ta làm việc trên hệ thống mới thì cũng không nên bỏ quên hệ thống cũ, vì việc làm sao đưa một hệ thống cũ (vẫn đang chạy tốt và tạo ra doanh thu cho doanh nghiệp) vào hệ thống mới cũng là yếu tố vô cùng quan trọng và mang tính sống còn.
Trong buổi nói chuyện này, Phương và Thắng cũng muốn khai thác và chia sẻ thêm các kinh nghiệm thực tế khi làm các dự án ở Nashtech để người đọc dễ dàng hiểu rõ hơn. Đó là khi tích hợp hệ thống cũ vào hệ thống mới sẽ rất khó, đòi hỏi nhiều kinh nghiệm trên nền yêu cầu chức năng và kiến thức của hệ thống cũ để hoàn thiện quy trình tích hợp. Vì những công nghệ hiện giờ chưa được build-in sẵn để hỗ trợ việc intercommunication, state management, pub/sub, event bindings,… Và sau khi xây dựng và tích hợp hệ thống xong, điều quan trọng là phải vận hành được nó. Bên cạnh đó, bảo mật cũng là một vấn đề quan trọng. Khi làm việc với các hệ thống của châu Âu thì có thêm loại bảo mật rất nổi trội chính là GDPR.
Đa phần khi làm việc với các ứng dụng ngày nay, các developer sẽ nghĩ đến việc tìm một package để sử dụng cho ngôn ngữ đang làm việc, chẳng hạn như 1 node package để gửi email chẳng hạn. Sau đó cài vào ứng dụng của mình để viết code và cấu hình thêm những yếu tố cần thiết khác để tạo nên một chức năng có thể chạy được.
Vấn đề lúc này là một ứng dụng thực tế sẽ không chỉ xài một thư viện mà sẽ cần rất nhiều thư viện và cũng có rất nhiều providers trên thị trường, ví dụ như SendGrid, local mail server… Và thực tế ta phải rẽ nhánh trong code ứng dụng để thỏa mãn việc sử dụng nhiều loại provider cho nhiều môi trường triển khai. Trong khi lẽ ra mình nên tập trung vào việc giải quyết vấn đề của business thì bây giờ, nếu sản phẩm bị bug sẽ phải giải quyết thêm vấn đề của các thư viện kết nối với các dịch vụ từ xa. Trong phát triển phần mềm gọi là vấn đề vendor-locking.
Một vấn đề khác nữa là quản lý versioning, đôi khi chúng ta muốn upgrade version nhưng lại bị ảnh hưởng lên các thư viện khiến việc upgrade trở nên khó khăn hơn. Lại nói tiếp về Portability trong việc xây dựng ứng dụng, hiện nay có 2 vấn đề cần phải giải quyết:
Khi làm việc với môi trường phân tán và đám mây thì làm sao để chạy được trên local có Docker hay không có Docker và làm sao để hệ thống chạy được trên Kubernetes trên local và trên đám mây? Rõ ràng rằng việc được cái này phải chấp nhận mất cái kia là điều không tránh được. Sẽ phải thỏa mãn rất nhiều thứ phức tạp khiến các developer gặp khó khăn trong việc xây dựng ứng dụng hiện nay. Vậy giải pháp cho những vấn đề này như thế nào? Dapr sẽ giải quyết vấn đề này.
Nền tảng Dapr giúp gì trong quá trình làm việc?
Dapr là tập hợp có thể giải quyết các vấn đề khó khăn mà chúng ta vừa kể trên, cô đọng lại vào các khối nền dùng chung (building blocks) có sẵn và chỉ cần đưa vào ứng dụng rồi sử dụng nó mà thôi. Có thể hiểu building blocks như một platform ở dưới làm nền tảng để phát triển các ứng dụng phía trên theo hướng cloud-native. Khi muốn build một hệ thống có nhiều ngôn ngữ (polyglot languages) như .NET, Java, Nodejs, Go… thì độ phức tạp do việc phải bảo trì cùng lúc nhiều ngôn ngữ lập trình và các stack ngôn ngữ của nhóm phát triển dự án sẽ tăng lên. Nghĩa là trong nhóm phải có một người có thể làm nhiều ngôn ngữ hay một người có thể làm nhiều framework khác nhau (fullstack và cross-stack).
Tuy nhiên vấn đề khó khăn ở đây là, chúng ta không thể dùng ngôn ngữ đó để giải quyết vấn đề kinh doanh vì phải tập trung quá nhiều vấn đề kỹ thuật và đơn thuần chỉ là kỹ thuật. May mắn Dapr khắc phục được vấn đề đó qua các khối building-blocks, mô hình độc lập nền tảng và các stack ngôn ngữ (agnostic platform và programming languages). Khi làm việc với Dapr, chúng ta chỉ phải tập trung giải quyết code business của ứng dụng, còn những phần khác Dapr sẽ giúp chúng ta. Vậy nên khi phát triển một ứng dụng với Dapr thì việc có thể tận dụng nhiều ngôn ngữ khác nhau, nhiều framework khác nhau là chuyện hoàn toàn có thể làm được.
Sự hỗ trợ nhiều từ cộng đồng cũng là một điểm mạnh của Dapr. Ý tưởng này được phát triển đầu tiên bởi CTO và các thành viên chủ chốt của Microsoft, sau đó trở thành open-source. Đến bây giờ thì không chỉ có Microsoft mà các cộng đồng ở những công ty khác cũng có thể đóng góp thêm nhiều ý tưởng và xây dựng cộng đồng rộng lớn không chỉ chạy trên Azure cloud mà còn các dịch vụ của Google Cloud, AWS hay Alibaba cloud. Cộng đồng này rất biết cách lắng nghe, khi có ý tưởng hay bạn có thể đệ trình lên nơi lưu trữ của Dapr trên Github hoặc cũng có thể tạo các pull-request để đóng góp ngược lại vào Dapr cho các phiên bản release tiếp theo.
Dapr hỗ trợ đa ngôn ngữ và framework
Để mọi thứ hoạt động trơn tru hơn trên nhiều nền tảng hay nhà cung cấp đám mây khác nhau, thì Dapr phải tuân theo và yêu cầu các Developer tuân thủ các chuẩn của công nghệ phần mềm cho các phần như communication, Rest API,… Về Open APIs, Dapr xây dựng trên nền có sẵn của Kubernetes, và bản thân Kubernetes có bộ API cho riêng nó phía trên và cho phép thao tác từ bên ngoài vào thông qua các CLI hoặc Rest API để thao tác trực tiếp vào những thành phần (Dapr gọi nó là Component) hiện sẵn có trong nền tảng Dapr.
Điểm hay nhất ở đây là có thể chạy ở bất kỳ nền tảng nào (on-prem hoặc on-cloud và thậm chí trong các thiết bị IoT). Vì Dapr có thể mở rộng (extensible) và và có thể gắn thêm (plugable) nên chúng ta có thể sử dụng rất nhiều Component từ phía nhà phát triển Dapr hoặc cộng đồng phát triển. Hiện nay, 3 công ty điện toán đám mây lớn trên thế giới (AWS, Azure, Google Cloud) đều đang đóng góp cho Dapr và họ đã viết những Component mềm dẻo cho các dịch vụ đám mây của họ để có thể gắn kết vào Dapr.
Việc của các Developer là tải về, cấu hình và thay đổi các thông tin cấu hình theo các thông tin các nhân của từng người sử dụng đám mây cho các service đó là có thể sử dụng ngay lập tức.
Micro Service Building Blocks
Dapr sinh ra để giải quyết vấn đề mà hiện tại đang khiến mọi người rất đau đầu trong việc giải quyết bài toán hệ thống phân tán: Đó là với Microservice, nếu không có Kubernetes và Dapr, chúng ta phải có 1 cơ chế Service Discovery để trừu tượng hóa các địa chỉ IP và Port của các service (Dapr gọi là app); Còn với Kubernetes và Dapr thì đơn giản hơn rất nhiều, bạn chỉ cần biết tên của service (app), giống như một khi tìm một nhà nào đó thì mình chỉ cần biết được địa chỉ của nhà đó rồi đến mà thôi chứ không quan tâm đến các chi tiết bên trong ngôi nhà.
Kubernetes Service chỉ quan tâm đến traffic từ bên ngoài vào và đó là lý do nó chỉ quan tâm đến service name. Dapr thừa hưởng các đặc tính này Kubernetes.
Với Dapr, chúng ta được tiếp cận với một khái niệm gọi là state-management. Cho đến nay khi xây dựng 1 ứng dụng, chúng ta thường có 2 dạng là stateless và stateful. Chúng khá nhập nhằng khiến các Developer không phân biệt được rõ ràng. Dapr thống nhất 2 khái niệm này với nhau, việc khi nào ứng dụng có trạng thái hoặc khi nào không có trạng thái, mình sẽ đọc tài liệu và code dựa trên 1 public API thống nhất cho phần state management rồi cấu hình để nó hoạt động mà thôi. Dapr không bị vendor-locking nên nó cho phép mình thay đổi dựa trên các môi trường.
Khi chúng ta làm việc với hệ thống phân tán, nếu muốn 1 hệ thống có high throughput và low latency thì nên cân nhắc sử dụng các cơ chế event-based. Dapr có các building-blocks sẵn có cho việc giúp chúng ta dễ tiếp cận với các kiểu publish/subscribe, send/receive message. Các message tuân thủ chuẩn cloud-event nên có thể được consume dễ dàng trên các nền tảng đám mây khác nhau hoặc on-prem (nếu có), và vì được chuẩn hóa nên nó đa dạng cho nhiều lại message brokers và các hệ thống message khác nhau điển hình như Kafka.
2. Resource binding và trigger
Resource binding và trigger là một vấn đề khá hay. Trong hệ thống phần mềm phức tạp, ta luôn có rất nhiều thành phần cần tính theo thời gian (trigger). Lấy ví dụ, Dapr trừu tượng hóa cả việc làm sao một cái tệp tin được bỏ vào Blob Storage, và bắt các sự kiện để trigger ra ngoài để các hệ thống/function khác nhận lấy và thực thi các hoạt động mở rộng trên cơ thế tệp tin. Chẳng hạn như sẽ gửi mail cho những người liên quan khi có các thao tác cập nhật nội dung tệp tin.
Dapr giải quyết chuyện này bằng khái niệm input và output. Input là event đi tới và output là trigger các sự kiện cho các hệ thống khác xử lý tiếp theo. Hiện tại được sử dụng khá nhiều cho các cơ chế của các thiết bị IoT, việc phân tích dữ liệu nâng cao,… Và đó là là resource bindings.
3. Actors Model
Actors Model với từng ngôn ngữ lập trình sẽ có các thư viện và cách sử dụng khác nhau, chẳng hạn như Akka, Orleans, Actix,… Sẽ có rất nhiều dạng ứng dụng trong thực tế sử dụng mô hình actors, nhóm phát triển Dapr cũng nghĩ thế và trừu tượng hóa nó thành 1 cách sử dụng dễ dàng nhưng cũng vô cùng mạnh mẽ. Việc sử dụng Actors Model trên Dapr giúp việc scale ứng dụng trên mô hình phân tán đơn giản hơn.
Micro Service Building Blocks là hệ thống của Dapr với nhiều thế mạnh
4. Security với nền tảng Dapr
Quản lý những thông tin bí mật như password của database, các secret keys cũng là thế mạnh của Dapr. Với bài toán thường, sẽ phải sử dụng những file cấu hình hoặc biến môi trường để mô tả theo từng môi trường riêng rẽ. Dapr đưa ra một chuẩn riêng với các key value, sử dụng với sản phẩm và cấu hình phù hợp. Điểm hay là tất cả các cấu hình này có thể chạy được trên các môi trường độc lập khác nhau và không cần phải kiểm thử lại.
5. Extensible
Dapr hỗ trợ mở rộng trong trường hợp mình muốn có thêm các Components và các behavior mới trong ứng dụng. Dapr hỗ trợ phát triển ứng dụng rất tốt nhưng nó lại độc lập với ứng dụng đang làm việc nên câu hỏi đặt ra là khi sử dụng với các ngôn ngữ .NET, Java, Nodejs, Python, Go, và Rust thì có cần cài đặt Dapr vào trong ứng dụng hay không?
Câu trả lời là thật sự chúng ta không cần cài đặt bất cứ Dapr nào vào ứng dụng của mình hết.
Vậy nền tảng Dapr sẽ giải quyết vấn đề như thế nào?
Sidecar và Component Architecture
Với quá trình làm việc này, service productcatalog lấy thông tin của product và service shoppingcartapp là thông tin trên giỏ hàng, bài toán cần giải quyết là khi thêm các items vào giỏ hàng, Dapr hoạt động trên mô hình này như thế nào?
Nếu làm theo cách cũ, catalogproductapp service sẽ call API của shoppingcartapp service, tuy nhiên với Dapr nó không cần call trực tiếp mà sẽ thông qua một Dapr Sidecar. Mỗi service sẽ có Dapr Sidecar đứng kế bên. Trong trường hợp này, Dapr Sidecar của productcatalogapp sẽ call đến Dapr Sidecar của shoppingcartapp để lấy dữ liệu, khi đó Dapr Sidecar của shoppingcartapp sẽ gọi vô internal API của shoppingcartapp để lấy và trả dữ liệu về cho Dapr Sidecar của productcatalogapp.
Sau đó Dapr Sidecar của productcatalogapp sẽ trả dữ liệu này vào service bên trong. Mô hình này làm việc như một dạng thông dịch và chạy độc lập không phụ thuộc các ngôn ngữ lập trình, miễn là bạn có Sidecar cho từng service.
Nhờ mô hình làm việc này nên Dapr sẽ có rất nhiều thông tin về logs, metrics để chuyển về trung tâm. Đó là lý do chúng ta không cần cài đặt Dapr cho ứng dụng vì ứng dụng chỉ biết rằng Dapr đang cung cấp một chuẩn API và call chuẩn API đó mà thôi. Đây là được xem là “nét đẹp” của Dapr.
Và kể cả nếu chạy trên Kubernetes cũng không cần thay đổi mô hình hoạt động này. Vì thật ra nó chỉ là những cấu hình nên khi chúng ta muốn thay bằng các Component khác thì chỉ phải đổi Component trong thư mục Components của Dapr mà thôi, nhờ về việc tránh vendor-locking như đề cập ở trên.
Để Kubernetes hiểu được các cấu hình, thông số thì chắc chắn phải sử dụng Helm chart. Trong Dapr sẽ có các components, core components là thành phần chính để Dapr đọc, nạp và vận hành được. Đối với tất cả các ứng dụng sẽ có ít nhất 2 container, 1 container là ứng dụng application code và 1 container nữa là Dapr Sidecar. Ngoài ra, các components chính là những service bên ngoài. Chúng ta có thể dùng Dapr thông qua các file cấu hình như thế.
Bài viết được trích dẫn từ phần trình bày của anh Phương Lê và Thắng Chung tại sự kiện Vietnam Web Summit 2020 LIVE do TopDev tổ chức
Bạn sẽ không bao giờ có cơ bắp to khỏe nếu chỉ ngồi trên sô pha suốt ngày, và cũng không thể phát huy những sức mạnh tuyệt vời của sự tập trung nếu chỉ đọc Buzzfeed và xem ti-vi. Cũng như các cơ bắp vật lý, cơ bắp tinh thần cần có tính bền bỉ; nó cần những thử thách vượt quá giới hạn để hình thành những “sợi cơ” tập trung. Bên dưới, tôi xin liệt kê những bài tập giúp tăng cường khả năng tập trung để bạn có thể bắt đầu xử lý những công việc đòi hỏi sự tập trung cao hơn.
Nếu bạn quyết định muốn có thân hình cân đối nhưng chỉ vừa mới bắt đầu, bạn không nên dấn thân vào chương trình luyện tập cường độ cao vì điều đó sẽ làm bạn bị chấn thương, nản chí hoặc cả hai, và bạn sẽ bỏ cuộc ngay cả trước khi thật sự bắt đầu.
Tương tự, nếu hiện tại bạn tập trung không được lâu, tốt nhất bạn nên từ từ gia tăng thời lượng mà bạn muốn tập trung. Tôi đề xuất “Phương pháp Pomodoro”, theo đó bạn tập trung trong 45 phút liền và cho bản thân nghỉ ngơi 15 phút. Nhưng đối với nhiều người thì có lẽ 45 phút giống như một chặng đua đường dài của tâm trí!
Vậy hãy bắt đầu với một mục tiêu khá đơn giản và từ đó nâng cao hơn. Hãy đặt đồng hồ hẹn giờ trong 5 phút và hoàn toàn tập trung vào công việc trong khoảng thời gian này. Sau đó, hãy nghỉ ngơi 2 phút trước khi tập trung thêm 5 phút nữa. Mỗi ngày, bạn hãy tăng thời gian tập trung thêm 5 phút, đồng thời cộng thêm thêm 2 phút vào thời gian nghỉ ngơi. Trong 9 ngày, chắc hẳn bạn có thể làm việc liên tục trong 45 phút rồi nghỉ ngơi trong 18 phút. Một khi đã quen với phương thức này, bạn có thể cố gắng kéo dài những khoảng thời gian tập trung hơn một chút và rút ngắn những khoảng nghỉ ngơi lại.
2. GHI LẠI NHỮNG VIỆC GÂY PHÂN TÂM VÀ XỬ LÝ SAU
Bởi internet giúp ta có thể truy cập tức thì bất kỳ thông tin nào, mỗi khi nghĩ ra điều gì đó, ta có xu hướng muốn tra cứu nó ngay. “Không biết thời tiết ngày mai thế nào nhỉ?” “Bộ phim đó đã ra mắt vào năm nào?” “Không biết Facebook của mình có cập nhật gì mới không?” Do đó, ngay khi có những suy nghĩ hoặc câu hỏi như vậy, ta sẽ ngừng tập trung vào công việc đang làm. Vấn đề là một khi bị xao lãng, ta phải mất trung bình 25 phút để quay trở lại công việc ban đầu. Thêm vào đó, việc chuyển đổi sự chú ý từ việc này sang việc khác cũng làm suy giảm sức tập trung của ta.
Vì vậy hãy tiếp tục làm công việc; bất cứ khi nào chợt nghĩ đến một điều mà bạn muốn kiểm tra, hãy viết nó ra một tờ giấy bên cạnh (hoặc ghi chú vào ứng dụng Evernote), và tự hứa với bản thân rằng sau khi hết thời gian tập trung và đến lúc giải lao, bạn sẽ quay lại kiểm tra.
Khi bị xao lãng, bạn phải mất trung bình 25 phút để quay trở lại công việc ban đầu!
3. XÂY DỰNG Ý CHÍ
Sự tập trung có chủ ý và ý chí gắn liền với nhau. Ý chí cho phép ta bỏ qua có ý thức những yếu tố gây xao lãng trong khi vẫn tập trung vào công việc đang làm.
4. THIỀN ĐỊNH
Thiền định không chỉ giúp bạn giữ bình tĩnh, thanh thản và tự chủ, các nghiên cứu còn nhiều lần cho thấy rằng thiền chính niệm có thể giúp bạn tập trung lâu hơn đáng kể.
Trong một nghiên cứu, 140 tình nguyện viên tham gia một khóa tập thiền 8 tuần. Sau khoảng thời gian đó, thời gian tập trung cũng như những chức năng nhận thức quan trọng khác của tất cả tình nguyện viên đều được cải thiện rõ rệt .
Bạn không phải dành cả ngày đến một thiền viện để ngồi thiền nhằm tận dụng sức mạnh gia tăng sự tập trung của nơi đó. Nghiên cứu cho thấy chỉ cần ngồi thiền 10 đến 20 phút mỗi ngàycũng cho kết quả như mong đợi. Hơn nữa, thậm chí bạn còn thấy khả năng tập trung của mình được cải thiện chỉ sau 4 ngày.
Vì vậy, nếu bạn muốn tập trung học một lúc nhiều giờ liền, hãy bắt đầu buổi sáng bằng việc tập trung vào hơi thở.
5. THỰC HÀNH CHÍNH NIỆM XUYÊN SUỐT MỘT NGÀY
Bên cạnh việc dành 10 đến 20 phút mỗi ngày để thiền chính niệm, các chuyên gia về khả năng tập trung khuyên ta nên tìm cơ hội thực hành chính niệm xuyên suốt một ngày. Chính niệm đơn giản là tập trung trọn vẹn vào việc bạn đang làm, suy nghĩ chậm lại, và quan sát tất cả những cảm nhận về cơ thể và tinh thần mà bạn đang trải nghiệm vào lúc đó. Bạn cũng có thể thực hành chính niệm khi ăn bằng cách nhai chậm và tập trung vào mùi vị cũng như kết cấu của thức ăn.
Việc đưa những khoảng thời gian thực hành chính niệm vào suốt một ngày sẽ giúp bạn củng cố sự tập trung và tập trung lâu hơn những khi bạn thật sự cần.
Chính niệm cũng có thể giúp chống lại các yếu tố gây xao lãng khi nó xuất hiện. Nếu bạn đang làm việc nhưng lại cảm thấy rất muốn đứng dậy làm gì đó khác, hãy tự nhủ,“Ngồi yên tại đây nào.” Vào lúc đó, hãy chú ý đến cơ thể và hơi thở của bạn. Sau vài giây tập trung vào hơi thở, bạn sẽ nhận thấy yếu tố gây xao lãng biến mất và giờ thì bạn sẵn sàng quay lại với công việc.
Thiền định và thực hành chánh niệm cũng là cách cải thiện khả năng tập trung.
6. TẬP THỂ DỤC
Bạn không chỉ có thể so sánh việc rèn luyện tâm trí với rèn luyện cơ thể, mà việc rèn luyện cơ thể còn thật sự mang đến những lợi ích cho tâm trí một cách trực tiếp. Các nhà nghiên cứu phát hiện ra rằng những học sinh tập thể dục ở cường độ vừa phải trước khi kiểm tra khả năng tập trung đạt kết quả tốt hơn những học sinh không tập. Các nhà nghiên cứu nhận thấy việc tập thể dục chủ yếu giúp não bộ phớt lờ các yếu tố gây xao lãng, mặc dù họ chưa tìm được lý do chính xác. Tôi xin nói rằng việc kỷ luật bản thân để chịu đựng sự vất vả của một buổi tập giúp củng cố lượng ý chí tương đương với khi ta phớt lờ các yếu tố gây xao lãng để tiếp tục làm việc/tập trung.
7. TẬP GHI NHỚ
Đây không những là một mẹo hay để tạo ấn tượng mà còn là một cách tuyệt vời để rèn luyện cơ bắp tinh thần. Hãy đặt ra mục tiêu học thuộc một bài thơ hoặc một đoạn văn mỗi tuần.
8. ĐỌC NHỮNG NỘI DUNG DÀI MỘT CÁCH CHẬM RÃI
Với sự phát triển của máy tính bảng, máy đọc sách và điện thoại thông minh, một số nghiên cứu chỉ ra rằng việc đọc các nội dung điện tử nói chung đã tăng đến gần 40%. Chắc hẳn bạn nghĩ đó là một điều tốt, nhưng tạp chí Slate gần đây đã thực hiện một số nghiên cứu với sự giúp đỡ của công ty phân tích trang web Chartbeat. Kết quả cho thấy chỉ vỏn vẹn 5% người đọc một bài báo điện tử thật sự đọc đến hết bài. Ngoài ra, 38% người đọc không bao giờ đọc nhiều hơn vài đoạn đầu. Vì vậy, việc nói rằng mọi người đọc nhiều hơn là chưa đúng. Điều chúng ta đang làm thật sự chỉ là cuộn lên cuộn xuống nhiều hơn và ít đọc hơn.
Đồng thời, chúng ta cũng đọc ít sách hơn; một nghiên cứu gần đây cho thấy 25% người Mỹ không đọc một quyển sách nào trong năm vừa qua.
Đây thật sự là điều đáng xấu hổ. Tuy dài không hẳn đồng nghĩa với chất lượng cao hơn, nhưng có những ý tưởng phức tạp nhất định không thể nào được gói gọn trong một bài viết ngắn mà phải được viết thành một quyển sách (hoặc vài quyển) để làm rõ. Bỏ qua một nội dung nào đó chỉ vì nó dài là bỏ lỡ cả một kho kiến thức mà chỉ những người sẵn lòng tìm hiểu sâu hơn mới tiếp cận được. Nhất định có một nơi dành cho việc đọc lướt và học một phần nhỏ kiến thức, nhưng bạn cũng nên dành thời gian đọc thấu đáo một vài chủ đề nào đó.
Nếu lâu rồi bạn không đọc sách, tôi thách thức bạn đọc một quyển tối nay. Hãy thật sự tập trung đọc quyển sách đó. Hãy học cách đọc sách sao cho hợp lý, và thói quen đó sẽ thay đổi cuộc đời bạn.
Bên cạnh những quyển sách, hãy cố gắng đọc một hoặc hai bài viết dài mỗi tuần.
Hãy cố gắng đọc sách hoặc những nội dung dài một cách chậm rãi.
9. HÃY HIẾU KỲ
Càng hiếu kỳ, sức mạnh tập trung của bạn càng cao. William James gợi ý một thí nghiệm đơn giản để xem việc hiếu kỳ về một chủ đề bạn quan tâm có thể giúp bạn tập trung vào chủ đề đó lâu hơn đến mức nào:
“Hãy cố gắng nhìn chằm chằm vào một cái chấm trên tờ giấy hoặc trên tường. Bây giờ bạn sẽ phát hiện một trong hai chuyện sau xảy ra: hoặc tầm nhìn của bạn mờ đi nên giờ bạn không thấy rõ gì cả, hoặc bạn vô tình không còn nhìn chằm chằm vào cái chấm đó nữa mà đang nhìn thứ khác. Nhưng nếu bạn liên tục hỏi bản thân về cái chấm đó, như nó to cỡ nào, cách bạn bao xa, có hình dạng và màu sắc ra sao, v.v…; nói cách khác, nếu bạn xem xét nó, nghĩ đến nó theo nhiều cách khác nhau, cùng với những kiểu liên hệ khác nhau – bạn có thể tập trung vào nó trong một thời gian tương đối dài. Đây là điều mà các thiên tài vốn làm, họ tìm hiểu một đề tài đến nơi đến chốn và phát triển nó.”
Charles Darwin là bậc thầy về khái niệm này. Những người cùng thời trầm trồ trước khả năng dành cả ngày quan sát động vật và thực vật của ông. Bí quyết của Darwin là không bao giờ thôi hiếu kỳ – ông có thể khám phá ngày càng nhiều hơn về một vật thể đơn lẻ bằng cách tập trung vào các chi tiết khác nhau, xem xét theo nhiều cách và đặt những câu hỏi mới. Ông khám phá nó từng chút một.
10. THỰC HÀNH LẮNG NGHE CHỦ ĐỘNG
Tập trung không chỉ hữu ích cho những công việc trí óc, nó cũng là kỹ năng thiết yếu để giao tiếp. Khả năng hiện diện trọn vẹn bên một người thân yêu hay bạn bè giúp bạn xây dựng mối quan hệ, sự thân thiết và tin tưởng giữa bạn và họ. Đồng thời, việc cố gắng tập trung hết sức để lắng nghe người khác giúp toàn bộ cơ bắp tập trung của bạn mạnh lên. Đây là một việc có lợi cho cả hai bên. Vì vậy lần sau khi nói chuyện với người bạn yêu thương nhất, hãy đặt điện thoại sang một bên và chú ý lắng nghe hết sức có thể.
Bài viết được sự cho phép của BBT Tạp chí Lập trình
Dù bạn là người đang học code hay đã có thâm niên coding vài năm thì những cuộc “cách mạng” công nghệ hiện nay vẫn có thể khiến bạn tụt hậu nhanh chóng nếu không giắt túi vài bí kíp tự học hiệu quả để luôn học những điều mới mẻ, và nâng cấp những năng lực sẵn có trong người.
Có những bí kíp thuần kinh nghiệm, có vài bí kíp nghe thì hay nhưng hên xui, và cũng có những bí kíp đã được khoa học kiểm chứng về tính hiệu quả. Bài này chia sẻ vài cách thức được đúc rút từ các nghiên cứu khoa học về việc học tập hiệu quả, hoặc của những cao thủ trong nghề viết mã.
1. Hãy luyện tập phân bổ, đừng học cuốn chiếu, và thật có chủ đích.
Theo một nghiên cứu của nhiều nhà khoa học đăng trên tập san “Psychological Science in the Public Interest ”, bạn không nên học kiểu dồn ép và cuốn chiếu mà nên phân bổ kiến thức ra. Ví dụ, khi bạn học một ngôn ngữ mới (ví dụ Java), thì đừng vội đặt mục tiêu “làm chủ Java trong 7 ngày” rồi bỏ hết tất cả các việc khác để dồn 100% công lực vào học Java trong vòng 7 ngày. Điều đó nghe rất hấp dẫn nhưng không khả thi, bạn sẽ không thu hoạch được nhiều sau 7 ngày. Và đặc biệt, nếu sau 7 ngày đó bạn coi như đã “xong việc” thì đảm bảo là bộ nhớ của bạn sẽ chẳng còn bao nhiêu sau một thời gian ngắn.
Thay vào đó, hãy rải việc học ra mỗi tuần một ít, có chủ đích lặp đi lặp lại để “luyện cơ” và khắc sâu kiến thức vào bộ nhớ trong đầu bạn.
Ví dụ: Tuần 1 bạn học căn bản về ngôn ngữ Java, các khối điều khiển, cách tổ chức chương trình
Tuần 2 bạn có thể tập cách tổ chức một trang web đơn giản, vận dụng các kiến thức về cấu trúc chương trình, hàm/cấu trúc điều khiển trước đó.
Tuần 3 bạn nâng cấp trang web đó dưới dạng kiến trúc MVC, có liên hệ hay dở với cách thức tổ chức chương trình kiểu cũ.
Cứ thế cứ thế, kiến thức sẽ được xây dựng vững chắc từng khối từng khối một.
Ở đây có ba từ khoá: phân bổ, cuốn chiếu và chú tâm. Luyện tập phân bổ nghĩa là tách các kĩ năng ra để làm chủ từ từ, đừng dồn lại một lúc. Cuốn chiếu chính là cách học [không hiệu quả] được các sách dạng tutorial quảng cáo (thật đáng tiếc là một số trường học vẫn đang dạy lập trình cuốn chiếu kiểu này). Còn có chủ đích là cái mà cao thủ Peter Norvig đã đề cập (đọc thêm bài “Luyện code như luyện cơ”): “ Điều quan trọng là bàn về phương pháp thực hành: không chỉ là việc lặp đi lặp lại đơn thuần, mà còn thử thách chính mình bằng những nhiệm vụ như vượt qua khả năng hiện tại của bản thân, cố gắng, phân tích hiệu xuất của mình trong và sau quá trình rèn luyện, và sửa chữa bất kỳ sai lầm nào. Cứ như vậy, lặp đi lặp lại.””.
2. Hãy thư giãn, và ngủ đủ
Coder rất hay dán mắt vào màn hình trong nhiều giờ, kể cả khi làm việc cũng như khi chơi game. Điều này gia tăng sức ép lên não bộ, khiến nó mệt mỏi và khó hoạt động hiệu quả.
Theo nghiên cứu của nhà khoa học thần kinh John Medina ghi trong sách “Luật trí não”, não bộ chúng ta hoạt động theo một chu kì 10 phút tập trung rồi sau đó là sao nhãng.
Mẹo hay: Hãy dùng đồng hồ bấm giờ và sử dụng phương pháp Pomodoro để áp dụng hài hòa cơ chế tập trung-thư giãn khi làm việc.
Theo hai chuyên gia khác về học tập và thần kinh học Gs. Barbara Oakley và Gs. Terence Sejnowski, thì chúng ta nên kết hợp tập trung và thư giãn để giúp não bộ làm việc hiệu quả. Khi bạn thư giãn, không có nghĩa là não ngừng hoạt động, mà nó hoạt động ở cơ chế “khuếch tán” (diffused). Nhiều ý tưởng hay, nhiều sáng tạo quan trọng được phát sinh trong lúc thư giãn ấy chứ không phải tập trung hết cỡ để học tập hay giải quyết vấn đề.
Lời khuyên cực kì quan trọng khác là chúng ta nên ngủ đủ. Lời khuyên này tầm thường như cân đường hộp sữa nên dễ bị bỏ qua. Các coder thường kháo nhau về trình độ của một tay nào đó “làm việc 3 ngày liền không cần ngủ”, nghe rất “ngầu”. Thực ra, nếu bạn muốn năng suất giảm sút gấp đôi, và rước bệnh vào thân thì cứ việc “OT” liên tục, “over night” liên tục. Chúc bạn may mắn.
3. Hãy đọc thật nhiều code
Bill Gates từng tâm sự, thời học code, cậu bé tò mò tọc mạch Bill Gates đã lục tung code của các chương trình máy tính sẵn có. Nhờ đó mà học cách viết code. Nhiều người cũng học code bằng cách đọc code của người khác, bao gồm cả người viết bài này.
Bạn được lợi gì từ việc đọc code? Thứ nhất là có thể biết được cách các cao thủ tổ chức mã lệnh thế nào, từ đó mà bắt chước được phần nào đấy. Thứ nhì là mở rộng khả năng “hiểu” code. Bản thân code là một văn bản. Mặc dù code viết ra để cho máy nó chạy, nhưng một “người viết code tốt là người viết ra để con người hiểu được”, “còn viết code chỉ để máy hiểu được thì là code bình thường”. Đọc hiểu được code cũng giúp bạn phần nào trong việc viết ra những đoạn code mà người khác đọc được. Tất nhiên, nếu là người mới học, hãy bắt đầu từ đọc những chương trình nhỏ, đừng vội xông ngay vào mã nguồn của Linux nếu bạn không muốn ngất trên bàn phím.
4. Hãy kiến tạo
Ý tôi là, hãy viết gì đó dùng được. Vui thôi cũng được. Học không gì hay bằng tự làm ra sản phẩm. Học mà làm, làm thì học.
Khi học Android chẳng hạn, một trong những cách học hay nhất là làm một cái app nào đó giải quyết vấn đề nào đó của chính mình và người xung quanh. Càng cụ thể và “nhỏ bé” càng tốt. Vì bạn sẽ có những “chiến thắng nhỏ” của riêng mình. Điều đó chính là liều doping cực mạnh để thúc đẩy bạn viết những chương trình lớn hơn, vươn lên những mục tiêu mới.
Hơn chục năm trước, tôi cũng từng làm một cái app Java (J2ME) có tên rất buồn cười là “Mama tổng quản”, cài lên máy Sony Ericson của người thân để theo dõi chi tiêu khi đi chợ. Nghe ngớ ngẩn phải không? Nhưng tôi của dạo ấy thì vui lắm, vì có thể dùng những dòng code của mình vào những việc hữu ích hằng ngày.
5. Hãy tự đánh giá
Tự đánh giá là một trong những cách học tốt nhất theo nghiên cứu đã dẫn ở bên trên. Nó vừa giúp ta khắc sâu kiến thức, vừa giúp ta tránh những hiểu nhầm. Đó vừa là cơ hội củng cố kiến thức, nhớ dai hơn, nhưng cũng là cơ hội để sửa sai, tránh tình trạng “ảo tưởng sức mạnh”.
Có nhiều hình thức tự đánh giá. Bạn có thể dùng các bài tập, câu hỏi ôn tập, danh mục kiểm tra ở cuối chương và tự làm lấy rồi so kết quả, hoặc tự kiểm tra sản phẩm làm ra. Nếu tham gia một lớp học, hãy yêu cầu giảng viên cung cấp các câu hỏi nhanh (quiz), rubrics, checklist. Đó sẽ là những công cụ tuyệt vời để bạn tự kiểm tra kiến thức của mình.
Đôi khi tự mình viết ra những tóm tắt và suy tư (reflection) về bài học, hoặc tự thuyết trình kiến thức học được cho người khác cũng là một cách tự kiểm tra, xem mình đã thực sự lĩnh hội được mấy phần kiến thức.
Tự học luôn là một hành trình đầy thú vị. Hy vọng năm chiến thuật trên đây giúp bạn đi nhanh hơn và thu hoạch tốt hơn trên hành trình ấy.
Trong bài viết Abstract class và Interface trong Java, mình có giới thiệu về Marker Interface. Tuy nhiên, có một số bạn vẫn chưa hiểu rõ hoặc chưa biết trường hợp nào cần sử dụng nó. Trong bài này, chúng ta sẽ cùng tìm hiểu chi tiết hơn về Marker Interface trong Java và một số trường hợp sử dụng Marker Interface.
Marker Interface là một interface không có bất kỳ phương thức và thuộc tích nào bên trong nó. Nó cung cấp thông tin run-time type về object, vì vậy compiler và JVM có thêm thông tin về đối tượng thể thực hiện một số hoạt động hữu ích.
Một marker interface còn được gọi là một tagging interface.
Ví dụ:
public interface Serializable {
}
Built-in marker interface trong Java
Một số marker interface hiện có trong (built-in) Java: java.io.Serializable, java.lang.Cloneable, java.rmi.Remote, java.util.RandomAccess, java.util.EventListener, …
java.io.Serializable được sử dụng để đánh dấu đối tượng Serialize. Khi chúng ta gọi phương thức ObjectOutputStream.writeObject(), JVM sẽ kiểm tra đối tượng có implement một marker interface Serializable hay không. Nếu không, sẽ throw một exception NotSerializableException. Vì vậy đối tượng sẽ không được Serialize sang output stream object. Chi tiết các bạn xem bài viết “Serialization và Deserialization trong java“.
Tương tự, java.lang.Cloneable là một marker interface để nói với JVM rằng, đối tượng có thể call Object.clone() method. Nếu chúng ta thực hiện clone một object mà không được implement một marker interface Clonable, thì sẽ gặp một exception CloneNotSupportedException. Chi tiết về Clone và Clonable, các bạn xem lại bài viết “Object Cloning trong Java“.
Chúng ta có thể sử dụng Marker Interface ở đâu?
Có hai mục đích thiết kế chủ yếu của marker interface là:
Tạo một cha chung: Như với EventListener interface, mà được kế thừa bởi hàng tá các interface khác trong Java API, bạn có thể sử dụng một tagging interface để tạo một cha chung cho một nhóm interface. Ví dụ, khi một interface kế thừa EventListener, thì JVM biết rằng interface cụ thể này đang được sử dụng trong một event.
Thêm một kiểu dữ liệu tới một class: Đó là khái niệm tagging. Một class mà triển khai một tagging interface không cần định nghĩa bất kỳ phương thức nào, nhưng class trở thành một kiểu interface thông qua tính đa hình (polymorphism).
Thực hiện một số pre-processing trên các class, đặc biệt hữu dụng để phát triển các API và Framework giống như Sping, Struts.
Giúp cho code coverage và build tools để find bug dựa trên một behavior cụ thể của marker interface.
Custom Marker Interface
Trong ví dụ bên dưới, chúng ta tạo một Marker Interface gọi là SafeDeletable. Interface này chỉ ra rằng một đối tượng không được xoá khỏi database, chỉ được set flag là delete.
Marker interface:
interfaceSafeDeletable { }
Chúng ta có 2 đối tượng:
Order: đối tượng này có thể xoá khỏi database.
Customer: đối tượng này không thể xoá khỏi database, cần set flad delete khi được yêu cầu xoá.
class Order {}
class Customer implements SafeDeletable {}
Chương trình chúng ta như sau:
public class InterfaceMarkerExample {
public static void delete(Object obj) {
if (obj instanceof SafeDeletable) {
System.out.println("Set flag to delete: " + obj.getClass());
} else {
System.out.println("Call delete object from database: " + obj.getClass());
}
}
public static void main(String[] args) {
delete(new Order());
delete(new Customer());
}
}
Output:
Call delete object from database: class com.gpcoder.Order
Set flag to delete: class com.gpcoder.Customer
Marker Interface vs. Annotation
Tương tự như Marker Interface, chúng ta có thể sử dụng Annotation cho cùng mục đích. Chúng ta có thể chỉ giới hạn sử dụng Annotation ở mức class giống như interface bằng cách khai báo java.lang.annotation.ElementType là TYPE.
Hãy xem cách sử dụng Annotation để thay thế cho Marker Interface ở trên:
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface SafeDeletable {
}
class Order { }
@SafeDeletable
class Customer{ }
public class AnnotationMarkerExample {
public static void delete(Object obj) {
if (obj.getClass().isAnnotationPresent(SafeDeletable.class)) {
System.out.println("Set flag to delete: " + obj.getClass());
} else {
System.out.println("Call delete object from database: " + obj.getClass());
}
}
public static void main(String[] args) {
delete(new Order());
delete(new Customer());
}
}
Một câu hỏi đặt ra là có phải Annotation có thể thay thế 100% Marker interface?
Chúng ta có thể sử dụng Annotation để thay thế cho Marker interface, tuy nhiên trong một số trường hợp sẽ khó khăn nếu sử dụng Annotation. Chẳng hạn trong ví dụ trên, nếu chúng ta có một class con của Customer :
classVipCustomer extendsCustomer {}
Nếu sử dụng Marker inetrface, mặc định class VipCustomer cũng được đánh dấu là SafeDeletable vì tính kế thừa của Java. Tuy nhiên, với Annotation, chúng ta cần đánh dấu lại Annotation SafeDeletable cho class VipCustomer. Kế thừa cũng là một bất lợi của Marker Interface so với Annotation là chúng ta không thể bỏ Marker Interface ở subclass, với Annotation thì không cần làm gì thêm.
Vì interface cho chúng ta tính đa hình (polymorphism), nên chúng ta có thể sử dụng để type check tại thời điểm compile time. Chẳng hạn, chúng ta có class DocumentTransferExecutor, class này chỉ chấp nhận transfer cho những document có implement marker interface DocumentTransferable. Thay vì nhận vào một Object type, chúng ta có thể chỉ định là một Marker interface để tránh developer truyền sai parameter type (đối tượng không phải là document) hay cast object trong quá trình xử lý.
interface DocumentTransferable { }
class DocumentTransferExecutor {
public void transfer(DocumentTransferable obj) { }
}
Tóm lại, marker interface trong Java được sử dụng để chỉ ra một cái gì đó cho complier, JVM hoặc bất kỳ công cụ nào khác. Hiện nay, hầu hết các developer ủng hộ các Annotation để giải quyết một số vấn đề tương tự thay vì dùng marker interface. Mặc dù các marker interface vẫn đang được sử dụng, nhưng chúng nên được sử dụng cẩn thận vì tính kế thừa của nó.
Bài viết được sự cho phép của tác giả Trần Khôi Nguyên Hoàng
Nhắc đến nhận diện gương mặt thì nhắc đến một cái gì đó đao to búa lớn như là Machine Learning cùng với một số thuận ngữ mang tầm vĩ mô như Deep Learning, Training Model, Neural Network, vân vân và mây mây. Đứng dưới góc độ của một thằng Developer quèn thì mình không đủ sức dùng Machine Learning hay gì cả. Cho nên mình xin chia sẻ các bạn một cách đơn giản hơn để thực hiện việc nhận dạng gương mặt chỉ bằng Javscript với face-api-js.
Nhận điện Face Landmark (Không biết dịch ra tiếng việt là gì luôn).
Dự đoán tuổi và giới tính.
Các bước thực hiện
Trước khi bắt đầu thì có một điều quan trọng nó là như thế này. Nhận diện gương mặt bao gồm 2 bước.
Phát hiện gương mặt.
Nhận diện gương mặt.
Chuẩn bị
Đầu tiên tạo một folder cơ bản nhé.
mkdir face
touch index.html
touch script.js
mkdir data // Dùng để bỏ dữ liệu ảnh đầu vào
mkdir images // Ảnh dùng để testmkdir models // Chứa các pre-train model
face-api-js.min.js // Tải từ github ở trên về.
Dùng hàm detectSingleFace để phát hiện ra gương mặt ở trong ảnh
Dùng hàm FaceMatcher và findBestMatch để nhận diện gương mặt.
Load Model vào trong dự án
Đầu tiên là load model vào. Ở đây sử dụng 3 model chính.
ssdMobilenetV1 Model: Đây là pre-trained model dùng để phát hiện gương mặt.
faceLandmark68Net Model: Đây là pre-trained model dùng để hiển thị được các điểm xung quanh mặt của mình.
FaceRecognitionNet Model: Đây là pre-trained model dùng để nhận dạng gương mặt.
Các bạn có thể đọc thêm chi tiết của các model này ở trong link Github ở trên nhé. Tại sao phải load model faceLandmark68Net? Câu trả lời là nhờ vào faceLandmark68Net thì mình phải có thể “nhận dạng” được gương mặt. Nên cho dù không dùng cũng phải load vào.
Ví dụ về Landmark68Net
Vì thế trong file script.jsthì mình sẽ load 3 model này vào trước.
Nếu như mình đưa một tấm ảnh không phải là Nancy, ở đây ví dụ mình đưa Trump vào, thì nó sẽ hiện kết quả là Unknown.
Kết quả sau khi nhận diện Đỗ Nam Trung
Đến đây thì mình đã hoàn thành hệ thống nhận điện đơn giản chỉ bằng Javascript.
Mở rộng
Các bước ở trên thì nó chỉ nhận dạng được một gương mặt của Nancy thôi. Minh muốn nó nhận diện được thêm nhiều người nữa thì phải làm sao? Ví dụ như nhận diện Nancy và Yeonwoo thì làm thế nào? Rất đơn giản, mình chỉ cần tạo folder Yeonwoo và thêm data vào đó. Mình sẽ sửa hàm detectNancyFace() thành detectAllLabeledFaces()
asyncfunctiondetectAllLabeledFaces(){const labels =["Nancy","Yeonwoo"];returnPromise.all(
labels.map(asynclabel=>{const descriptions =[];for(let i =1; i <=2; i++){const img =await faceapi.fetchImage(`http://localhost:5500/data/${label}/${i}.jpg`);const detection =await faceapi
.detectSingleFace(img).withFaceLandmarks().withFaceDescriptor();
descriptions.push(detection.descriptor);}returnnewfaceapi.LabeledFaceDescriptors(label, descriptions);}));}
Kết quả sau khi mình sửa ảnh thành Yeonwoo như sau
Kết quả sau khi nhận diện Yeonwoo
Phát triển
Dựa vào bài này, các bạn có thể phát triển thành một dự án vui vẻ hơn. Ví dụ như clone lại cái Nhận Diện Jav Idol của anh Hoàng Code Dạo chẳng hạn. Hoặc hệ thống điểm danh nhận diện gương mặt chẳng hạn. Ngoài ra, face-api-js còn có các hàm dùng để xác định tuổi, cảm xúc nữa. Nên các bạn đem ra vọc vạch thử cũng vui. Ví dụ như đưa một tấm hình vào và đoán xem ngườ ta bao nhiêu tuổi, như cái https://www.how-old.net/ của Micro$oft chẳng hạn.
Kết luận
Trên đây là bài viết giới thiệu về face-api-js API và cách sử dụng đơn giản của nó. Chú ý là hệ thống nhận diện này được sử dụng bằng các pre-trained model mà không qua bất kì một bước phức tạp nào để tranfer dữ liệu từ pre-trained model nên độ chính xác ở mức tương đối. Không thể nào được như Deep Learning được nhé. Đôi khi mình để ảnh Yeonwoo vào mà nó nhận diện ra Nancy (Chứng tỏ là gái Hàn con nào cũng giống giống nhau).
Các bạn có thể xem source code tại link Github của mình nhé.
Làm gì cũng vậy, để có tay nghề tốt, bên cạnh việc thực hành, làm việc liên tục chúng ta cũng cần phải học hỏi để tiếp thu các kiến thức mới, không ngừng nâng cao tầm kiến thức hơn nữa. Nâng cao chất lượng rồi thì cũng cần nâng cả số lượng nữa. Điều này có nghĩa là làm tốt rồi cần làm nhanh nữa :)) Lý thuyết vẫn được mọi người nói là thế.
Tất nhiên là như thế rồi, cái đó ai chẳng biết, nhưng bên cạnh đó mình cũng rất để ý đến những kiến thức cơ bản. Bạn khẳng định bạn làm cái này rất tốt, cái kia rất tốt, có nhiều kinh nghiệm abc này nọ, nhưng mà đến khi phỏng vấn họ hỏi bạn mấy kiến thức cơ bản, bạn lại cứ ú ớ không giải thích được, giải thích được nhưng mà lại lộn chỗ này xộn chỗ kia thì họ đếch tin vào mấy dòng quảng cáo trong CV của bạn nữa đâu Hehe.
Vì vậy để đỡ quê khi đi phỏng vấn, chẳng may bị “chơi” chỗ này, mình ôn lại một lần nữa chỗ này (ai thi ISTQB rồi, hoặc đọc qua đâu đấy rồi thì sẽ là ôn lại, ai chưa đọc hay chưa biết là thì đọc cho biết nhé :D). Mấy kiến thức này đọc xong lâu lâu lại quên là chuyện bình thường thôi nhé, chịu khó đọc nhiều lần thì tự dưng sẽ nhớ thôi Như mình kiến bài đọc để viết này, bây giờ thì mình tự tin rồi! Haha.
Hôm nay sẽ nói về Smoke testing và Sanity testing. Ahihi đừng cố gắng dịch ra tiếng việt hai cái từ này nhé, ngầm hiểu là được rồi. còn nó như thế nào mời các bạn đọc tiếp bài viết ha.
Smoke testing là một loại kiểm thử phần mềm được thực hiện sau khi có một bản build mới, để đảm bảo rằng các chức năng chính, quan trọng của phần mềm vẫn hoạt động bình thường. Công việc này được thực hiện để phát hiện các vấn đề nghiêm trọng sớm nhất có thể, trong trường hợp phát hiện vấn đề, bản build đó sẽ bị từ chối, và không được bàn giao cho giai đoạn kiểm thử tiếp theo, do đó sẽ giúp tránh lãng phí thời gian cho cả người kiểm thử và phát triển. Trong smoke testing, các test case được chọn sẽ bao phủ được hầu hết các tính năng, thành phần chính quan trọng của sản phẩm phần mềm.
Ví dụ, trong một ứng dụng web, có các chức năng như đăng nhập, trang chủ, tạo mới hồ sơ, gửi hồ sơ, quản lý hồ sơ,… Để có thể thực hiện được các thao tác trên hệ thống bạn cần phải đăng nhập vào ứng dụng thành công, tuy nhiên sau bản build thì một vài vấn đề xảy ra làm cho người dùng không thể login vào hệ thống được. Hay là đăng nhập được nhưng chức năng tạo mới hay gửi hồ sơ đi không thực hiện được. Đây là những tính năng quan trọng của hệ thống, vì vậy việc thực hiện smoke test trước khi bàn giao sẽ phát hiện sớm và fix sớm những vấn đề cơ bản này, thay vì phải bàn giao, thực hiện cài cắm cấu hình các thứ xong rồi bắt đầu kiểm thử thì mới phát hiện ra, gây lãng phí khá nhiều thời gian. Mà chúng ta đều biết rằng, thời gian còn quý hơn cả vàng đó :v
2. Sanity testing là gì?
Sanity testing cũng là một loại kiểm thử phần mềm, Sanity testing được thực hiện sau khi nhận được bản build, ở bản build này một số chức năng của phần mềm được chỉnh sửa, cập nhật do yêu cầu hoặc một số lỗi nào đó đã được sửa, việc này để kiểm tra nhanh các trạng thái hoặc thay đổi đó có ảnh hưởng đến các tính năng khác hay không, có đáp ứng như mong đợi hay không? Nếu các vấn đề được tìm thấy, bản build sẽ không được đưa tới giai đoạn kiểm thử chi tiết hơn tiếp theo, giúp giảm thiểu thời gian và các chi phí khác.
Ví dụ: trong ứng dụng ví dụ bên trên, ở bản build trước có phát hiện ra lỗi liên quan đến việc gửi hồ sơ do phân quyền sai nên hồ sơ được gửi đi nhưng lại gửi không đúng người nhận, ở bản build này bug này đã được sửa, sanity test ở đây sẽ kiểm tra nhanh việc chỉnh sửa chức năng này có liên quan đến các chức năng, vai trò khác hay không? Nhưng vẫn cần phải lưu ý rằng mình sẽ chỉ kiểm tra những phần có liên quan nhất, không sa đà chi tiết quá vào việc kiểm thử chức năng, giao diện gửi hồ sơ hay những chức năng đã ổn định khác, vì thời gian dành cho sanity test là không nhiều.
3. Một vài so sánh cơ bản giữa Smoke và Sanity testing
Smoke testing
Sanity testing
Smoke testing được thực hiện để đảm bảo rằng các chức năng quan trọng của phần mềm vẫn hoạt động bình thường
Sanity testing được thực hiện để xác định các chức năng hoạt động đúng như yêu cầu, thiết kế sau khi có một vài thay đổi nhỏ, hoặc sau khi fix 1 bug nào đó.
Mục đích của Smoke testing đó là kiểm tra sự “ổn định” của hệ thống để có thể tiến hành các bước kiểm thử nghiêm ngặt hơn
Mục đích của sanity testing là kiểm tra sự hoạt động “hợp lý” của hệ thống để có thể tiến hánh các bước kiểm thử nghiêm ngặt hơn
Kiểm thử này thường được thực hiện bởi đội phát triển (Developer) hoặc đội kiểm thử (tester)
Sanity testing thì thường được thực hiện bởi đội kiểm thử
Smoke test thường được lưu thành các tài liệu cố định hoặc các script để có thể chạy tự động (Bởi vì đơn giản, khi các chức năng lớn quan trọng của hệ thống sẽ được định hình ổn định trước tiên, và mỗi lần build thì đều phải đảm bảo hoạt động của các chức năng đó thì mới được coi là build thành công, vì vậy việc tài liệu hóa hoặc viết script là việc cần thiết nên làm)
Đối với Sanity testing, do tính không ổn định trước những yêu cầu và các vấn đề phát sinh khác nên sẽ không có tài liệu cụ thể hay script nào được dựng sẵn cả.
Smoke testing được thực hiện trước giai đoạn kiểm thử hồi quy
Sanity testing được thực hiện trước giai đoạn kiểm thử hồi quy và sau giai đoạn Smoke testing.
Smoke testing sẽ kiểm tra tổng thể toàn bộ hệ thống
Sanity testing kiểm tra từng phần hệ thống.
Kiến thức cơ bản tạm thời là thế, nắm chắc mấy cái này mình nghĩ là OK rồi đấy, thoải mái chém gió tơi bời với các anh/chị phỏng vấn về sanity và smoke rồi nhé!
Đùa thôi, nếu bạn nào có thấy vấn đề gì, hay có thắc mắc, góp ý thì cứ thoải mái để lại dưới phần bình luận cho mình nha.
Tham khảo: https://www.guru99.com/smoke-sanity-testing.html
Bài viết được sự cho phép của tác giả Nguyễn Hữu Đồng
Trước khi nói tới redis, phải nói từ việc caching là và tầm quan trọng của caching.
Bình thường, cứ mỗi yêu cầu từ phía client, hầu hết trong chúng ta ai cũng chạy vàodatabase query thứ gì đó, sau đó làm vài việc rồi lại trả về kết quả cho client. Chuyện này vẫn bình thường cho tới khi số lượng request tăng lên đáng kể khiến CPU và Hard Disk gồng mình ra làm đi làm lại mãi cùng một việc, lấy data rồi lại trả về, thậm chí có những thứ đã lấy lần trước rồi tính toán xong xuôi rồi, biết kết quả rồi vẫn phải đi làm lại, thậm chí làm lại hàng ngìn lần.
Và để tránh giải quyết trường hợp đó, caching xuất hiện như là một phương tiện giúp server ghi nhớ kết quả của quá trình tính toán, để trả về nhanh hơn cho những lần request tương tự của client trong tương lai.
Redis là một công cụ hỗ trợ server giải quyết bài toán caching, không những vậy Redis có thể được sử dụng như một database được lưu trữ trong ram để tăng tốc độ xử lí, nhưng đó cũng là một nhược điểm của Redis, khi mà cúp điện đồng nghĩa với mất dữ liệu, mặc dù redis có hỗ trợ backup và restore data từ ổ cứng theo chu kì và điều đó là không hoàn hảo. Cẩn thận thì là tốt nhất : D
Redis hỗ trợ lưu data dưới dạng Key Value, value đó có thể là một chuỗi, số, danh sách, danh sách được sắp xếp hay thậm chí là một tài liệu dạng từ điển (hash).
Vậy chúng ta sẽ sử dụng Redis để caching data như thế nào ?
Bạn có thể dùng redis để caching mọi thứ bạn muốn, từ kết quả của một câu query trong database, một profile của user, profile cửa hàng. Và khi cache phải chắc chẵn những gì được cache là mới nhất vì nếu data cũ thì sẽ rất ảnh hưởng đến client.
Redis hỗ trợ Transaction, hỗ trợ Pub/Sub vì vậy nó cũng được sử dụng làm hệ thống Message Broker, kinh điển là RabbitMQ sử dụng Redis là core của hệ thống.
Thử cache thứ gì đó với Redis.
Ví dụ như mình, mình có một web app cho user sử dụng để upload ảnh, tạo ảnh thumbnail những mình chỉ cho phép user sử dụng sau khi Login bằng account hợp lệ của Google.
Và khi user Login thành công, mình sẽ xem trong database có thông tin User hay không nếu không thì sẽ tạo mới, tiếp theo mình sẽ cache luôn profile của user dựa vào email, và sau này khi user login mình sẽ lấy thẳng trong Redis luôn, nhanh hơn so với việc chui vào Database để lấy.
Các bạn thấy đấy mình đã dùng kiểu “key-value” để cache nguyên object profile của user dưới dạng string. Và sau này khi client gọi lên để lấy profile user thì mình chỉ chần chui vào ram lấy, nếu lấy không được chỉ có trường hợp user đó chưa login thôi 😀
Ngoài ra do cũng hộ trợ Transaction nên dữ liệu của Redis luôn được đảm bảo là được sửa đổi chính xác, các bạn có thể đọc trong bài viết này của mình, mình đã sử dụng Redis làm nơi lưu trữ số lượng request từ client sau đó thì chặn nếu request được thực thi một cách không hợp lệ.
Hay là một ví dụ, mình cần lên thực đơn đồ ăn món uống do công ty bình chọn cho ngày hôm nay, bởi vì thông tin chỉ được thay đổi cỡ 1 lần 1 ngày, nên mình sẽ chuẩn bị trước tất cả, query lấy hết thông tin món ăn, cửa hàng bán loại món này lưu sẵn vào Redis và qua ngày mới, nếu có hàng ngìn người cùng lấy thông tin thì cũng sẽ rất nhanh vì đã có sẵn rồi.
Nói qua vậy là đủ bây giờ mình sẽ hướng dẫn các bạn Setup một Redis server trên Ubuntu theo kiểu mì ăn liền để test xem nó có gì hay.
Trước tiên chạy lên này. Nó sẽ cài đặt redis-server và redis-cli cho bạn, redis-cli là công cụ giúp bạn giao tiếp với redis-server và thao tác với redis database.
sudo apt-get install redis-server
Để tiến hành chạy Redis Server từ terminal bạn gõ “redis-server” nếu kết quả được như trên thì đã có server để Test.
Đã có server chạy, mặc định redis server sẽ lắng nghe trên cổng 6379 bạn có thể chỉnh sửa bằng cách cấu hình các thông số trong file config. Mặc định thì sẽ nằm tại “ /etc/redis/redis.conf”. Nếu không có thì các bạn có thể tạo mới và tìm hiểu các thông số tại đây.
Tiếp theo mình sẽ dùng “redis-cli” để kết nối với “redis-server” chỉ cần chạy “redis-cli” thì mặc định nó sẽ kết nối đến “locahost:6379”. Mình sẽ dùng lệnh “ping” xem có nhận được gì không, nếu kết nối thành công thì server sẽ “pong”. Như hình dưới.
Mình chạy một vài command. Khá đơn giản, để xem full command và các kiểu dữ liệu trong redis các bạn có thể tham khảo qua bảng cheet-sheet này.
Nhưng trong hình mình tiến hành ghi vào database một biến có tên là user_393901228 với kiểu dữ liệu là hash, và sau đó setup lại giá trị rồi lại lấy ra.
Sau này nếu có điều kiên, đối mặt với lượng request lớn mình sẽ áp dụng redis thường xuyên để cache, hoặc là làm database cho thứ gì đó, và nếu có điều gì hay mình sẽ viết tiếp.
Mình xin dùng bút tại đây, à quên dừng gõ phím :V cảm ơn các bạn đã xem qua bài.
Trong một project rất là lớn (hay không lớn lắm) làm sao để cả team dev, team test và các cấp quản lý có thể nắm được thông tin về bug hay defect đang có của project? Làm sao để tìm kiếm nhanh được bug này được giao cho ai, do ai log, trạng thái đang là gì, thuộc về chức năng nào… hay trong tháng trước sản phẩm đã phát hiện bao nhiêu bug, đã fix được bao nhiêu bug và còn lại bao nhiêu, số lượng bug ở mức độ nghiêm trọng là bao nhiêu, làm sao để dev biết được những lỗi này cần phải được ưu tiên fix trước trong danh sách cả mấy chục bug kia… và rất rất nhiều những vấn đề khác nữa.
Để trả lời được những câu hỏi kia, dùng MS Excel là được hết á =)). Nhưng mà dùng excel thì sẽ khó để tất cả mọi người có thể làm việc song song cùng lúc, truy vết thông tin được, khó tránh khỏi gian lận có thể xảy ra :v, chỉ có cấp quản lý bên trên họ cần tổng hợp thông tin chung thì sẽ rất là tiện, nhưng với những dân tổ chuyên log bug và fix bug thì Excel không hẳn là lựa chọn ngon nhất :v.
Vì thế sự ra đời của các hệ thống quản lý bug đã giúp giải quyết được không chỉ các yêu cầu cơ bản trên, mà còn rất yêu cầu nâng cao hơn, bên cạnh đó còn cung cấp rất nhiều các tiện ích khác liên quan, hỗ trợ rất nhiều các công việc quản lý trong lĩnh vực phần mềm này :)) (không biết chém có quá lời không, nhưng nếu bạn nào đang dùng rồi thì chắc là cảm nhận được thôi mà) Các em mới “vào đời” chưa có cơ sở nhưng mình khẳng định tin được đến 8 -9 phần nên không có gì phải lo lắng nhé! Kaka -.- không tin thì tự chứng minh nè.
Vui thôi, dưới dây là một số hệ thống quản lý bug khá phổ biến và nổi tiếng, mọi người chắc hẳn cũng đã từng làm việc trực tiếp rồi, có thể để lại bình luận và cảm nhận dành cho các công cụ này ở phía dưới nhé!
Bugzilla
Bugzilla là một trong những công cụ quản lý bug hàng đầu được khá nhiều tổ chức, công ty sử dụng trong thời gian dài gần đây. Bugzilla được đánh giá là rất dễ dàng khi sử dụng với giao diện web thân thiện. Đặc biệt đây là một công cụ nguồn mở và miễn phí.
Một số tính năng nổi bật của Bugzilla:
Cho phép tùy biến Tìm kiếm nâng cao
Báo cáo chi tiết được thể hiện qua các dạng biểu đồ khác nhau như biểu đồ bảng, đường và biểu đồ thanh và biểu đồ hình tròn, có hỗ trợ xuất dữ liệu định dạng CSV để bạn có thể tự điều chỉnh dữ liệu của mình
Hỗ trợ quản lý, theo dõi theo thời gian
Thông tin người review
Bạn có thể theo dõi tình trạng, thông tin hoặc khi có tác động thay đổi từ người khác lên bug mà bạn có liên quan hoặc nhận theo dõi nhờ các thông báo được gửi tới email đăng ký của bạn.
Có thể tùy chọn các trường và luồng nghệp vụ tương ứng
Chức năng “Sanity Check” sẽ thực hiện chức năng quét trên toàn bộ dữ liệu của bạn để phát hiện các vấn đề như không thống nhất, các báo cáo lỗi và các đề xuất để sửa các lỗi đó.
Có rất nhiều các tiện ích mở rộng cho nhiều trình duyệt khác nhau, email, các ông cụ quản lý dự án từ đó bạn có thể liên kết các hệ thống đang sử dụng với nhau.
Để tìm hiểu hơn về Bugzilla các bạn truy cập đây nhé, hoặc các hướng dẫn chi tiết cụ thể – có hình ảnh đi kèm luôn về cách sử dụng hiệu quả các chức năng của Bugzilla thì các bạn có thể tham khảo những hướng dẫn ở đây nhé!
JIRA
Atlassian JIRA, là một công cụ chủ yếu được sử dụng để quản lý sự cố tuy nhiên bên cạnh đó nó cũng được sử dụng để theo dõi lỗi. JIRA cung cấp một bộ dữ liệu hoàn chỉnh như record, báo cáo, workflow và các tính năng tiện lợi có liên quan khác.
JIRA là một công cụ có thể tích hợp trực tiếp với code trên môi trường phát triển do đó đây là một công cụ hoàn toàn phù hợp với các developer. Ngoài ra, khả năng có thể theo dõi bất kỳ công việc và tất cả các loại issue, vì thế JIRA có thể sử dụng được với các ngành công nghiệp khác có nhu cầu quản lý các công việc hay issue, JIRA khá là hiệu quả như các công việc liên quan đến hỗ trợ (helpdesk), hệ thống quản lý nhập-xuất, vào ra, vv.
Tuy nhiên, đây là sản phẩm thương mại vì thế mà nó cũng nhiều trình bổ sung hỗ trợ khả năng mở rộng hơn, chắc chắc là đáng đồng tiền bát gạo rồi. Mình thấy khá là nhiều công ty lớn ở Việt Nam đã và đang sử dụng hệ thống này. Trên trang chủ có cung cấp bản dùng thử miễn phí, các bạn nếu chưa biết cộng với tò mò có thể tải về trải nghiệm! :v
Chi tiết về JIRA các bạn có thể tham khảo trên trang chủ của JIRA và các diễn đàn khác qua tìm kiếm google nha.
Mantis
Đây là một công cụ khá là quen thuộc, và đối với Mantis chắc là cũng chỉ cần nói một vài từ ngắn gọn thôi đó là đơn giản và dễ sử dụng. Mantis cung cấp đầy đủ các tính năng mà bạn cần. Bên cạnh đó, để đáp ứng nhu cầu của người dùng và xu thế hiện nay, Mantis không chỉ xuất hiện dưới dạng ứng dụng web mà còn có cả phiên bản riêng dành cho di động. Mantis được xây dựng bằng ngôn ngữ PHP và sử dụng miễn phí. Tuy nhiên, nếu bạn muốn một host riêng thì sẽ phải trả tiền, giá cả khá cũng là hợp lý.
Một số tính năng nổi bật của Mantis như:
Thông báo qua email: Khi có bất kỳ sự thay đổi, comment nào thì các thông tin đó sẽ được gửi tới những người liên quan thông qua email đăng ký của người đó.
Điều khiển truy cập: Cho phép bạn phân cấp, quyền người dùng truy cập theo mức project.
Tùy biến: Bạn có thể dễ dàng tùy biến điều chỉnh một số thông tin cho phù hợp với yêu cầu sử dụng của bạn.
Hỗ trợ nền tảng di động: Mantis hỗ trợ các nền tảng di dộng như iPhone, Android hay cả Windows Phone
Các bạn quan tâm có thể truy cập vào đây để xem thêm thông tin nhé!
Redmine
Redmine là một hệ thống quản lý issue nguồn mở, hệ thống này có thể tích hợp với các hệ thống quản lý source code. Tuy không phải là một công cụ chuyên biệt để “quản lý bug”, nhưng lại có liên quan đến việc xử lý các issue, các issue này có thể là các chức năng hệ thống, công việc, bug / defect, vv ..
Trong danh sách này thì Redmine là một giải pháp khác không chỉ là một công cụ theo dõi, quản lý bug. Cho đến nay giải pháp quản lý dự án nguồn mở này đã tồn tại hơn một thập kỷ và hỗ trợ 34 ngôn ngữ khác nhau. Do đó bạn có thể sử dụng công cụ này cho việc phát triển dự án của mình, hoàn toàn miễn phí. Tuy nhiên nếu bạn chỉ đang tìm kiếm một công cụ chỉ để theo dõi lỗi thì Redmine có thể có nhiều tính năng hơn mức bạn cần.
Lean Testing
Với slogan là: “Simple testing tools for complex software projects”
Lean Testing là phần mềm quản lý test case và quản lý bug miễn phí được thiết kế bởi những người kiểm thử. Bạn có thể sử dụng ứng dụng này như là một tiện ích mở rộng trên trình duyệt (Lean testing có extention trên các trình duyệt Safari, FireFox, Chrome) để report bug một cách nhanh chóng và dễ dàng, ngoài ra bạn còn có thể thực hiện report bug trực tiếp từ ứng dụng trên điện thoại di động mình. Lean Testing có thể tích hợp với các công cụ quản lý khác như Slack, Bitbuckit và GitHub.
Lean testing có mọi thứ mà bạn mong đợi từ trình quản lý lỗi đến việc quản lý test case, với điểm nhấn mạnh lớn đó là việc đảm bảo mọi thứ đều trực quan và dễ sử dụng. Lean Testing phát triển và sử dụng dựa trên nền tảng web và không yêu cầu cài đặt.
Trên đây chỉ là một phần nhỏ trong rất nhiều các hệ thống quản lý bug khác, hệ thống nào cũng có những trải nghiệm, ưu điểm và nhược điểm riêng. Các bạn có chia sẻ thêm gì về hệ thống quản lý bug nào không, nếu có để lại bình luận phía dưới cho mình nhé!
Trong phần Agile cơ bản, mình đã giới thiệu cơ bản về Agile với tuyên ngôn Agile (Agile Manifesto) và 12 nguyên tắc trong Agile. Trong phần này, mình muốn diễn giải thêm về “Tuyên ngôn Agile” để bạn hiểu thêm về Agile:
“Cá nhân và sự tương hỗ quan trọng hơn quy trình và công cụ”
“Sản phẩm xài được quan trọng hơn tài liệu về sản phẩm”
“Cộng tác với khách hàng quan trọng hơn đàm phán hợp đồng”
“Phản hồi với sự thay đổi quan trọng hơn bám theo kế hoạch”
1. “Cá nhân và sự tương hỗ quan trọng hơn quy trình và công cụ”
Ý tưởng là đặt trọng tâm vào con người và sự tương hỗ giữa những thành viên trong nhóm. Cơ bản là nếu dự án có những thành viên có năng lực, chịu làm việc cùng nhau thì sẽ mang đến thành công cho dự án. Nếu dự án của bạn có quy trình làm việc tốt, được hỗ trợ những công cụ tốt nhất nhưng những thành viên không “cùng nhìn về một hướng” thì khả năng dự án thất bại là rất lớn. Nói điều này không có nghĩa là phủ nhận tầm quan trọng của quy trình và công cụ nhưng trong Agile nó được đặt sau yếu tố con người. Có một câu bằng tiếng Anh khá phổ biến nói về điều này là “a fool with a tool is just a fool”
2. “Sản phẩm xài được quan trọng hơn tài liệu về sản phẩm”
Trong một số quy trình phát triển phần mềm, việc tạo ra và cập nhật các tài liệu về sản phẩm là bắt buộc. Nhóm Dev không thể hoặc không đồng ý tiến hành công việc nếu không có tài liệu đặc tả về yêu cầu, thiết kế hệ thống. Nhóm Test thì yêu cầu tài liệu về sản phẩm để có thể viết trường hợp kiểm thử và kiểm thử được. Nhóm QA đòi tất cả các tài liệu phải được viết trước khi sản phẩm được giao cho khách hàng nếu không thì không đủ điều kiện, chuẩn để giao sản phẩm cho khách hàng. Thực ra đứng với góc độ khách hàng thì khách hàng chỉ quan tâm đến sản phẩm có hoạt động được và tốt hay không. Trong khi việc tạo và cập nhật tài liệu mất nhiều thời gian và được cho là buồn tẻ. Vậy tại sao mình phải tập trung quá nhiều cho việc không cần thiết mà không dành thời gian đó để trao đổi để hiểu thêm về công việc phải làm. Mọi người đừng hiểu lầm là làm Agile là không viết tài liệu. Ý tưởng là chỉ viết những gì mà mọi người cần đọc.
3. “Cộng tác với khách hàng quan trọng hơn đàm phán hợp đồng”
“Khách hàng là thượng đế” hay “khách hàng luôn luôn đúng”. Tuy nhiên thì khách hàng có đủ loại khách hàng. Có khách hàng am hiểu về công nghệ, có người không. Có người suy nghĩ nhất quán có người thay đổi xoành xoạch, có người lạnh lùng có người cười nói suốt ngày, v.v và cách duy nhất để có thể làm việc tốt là phải cộng tác với khách hàng để hiểu được khách hàng muốn gì và cần gì để có thể tư vấn và điều chỉnh thay vì chỉ dựa vào những điều đã quy định trong hợp đồng.
4. “Phản hồi với sự thay đổi quan trọng hơn bám theo kế hoạch”
Có một điểm chung mà mình thấy trong hầu hết những dự án mình đã trải qua đó là không có dự án nào không có sự thay đổi điều chỉnh khi thực thi. Sự thay đổi đó có thể là thay đổi về yêu cầu, thay đổi công nghệ, thay đổi nhân sự, thay đổi deadline, thay đổi phương thức làm việc, v.v mặc dù kế hoạch đã được định ra rõ ràng từ đầu. Agile không khuyến khích cho sự thay đổi nhưng khuyến khích chúng ta tập thích nghi với thay đổi. Bạn hãy chuẩn bị tinh thần để thay đổi khi tham gia vào dự án Agile nhé.
Có một điều thú vị là đa số trong chúng ta đều cơ bản đồng ý với 4 tuyên ngôn của Agile. Nhiều người hiểu tầm quan trọng của “cá nhân” hay “cá nhân là tài sản quý giá nhất công ty” nhưng sẳn sàng thay đổi nhân lực để tương thích với quy trình/công cụ hiện có. Nhiều người hiểu “khách hàng là thượng đế” và “phải thích nghi với sự thay đổi” nhưng sẵn sàng tuyên bố “Dẹp, không làm nữa” vì khách hàng thay đổi yêu cầu liên tục. Hay như “sản phẩm xài được là quan trọng “ nhưng vẫn cố gắng viết thêm tài liệu với ý nghĩ rằng “biết đâu/lỡ sau này có ai cần thì có cái mà cung cấp”. 4 tuyên ngôn của Agile nói dễ hơn làm nhưng khi bạn theo Agile thì bạn hãy chuẩn bị tinh thần để “làm” chứ không phải để “nói”.
Progressive Web App và tương lai trong lĩnh vực E-commerce
Sutunam là công ty công nghệ của Pháp với hơn 40 nhân viên làm việc tại Việt Nam bên cạnh trụ sở chính tại Lyon, Pháp. Với hơn 10 năm kinh nghiệm trong lĩnh vực Open Source, Sutunam nổi bật với thế mạnh chuyên môn ở mảng Ecommerce. Công ty làm việc với đa dạng các dịch vụ xoay xung quanh website Ecommerce: từ hoạch định chiến lược kinh doanh số, thiết kế trải nghiệm trên website và mobile app, cho đến các dịch vụ về hạ tầng máy chủ. Sutunam hoạt động như một nhà tư vấn dự án số cho khách hàng, trong đó Progressive Web App là cũng là một hướng đi mà công ty chú trọng.
Progressive Web App và tương lai của nó trong lĩnh vực E-commerce sẽ như thế nào?
Progressive Web App (PWA) là gì?
PWA (progressive web apps) là dạng web app được xây dựng dựa trên các công nghệ của website, nhưng mang lại trải nghiệm tương tự như Native App. Nhờ vào tính năng của service worker, manifest và https, PWA có thể hoạt động offline ngay cả khi không có mạng. Khi người dùng vào website PWA thông qua trình duyệt trên mobile, họ có thể cài đặt website PWA trong điện thoại. Sau đó, họ có thể truy cập trở lại website thông qua icon ngay trên điện thoại, tương tự như khi họ click vào một icon của native app để truy cập phần mềm vậy.
Thông thường, quá trình mua hàng của người dùng sẽ đi từ việc tìm kiếm bằng phiên bản mobile website – responsive thông thường của phiên bản đó. Khi truy cập, bạn sẽ nhận được gợi ý tải app để vào web nhanh hơn chẳng hạn. Sau đó, bạn sẽ được điều hướng sang App Store hay Google Play, iOS Store, để download và cài đặt app vào máy. Cuối cùng, bạn sẽ tìm kiếm lại những thứ mình cần trong app đó một lần nữa và tiến hành thanh toán.
Đối với những người lần đầu tiên sử dụng website, hoặc ít mua hàng của doanh nghiệp đó, đây là một quy trình khá rắc rối. Theo thống kê, có gần 50% khách hàng lần đầu tiên đến với website rất dễ dàng bỏ qua giai đoạn gợi ý tải app về mobile. Ngoài ra, người dùng cũng có tâm lý ngại tải app mới để tăng dung lượng của điện thoại. Vậy phải làm gì để tăng trải nghiệm người dùng trên mobile responsive website, để giúp cho việc thanh toán trở nên dễ dàng và tiết kiệm thời gian hơn?
User flow native app
Progressive Web App chính là giải pháp.
Trải nghiệm người dùng với PWA sẽ đơn giản hơn rất nhiều. Khách hàng chỉ việc tìm kiếm trên mobile website và thanh toán đơn hàng, cuối cùng nhấn vào Add to homescreen để tải website về dưới dạng icon. Vậy là lần sau khách hàng chỉ cần nhấn vào icon để trở lại với website. Trải nghiệm này sẽ tương tự như khi người dùng app trong điện thoại. Với người dùng, đây là một giải pháp cực kỳ tiện dụng vì vẫn được sử dụng mobile website rất nhanh chóng mà không cần tải app về.
User flow PWA
Release Cycle
Với PWA, release cycle cũng đơn giản hơn. Với các lập trình viên mobile, mỗi lần có update hay tính năng mới, họ sẽ phải cập nhật phiên bản mobile app. Mỗi lần update như thế, các dev sẽ phải đẩy lên lại các chợ ứng dụng, quá trình như thế sẽ mất khá nhiều thời gian và công sức hơn so với PWA cập nhật trang web.
Với PWA, bạn chỉ việc release bản update một lần và refresh cache trên website. Tính năng đồng bộ ngay cả khi người dùng không mở PWA cũng được phát triển. Twitter được biết đến là một trong những đơn vị tiên phong trong việc sử dụng PWA. App size trên Android app của Twitter chiếm dụng 24mb, iOS app chiếm 214mb dung lượng máy, trong khi đó với PWA chỉ tốn 600 kb cho điện thoại. Đối với những khách hàng không muốn tốn quá nhiều dung lượng điện thoại hay không muốn cài đặt thêm các app khác gây tốn bộ nhớ máy thì đây là một lựa chọn tuyệt vời.
Chi phí vận hành và duy trì
Chi phí doanh nghiệp và lập trình cũng là một đề cần lưu tâm cho một dự án công nghệ. Với một doanh nghiệp e-commerce, xây dựng website cùng IOS + Android app sẽ yêu cầu chi phí vận hành lớn với đội nhân sự bao gồm front-end, back-end, IOS developer và Android developer.
Trong khi đó với PWA, với bản chất web-app dựa trên nền tảng công nghệ website, đội ngũ sẽ rút ngắn chỉ cần frontend và backend. Tuy việc thực hiện ứng dụng PWAs đòi hỏi số lượng nhân lực ít hơn, nhưng lại cần nhiều kỹ năng hơn. Đối với đội ngũ front-end đang quen thuộc với JQuery và HTML từ cách phát triển truyền thống backend-driven website, bây giờ sẽ cần học hỏi và tìm hiểu nhiều dạng kiến thức hơn để thực hiện dự án, và đội ngũ lập trình website truyền thống sẽ phải hiểu thêm về trải nghiệm người dùng trên mobile app.
Search Engine Optimization
Ưu điểm của PWA là ta có thể tối ưu hóa SEO cho nó. Vì vẫn là server side rendering nên ta vẫn có thể tối ưu hóa việc hiển thị trên Google với các kỹ thuật về technical SEO.
Đối với native app, ta khó có thể tối ưu hóa nội dung SEO mà chỉ có thể giới thiệu trên website, dẫn link tới chợ ứng dụng, hoặc trả tiền quảng cáo trên các chợ ứng dụng. Ngoài ra, PWA được tạo ra để tối ưu hóa trải nghiệm người dùng trên mobile, nhanh hơn, tiện dụng hơn, về thiết kế nó vẫn là mobile-first design và tuân thủ các nguyên tắc thiết kế được ưu ái của các công cụ tìm kiếm như Google, Bing.
PWA giúp nâng cao trải nghiệm người dùng với mobile website
Progressive Web App và Native App có đang trong thế “đối đầu” nhau?
Với những ưu thế nổi trội của PWA – là sự kết hợp của website và native app, nhiều người đã đặt các câu hỏi và so sánh PWA với Native App. Nhưng sự thật thì hai nền tảng này hoàn toàn không nằm trong thế đối đầu với nhau. Ít nhất ở thời điểm hiện tại.
Số lượng người dùng di động trên thế giới là khoảng 3 tỷ người, thị trường hoàn toàn đủ lớn để PWA và Native App cùng phát triển. Bên cạnh đó, PWA giúp chuyển hóa first-time user (người mua lần đầu) khá tốt, nhằm giúp họ làm quen với nhãn hàng và dần trở thành khách hàng trung thành. Từ đó, doanh nghiệp dễ dàng thu hút họ hơn trong việc tải và sử dụng native app của mình. Vì vậy, có thể thấy, ở thời điểm hiện tại PWA đang hỗ trợ cho Native App, chứ không hề ở thế đối đầu nhau.
Bên cạnh đó, PWA hiện tại vẫn đang trong quá trình phát triển nên vẫn còn khá mới mẻ. Đối với những doanh nghiệp có tiềm lực tài chính tốt, họ sẽ lựa chọn sử dụng cả hai vì không ai muốn mất khách hàng cả, doanh nghiệp nào cũng sẽ muốn tối ưu hóa lợi nhuận của mình.
Với các doanh nghiệp vừa và nhỏ, chi phí duy trì IOS app và Android App sẽ khá cao, nhất là với các Ecommerce app. PWA có thể chính là giải pháp phù hợp cho họ. Đặc biệt, đối với các doanh nghiệp có số lượng tải app của họ quá thấp, họ sẽ tìm cách để tối ưu hóa chi phí, tìm cách nào tiết kiệm hơn so với việc bảo trì Native App và cũng tìm đến với PWA.
Tương lai của Progressive Web App ở thị trường châu Á sẽ ra sao?
Châu Á là thị trường tiềm năng với lượng dân số đông, bối cảnh thị trường công nghệ độc đáo. Vì thế, tại châu Á, các doanh nghiệp sẽ đối mặt cả những vấn đề mà thế giới gặp phải, cũng như chưa thị trường nào từng trải qua. Nếu lựa chọn một nơi có một bước nhảy vọt và tiên phong về công nghệ, những báo cáo thị trường luôn chọn châu Á là nơi đi đầu trong tất cả những xu hướng đó.
Bối cảnh thị trường châu Á có 4 điểm chính:
Mức độ sử dụng di động rất cao
Việc sử dụng di động để mua hàng và truy cập mạng xã hội rất phổ biến
Dễ dàng chấp nhận công nghệ mới
Các công ty công nghệ nhanh chóng mở rộng cơ hội sáng tạo.
Mức độ sử dụng di động ở châu Á đặc biệt cao, nhiều hơn hẳn so với laptop, TV hay các hình thức giải trí khác. Khả năng tiếp cận công nghệ của gen Z rất nhạy bén. Vì là những người trưởng thành hoàn toàn trong thời kỳ công nghệ nên việc họ tương tác trên mạng xã hội rất cao, hình thành nên những ngành nghề hoàn toàn mới như content creator, influencer, streamer. Hành vi trên mạng xã hội rõ ràng cũng đã thay đổi rất nhiều.
Mức độ sử dụng di động ở châu Á rất cao, nhiều hơn hẳn so với laptop, TV hay các hình thức giải trí khác. Khả năng tiếp cận công nghệ của gen Z rất nhạy bén. Vì là những người trưởng thành hoàn toàn trong thời kỳ công nghệ nên việc họ tương tác trên mạng xã hội rất cao, hình thành nên những ngành nghề hoàn toàn mới như content creator, influencer, streamer. Hành vi trên mạng xã hội rõ ràng cũng đã thay đổi rất nhiều.
Châu Á đã, đang và sẽ tiếp tục là thị trường “màu mỡ” của PWA
Về khả năng thích ứng với công nghệ mới ở châu Á gần như cao hơn hẳn so với các khu vực khác trên thế giới. Một phần của vấn đề này liên quan đến bối cảnh văn hóa độc đáo của khu vực này. Đây là môi trường khá non trẻ, các công ty đa phần đều thuộc first generation (thế hệ đầu tiên) nên họ sẽ không có lịch sử 200, 300 năm hay những yếu tố lịch sử tương tự. Từ đó, các công ty thường sẽ mở rộng và dễ dàng đón nhận xu hướng hơn và có nhiều cơ hội sáng tạo hơn.
Ở châu Á cũng sẽ gặp những vấn đề mà không có châu lục nào gặp phải (như không có quốc gia nào trên thế giới có đến hơn 1 tỷ dân như Trung Quốc, Ấn Độ) nên đây cũng là động lực để đáp ứng nhu cầu thị trường đa dạng để các doanh nghiệp công nghệ tiếp tục phát triển nhiều hơn trong tương lai. Bên cạnh đó, ta cũng có thể thấy sự khác biệt về thị trường công nghệ phát triển cao (Nhật Bản – Hàn Quốc) và đang phát triển (Đông Nam Á), tạo ra một bối cảnh đặc biệt thú vị và khó dự đoán tại Châu Á
Không có một “”châu Á đồng nhất””, những công ty công nghệ lâu đời ở Hàn Quốc và Nhật Bản nên sẽ mang đến cho các lập trình viên những cơ hội công việc ổn định và môi trường phát triển chắc chắn hơn. Trong khi đó, Trung Quốc, Ấn Độ và các quốc gia khu vực Đông Nam Á sẽ phải đối mặt với những khó khăn khác nhau, nên đây cũng là cơ hội để các công ty có cơ hội tiếp xúc với PWA nói riêng và các công nghệ mới nói chung.
Từ bối cảnh công nghệ của châu Á, ta có khẳng đinh về châu Á là một mobile-first region, châu lục được thống trị bởi nhu cầu sử dụng di động. Tối ưu hóa trên di động từ đó cũng sẽ mang lại cạnh tranh màu mỡ cho doanh nghiệp.
Một đặc tính thị trường châu Á ta có thể là sự thống trị của Marketplace – những trang web trung gian, các sàn thương mại điện tử, từ Taobao, Lazada, Shopee, Tiki,… Vậy nên để các doanh nghiệp nhỏ và vừa, những doanh nghiệp không phải là Marketplace muốn tồn tại được, họ bắt buộc phải sáng tạo nhiều hơn, tiến bộ nhiều hơn, tìm những đường ngách để đi, tăng cường các kế hoạch branding cho doanh nghiệp trên tinh thần tập trung tối ưu mobile. PWA ở đây sẽ là một lựa chọn đổi mới có hiệu quả dài lâu cho các doanh nghiệp này.
PWAs trên ecommerce – bước đầu tiếp cận Headless Commerce
Kể cả khi người dùng đến với cửa hàng thực tế mua hàng, họ vẫn sử dụng di động để xem review của người mua trước, so sánh với các cửa hàng khác tương đương để đi đến quyết định có mua sản phẩm đó hay không. Khách hàng quan tâm tới việc tiếp cận nhãn hàng ở nhiều khía cạnh hơn là chỉ mua ở cửa hàng.
Khi di động là chìa khóa để phát triển doanh số, headless commerce cũng là sự phát triển tất yếu trong e-commerce.
Headless Architecture là gì? Đó là việc phát triển tách rời phần front-end và back-end của website, thông tin sẽ được gọi thông qua hệ thống API. Headless cho phép phần front-end (giao diện) không phụ thuộc và linh hoạt hơn khi tùy chỉnh và cá nhân hóa trải nghiệm người dùng, dễ dàng hơn cho doanh nghiệp kết nối thông tin với nhiều kênh bán hàng hơn (multiple touch-point) – một trong những yếu tố nền tảng của omnichannel để tạo ra vòng tròn trải nghiệm đa điểm cho khách hàng. Từ đó tăng sale, năng lực cạnh tranh và quản lý đồng nhất cho doanh nghiệp.
Thay vì là cấu trúc backend-driven truyền thống, xu hướng headless hiện tại sẽ phân tách cấu trúc frontend và backend. Backend sẽ xử lý phần logic, frontend sẽ độc lập kết nối với rất nhiều selling point để tạo ra lợi thế cạnh tranh và tăng sale cho doanh nghiệp.
Với PWA, lập trình viên cũng sẽ bắt đầu phải làm quen với việc phát triển tách rời front-end và back-end, làm việc với manifest và service worker, cho phép cache các thông tin và chức năng đẩy thông báo (push notification) tương tự như native app. Đây cũng sẽ bước đầu chuyển đổi website truyền thống trở thành cấu trúc headless.
Tuy còn khá nhiều thách thức, nhưng nếu xét tới khía cạnh thị trường và hỗ trợ công nghệ, ta có thể sự phát triển của PWAs còn tiếp tục tăng cao trong tương lai. Hi vọng bài viết sẽ đóng góp thêm một vài góc nhìn cho các bạn lập trình viên khi tiếp cận PWA.
Bài viết được trích dẫn từ phần trình bày của chị Ngô Kiều Anh tại sự kiện Vietnam Web Summit 2020 LIVE do TopDev tổ chức
Cấm kỵ khi đi phỏng vấn, đặc biệt là các phát ngôn có khiến bạn thắc mắc? Vậy đâu là lỗi khi đi phỏng vấn; cách gây ấn tượng lúc phỏng vấn như thế nào? Interview Round giúp nhà tuyển dụng khai thác tiềm năng và đánh giá mức độ phù hợp của ứng viên.
Để tạo ra sự thu hút nhà tuyển dụng, ứng viên cần có các câu trả lời ấn tượng nhất thể hiện đúng cá tính của mình. Song, cá tính là điều tốt nhưng phải luôn chừng mực và được đặt đúng chỗ. Cùng TopDev điểm qua các câu trả lời cấm kỵ khi đi phỏng vấn .
Hãy cho chúng tôi biết về bản thân bạn?
Với câu hỏi này, ứng viên sẽ chia sẻ những điều cơ bản về bản thân (có thể khác các nội dung đã đề cập trong CV).
Tăng hiệu quả ứng tuyển bằng cách tạo CV Online hiệu quả trên TopDev
Các ứng viên nói rằng họ thừa năng lực để thực hiện công việc đó. Họ nhận thấy kỹ năng của mình còn quá tệ, làm sao có thể đủ sức cạnh tranh. Đặc biệt, họ lại chia sẻ về sự lo lắng, quá hồi hộp của bạn thân. Đồng thời, ứng viên cũng thể hiện sự mơ hồ của mình trong việc lập kế hoạch tương lai. Mọi thứ chung quanh có vẻ quá sức với họ.
Hãy loại bỏ ngay những cách trả lời ấy vì bạn đang lãng phí đi các cơ hội. Bạn không thể nói quá nhiều về bản thân. Điều đó chứng tỏ bạn là người tự cao. Ngược lại, việc luôn tự ti sẽ làm buổi phỏng vấn trở nên chùn xuống. Vậy đâu là lỗi khi đi phỏng vấn, gây ấn tượng lúc phỏng vấn? Cùng tìm hiểu ngay sau đây!
Giải pháp phỏng vấn khắc phục cấm kỹ khi đi phỏng vấn
Nhà tuyển dụng sẽ không bao giờ chọn một ứng viênthiếu sự tiết chế trong cách định hướng các phản hồi cá nhân. Bạn không nên thể hiện các dấu hiệu tiêu cực và dùng nó để tạo “điểm nhấn”. Đó được đánh giá là nước đi thiếu khôn ngoan. Hơn thế nữa, nó còn làm cản trở sự tương tác giữa bạn và nhà tuyển dụng.
Đừng để mọi chuyện vượt ra khỏi trọng tâm của nội dụng phỏng vấn. Và đó là điều cấm kỵ khi đi phỏng vấn. Bạn không nên chia sẻ quá nhiều về thông tin, Vì thực tế, nhà tuyển dụng cho rằng đó là những thông tin dư thừa.
Bạn muốn mình là ai trong 5 năm tới?
Nhiều ứng viên đã trình bày các kế hoạch không một tí liên quan gì đến công việc như: mua nhà, đi du lịch, kinh doanh,…
Hoặc thậm chí, ứng viên bộc lộ nhiều sự cường điệu trong cách dẫn dắt câu chuyện. Chẳng hạn như việc chia sẻ rằng họ sẽ là một người có đam mê với công việc nhiều nhất; làm việc chăm chỉ nhất. Tồi tệ hơn là có nhiều ứng viên chỉ cười trừ vì không biết phải trả lời như thế nào. Vậy đâu là lỗi khi đi phỏng vấn, gây ấn tượng lúc phỏng vấn?
Bạn phải thật sự cẩn trọng trong cách trả lời của mình. Nếu không, bạn sẽ thất bại về vấn đề tri nhận các yêu cầu phản hồi thông điệp. Dù bạn cố tình hay vô tình (thiếu sự trải nghiệm), bạn cũng không nên khiến mình thiếu chuyên nghiệp.
Giải pháp khắc phục lỗi khi đi phỏng vấn
Cách tốt nhất là bạn nên xâu chuỗi các yêu cầu để có câu trả lời thật sự phù hợp. Thay vì nói một cách dàn trải, bạn hãy đặt ra hai dự định bạn sẽ thực hiện. Đó là dự định trong tương lai gần – Mục tiêu ngắn hạn và tương lai xa – Mục tiêu dài hạn.
Hãy tự tin để nói về các hoài bão cá nhân (tất nhiên nó vẫn đảm bảo sự tương quan với năng quan, kỹ năng, đam mê,…) của bạn. Đó có thể là lên vị trí Chuyên viên cho một lĩnh vực nào đó; mơ ước về việc điều hành một công ty mang dấu ấn của mình;… đừng ngần ngại nói cho nhà tuyển dụng biết bạn muốn mình ai.
Ngoài ra, bạn có thể mô tả đôi chút về những dự định ấy gắn với các thách thức cần bạn phải vượt ra. Đâu là điều bạn có để tạo ra lợi thế cho mình? Đâu là điểm bạn cần khắc phục? Đây đều là những điều bạn nên lưu tâm để có sự phản hồi tốt nhất với nhà tuyển dụng.
Tại sao chúng tôi nên chọn bạn?
Nhiều ứng viên khi gặp câu hỏi này họ thường nói nhiều hơn về bản thân. Đó là trường hợp thể hiện bản thân quá tự tin (như bài viết đã trình bày phía trên). Vậy đâu là lỗi khi đi phỏng vấn, gây ấn tượng lúc phỏng vấn?
Một cách trả lời khác được đánh giá là thiếu tinh tế và cấm kỵ là việc nói về những hạn chế của các ứng viên khác. Hoặc đơn giản, ứng viên sẽ thể hiện sự thất vọng thay vì thể hiện khao khát vị trí. Họ bắt đầu “bài tập làm văn” về những viễn cảnh có thể xảy ra nếu không may mắn trượt vị trí công việc này.
Giải pháp gây ấn tượng lúc phỏng vấn
Trong trường hợp này, bạn nên tập trung vào việc thể hiện mình nhiều hơn. Hãy nói về những thế mạnh của bản thân nhưng đừng quá phô trương.
Bên cạnh đó, hãy thể hiện rằng vị trí công việc bạn đang ứng tuyển là cơ hội để bạn phát triển khả năng tốt hơn. Bạn có thể kể những điểm còn hạn chế của bản thân. Song, bạn trình bày mong muốn sẽ cố gắng và học hỏi nếu có cơ hội làm việc tại đây.
Đừng thể hiện cảm xúc tiêu cực (cho dù đó là thật hay giả). Bạn cần cho nhà tuyển dụng thấy được bạn là ứng viên tiềm nang, biết tạo ra sự kết nối thông qua nguồn năng lượng từ chính khao khát được trải nghiệm vị trí này.
Tại sao bạn quan tâm đến công việc này?
Nếu có cách ứng xử thông mình, hiệu quả phỏng vấn hầu như đạt mức tuyệt đối. Tuy nhiên, nhiều câu trả lời dường như chỉ tập trung vào việc đào sâu các vấn đề nhạy cảm liên quan đến công việc. Cụ thể, nhiều ứng viên sẽ đề cập đến mức lương và các chế độ thuộc về mặt quyền lợi của nhân viên. Từ đây, các ý kiến khác nhau được bàn luận. Hãy cẩn trọng để không phải mắc phải cấm kỵ khi đi phỏng vấn nhé!
Em mong muốn mức lương bao nhiêu? Theo em tự đánh giá, với năng lực hiện tại thì mức lương cụ thể nào phù hợp với em?
Nhiều ứng viên đã đánh giá về mức lương. Họ chê mức lương hoặc đề nghị một mức lương cao hơn. Tất nhiên, câu chuyện về quyền lợi thì bất cứ ứng viên nào cũng đều quan tâm. Nhưng họ cần biết, nếu là một ứng viên thông minh và nhạy bén, ít ai lại “cò kèo” lương với nhà tuyển dụng. Vậy đâu là lỗi khi đi phỏng vấn, gây ấn tượng lúc phỏng vấn?
Một cách phản hồi cấm kỵ khi đi phỏng vấn nữa đó là ứng viên than vãn hoặc đòi hỏi quá nhiều về “giấc mơ doanh nghiệp”. Ví dụ họ muốn có một môi trường làm việc tốt, một người sếp biết quan tâm, các kế hoạch cho sự thăng tiến,… Đây mới thật sự là những gì họ quan tâm.
Giải pháp phỏng vấn
Hãy là một ứng viên ứng xử khôn khéo. Bạn có thể để xuất mức lương phù hợp với năng lực của mình. Điều này đòi hỏi bạn phải hiểu rõ những gì mình cò để đề nghị một mức lương phù hợp. Nếu không trò cười sẽ tiếp nối trò cười.
Không những thế, bạn có thể chọn cách trả lời thông mình hơn. Đó là gửi lời cam kết với nhà tuyển dụng về việc đánh giá dựa vào năng lực của bản thân. Nhả tuyển dụng sẽ đánh giá hiệu suất của bạn thông qua thành tích. Việc của bạn là cứ làm tốt và phát huy đối đa những gì mình có.
Ngưng than vãn và chấp nhận những trải nghiệm mới. Có nọ có kia thì cuộc hành trình nghề nghiệp mới trở nên thú vị.
Lời kết
Có rất nhiều câu chuyện thú vị xoay quanh vấn đề cấm kỵ khi đi phỏng vấn ứng viên. TopDev hi vong với bài viết này, các bạn sẽ hiểu thêm về thực trạng tuyển dụng. Đồng thời nhận ra những thiếu sót và bắt đầu lên kế hoạch hoàn thiện bản thân mình nhiều hơn. Những phân tích trong bài viết đều dựa trên những trải nghiệm từ đội ngũ. Hãy thảo luận và tìm ra nhiều hơn các câu trả lời cấm kỵ khi đi phỏng vấn để khắc phục nhanh chóng. Chúc các bạn có sự chuẩn bị tốt nhất cho buổi phỏng vấn của mình.
Bài viết được sự cho phép của tác giả Kien Dang Chung
Mỗi khi học một ngôn ngữ lập trình mới, việc đầu tiên chúng ta cần là học các cú pháp câu lệnh cơ bản. Với Vue.js thì có khác đi một chút do đây là một framework không phải là ngôn ngữ lập trình. Vue.js như là một ngôn ngữ trung gian, mọi thứ sẽ bạn viết sẽ Vue.js chuyển thành ngôn ngữ HTML kết hợp Javascript và CSS (còn gọi là render, thuật ngữ này sẽ được sử dụng nhiều cho ngắn gọn). Như vậy, về cơ bản Vue.js có thể sử dụng các cú pháp câu lệnh trong HTML, CSS và Javascript. Tuy nhiên, Vue.js cũng có một số các cú pháp riêng sử dụng cho những trường hợp sau:
In kết quả biểu thức ra màn hình.
Các phần xử lý có kiểm tra điều kiện.
Các phần xử lý kiểu vòng lặp.
Xử lý theo cách cá nhân hóa, xây dựng các plugin, module…
Vue.js sử dụng cú pháp {{ }} để in một biểu thức ra màn hình, kiểu cách này giống như Laravel sử dụng. Chúng ta cùng xem lại ví dụ đầu tiên của Vue.js:
<!DOCTYPE html><html><head><title>Ví dụ đầu tiên Vue.js - allaravel.com</title></head><body><div id="app"><h1>{{ message }}</h1><input v-model="message"></div><script src="https://vuejs.org/js/vue.min.js"></script><script type="text/javascript">newVue({
el:'#app',
data:{
message:'Xin chào, tôi là Vue.js'}})</script></body></html>
Trong ví dụ này chúng ta in giá trị của biến message vào thẻ <h1>. Trình biên dịch sẽ thay đối tượng message thành giá trị của nó khi render. Như vậy để in một đối tượng chúng ta chỉ cần đưa chúng vào cú pháp {{ doi_tuong_javascript }}. Chúng ta có một số chú ý khi sử dụng cú pháp {{ }} như sau:
Chú ý 1: Khi render cú pháp {{ }} xử lý dữ liệu dạng text đơn thuần chứ không xử lý các text dạng mã HTML. Ví dụ, nếu đối tượng message chứa dữ liệu dạng text HTML “Xin chào, tôi là <strong>Vue.js</strong>” thì nó vẫn in nguyên giá trị này ra. Nếu muốn trình biên dịch xử lý các biến dạng mã HTML, chúng ta sử dụng câu lệnh v-html. Chúng ta cùng xem sự khác nhau trong ví dụ dưới đây:
<html><head><title>In kết quả biểu thức trong Vue.js - allaravel.com</title></head><body><div id="app"><h1 v-html="message"></h1><h1>{{ message }}</h1><input v-model="message"></div><!-- <script src="https://unpkg.com/vue@2.5.16/dist/vue.min.js"></script> --><script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script><script type="text/javascript">newVue({
el:'#app',
data:{
message:'Xin chào, tôi là <span style="color: #41B883;">Vue</span>.<span style="color: #354B5E;">js</span>'}})</script></body></html>
Trong Laravel Blade, việc xử lý text đơn thuần hay mã HTML sử dụng các cú pháp tương ứng là {{ }} và {!! !!}.
Chú ý 2: Không sử dụng cú pháp {{ }} trong một thuộc tính của thẻ HTML. Thay vào đó sử dụng câu lệnh v-bind để gán một giá trị vào một thuộc tính trong thẻ HTML. Ví dụ
<img src="{{ imageUrl }}">
không hoạt động mà phải viết lại như sau:
<img v-bind:src="imageUrl">
Câu lệnh v-bind sẽ được giới thiệu chi tiết hơn ở phần cuối bài viết.
In giá trị biểu thức Javascript
Đây là trường hợp tổng quát, nó bao hàm cả trường hợp in giá trị đối tượng ở trên, tức là đối tượng nằm trong {{ }} có thể là một biểu thức Javascript. Chúng có thể là các biểu thức tính toán hoặc một lời gọi một hàm tính toán.
Chú ý, nội dung trong {{ }} phải là biểu thức và biểu thức dạng đơn chứ không thể sử dụng các biểu thức kiểu nhiều dòng hoặc các biểu thức dạng điều kiện. Các ví dụ dưới đây sẽ không chạy ra kết quả và báo lỗi:
<!-- đây là một câu lệnh không phải là biểu thức -->{{var a =1}}<!-- Câu lệnh điều kiện, rẽ nhánh không được sử dụng -->{{if(ok){return message }}}
Câu lệnh
Trong Vue.js có một khái niệm là directive dùng để đánh dấu các chỉ thị, lệnh hướng dẫn trình biên dịch xử lý các công việc cụ thể và sinh ra mã HTML cuối cùng (render). Trong suốt loạt bài này chúng ta sẽ sử dụng trực tiếp khái niệm directive hoặc câu lệnh cho thuận tiện. Các câu lệnh này bắt đầu bằng chữ v (Vue.js), ví dụ v-if, v-for, v-bind, v-html… và nằm trong các thẻ HTML dưới dạng các thuộc tính của thẻ. Trong ví dụ Hello world! chúng ta có đoạn:
<input v-model="message">
Câu lệnh v-model ở đây trông giống như một thuộc tính của thẻ input, trình biên dịch khi xử lý đoạn mã này nó sẽ biết v-model là câu lệnh nhằm chỉ thị là gán giá trị đối tượng message vào thuộc tính value của thẻ input.
Các câu lệnh có thể có tham số, có thể tham số là một tên một thuộc tính hoặc tên một sự kiện của thẻ HTML. Cú pháp truyền tham số vào câu lệnh là cau_lenh:tham_so.
Ví dụ 1: câu lệnh v-bind có thể có tham số là tên thuộc tính cần gán giá trị. Ví dụ:
<img v-bind:src="imageUrl">
Ở đây src là tham số chính là thuộc tính src của thẻ img. Một ví dụ khác là câu lệnh v-on để xử lý các sự kiện với các phần tử HTML, ví dụ nếu click vào một nút thì sẽ thực hiện một phương thức trong Javascript:
<button v-on:click="doSomething">
thì click là một tham số. Trong Vue.js chỉ có hai câu lệnh có tham số là v-bind và v-on, khi sử dụng các câu lệnh này có thể sử dụng dạng viết tắt tương ứng là : và @. Các ví dụ sử dụng v-bind và v-on có thể được viết lại như sau:
Qua bài viết chúng ta đã trả lời được Vue.js directive là gì? cách sử dụng để gán dữ liệu hoặc in giá trị đối tượng ra màn hình. Bài viết chỉ dừng lại ở giới thiệu mà chưa đi sâu cụ thể vào từng câu lệnh v-xyz, trong những bài viết tiếp theo, chúng ta sẽ cùng tìm hiểu chi tiết từng câu lệnh của Vue.js.
Một developer trẻ nói với Chú của mình về việc cậu ta muốn trở thành một Software Architecture trong tương lai. Sau đây là cuộc nói chuyện giữa hai chú cháu.
Con muốn sau này trở thành một Software Architecture (kiến trúc sư phần mềm).
Con có định hướng cho mục tiêu nghề nghiệp vậy là tốt lắm đó.
Con muốn được dẫn đầu một nhóm và đưa ra các quyết định quan trọng như chọn loại Database nào, Framework nào, Web API thế nào và dùng những công nghệ nào cho dự án.
Khá đó chứ. Nhưng nghe có vẻ như con không phải muốn trở thành Software Architecture nữa.
Tất nhiên là con muốn chứ. Con muốn trở thành một người quyết định tất cả những thứ quan trọng.
Chú biết vậy, nhưng mà con đang liệt kê những thứ không quan trọng. Chính xác hơn là những thứ con liệt kê nó không liên quan đến quyết định của một Software Architecture.
Ý của Chú là sao? Database mà không quan trọng sao? Chú có biết phải chi bao nhiêu tiền cho chúng không?
Có lẽ là rất nhiều, nhưng mà lựa chọn database không phải là một trong những quyết định quan trọng.
Sao Chú nói vậy? Database là trái tim của toàn hệ thống. Nó là nơi dữ liệu được lưu trữ, sắp xếp, đánh index và được truy cập. Không có nó thì sẽ không có hệ thống.
Database đơn thuần chỉ là một thiết bị IO. Nó chỉ là một công cụ hữu ích để sắp xếp, truy vấn và báo cáo nhưng đó chỉ là những phụ trợ cho kiến trúc hệ thống.
Phụ trợ hả? Chú giởn với con đúng không.
Chú nói thật, nó là phụ trợ thôi. Những nghiệp vụ (Business logics) của hệ thống có thể được sử dụng một trong các công cụ đó, nhưng những công cụ đó không phải là bản chất của các nghiệp vụ. Nếu cần con có thể thay thế Database này thành Database khác hoặc chuyển sang dùng Framework khác, nhưng các nghiệp vụ trong hệ thống của con vẫn như vậy.
Ý của Chú là sao?
Vấn đề của con là tin rằng các nghiệp vụ của phần mềm phụ thuộc vào các công cụ của Database. Sẽ không có chuyện đó hoặc có ít thôi nếu con cung cấp kiến trúc phần mềm tốt.
Chú nói nghe khó hiểu quá. Làm sao để xây dựng các nghiệp vụ mà lại không dùng đến các công cụ mà chúng phải dùng chứ.
Chú không có nói chúng ta không dùng các công cụ của Database, Chú nói chúng ta không nên phụ thuộc vào các công cụ để phát triển dự án. Các quy tắt nghiệp vụ sẽ không cần biết loại Database nào sẽ được dùng.
Vậy làm sao để có được các nghiệp vụ sử dụng các công cụ mà lại không biết về các công cụ?
Con hãy đảo ngược sự phụ thuộc này lại. Nghĩa là con có database phụ thuộc vào các nghiệp vụ, bây giờ con làm cho các nghiệp vụ không còn phụ thuộc vào database.
Vô lý quá vậy Chú.
Bình tĩnh, Chú đang nói với tư cách là một Software Architecture. Trong thiết kế phần mềm có một nguyên lý gọi là Dependency Inversion Principle. Nguyên lý này nói là những thứ low level sẽ phụ thuộc vào những thứ high level hơn, không được ngược lại.
Khó hiểu quá! những thứ high level ( Con đoán ý Chú là các nghiệp vụ – business logics) gọi xuống những thứ low level ( Con đón ở đây là database nè). Thế thì những thứ high level phụ thuộc vào low level cũng giống như callers thì phụ thuộc vào callees. Ai cũng hiểu vậy hết chơn hết chội (ai cũng hiểu vậy cả).
Tại thời điểm runtime thì đúng (lúc chạy chương trình). Nhưng tại thời điểm compile time (lúc biên dịch code hay viết code) chúng ta muốn đảo ngược các phụ thuộc này. Source code của high level (các nghiệp vụ) sẽ không cần biết source code ở low level (code để kết nối, thao tác với database)
Sao được Chú! mình gọi một cái gì đó mà không cần biết đến nó sao được.
Được chứ. Cái đó gọi là lập trình hướng đối tượng (OOP).
Con biết lập trình hướng đối tượng nè. Lập trình hướng đối tượng là việc tạo các classes (hay objects) từ thế giới thực vào trong phần mềm, các đối tượng (objects) thì có các thuộc tính (properties) và các hành vi (behaviors). Các đối tượng tương tác với nhau bằng cách gọi các functions của nhau. OOP là một cách để tổ chức code trực quan hơn.
Con biết chỉ có vậy thôi hả?
Ai cũng biết vậy mà Chú. Nó đúng mà.
Con nói không sai. Tuy nhiên, việc sử dụng các nguyên lý của lập trình hướng đối tượng sẽ giúp cho con gọi một cái gì đó mà không cần biết tới nó.
Con đồng ý luôn, Vậy làm thế nào đây?
Con có biết trong lập trình hướng đối tượng, các đối tượng có thể gửi tin nhắn cho nhau không?
Dạ, con biết chứ.
Rồi, con có biết là sender (đối tượng gửi message) không cần biết gì về kiểu dữ liệu của receiver (đối tượng nhận message)?
Cái này còn tùy vào ngôn ngữ mình đang dùng. Trong Java thì sender ít nhất cũng biết được base type của receiver. Trong Ruby thì sender ít nhất cũng phải biết receiver có thể handler được message.
Đúng vậy, nhưng cả hai trường hợp sender không hề biết chính xác kiểu dữ liệu của receiver.
Dạ, đúng như vậy.
Vì vậy sender có thể gọi một hàm bên trong receiver mà không cần biết chính xác kiểu dữ liệu của receiver đó.
Dạ, đúng. Con hiểu điều đó. Nhưng sender vẫn phụ thuộc và receiver.
Tại thời điểm chạy chương trình (runtime) thì đúng, nhưng lúc viết code (compile time) thì không. Source code của sender không hề biết cũng không hề phụ thuộc vào source code của receiver. Thức tế thì source code của receiver lại phụ thuộc vào source code của sender.
Không đời nào! con nghĩ là Sender vẫn phụ thuộc vào class mà nó đang gửi message.
Có lẽ chúng ta nên dùng vài dòng code để làm rõ vấn đề hơn. Chú sẽ viết cái này với Java. Đầu tiên là package sender:
package sender;
public class Sender {
private Receiver receiver;
public Sender(Receiver r) {
receiver = r;
}
public void doSomething() {
receiver.receiveThis();
}
public interface Receiver {
void receiveThis();
}
}
Tiếp theo sẽ là package receiver:
package receiver;
import sender.Sender;
public class SpecificReceiver implements Sender.Receiver {
public void receiveThis() {
//do something interesting.
}
}
Con hãy để ý là package receiver đang phụ thuộc vào package sender. Cụ thể là class SpecificReceiver phụ thuộc vào Sender. Con cũng thấy là package Sender không hề biết bất cứ thứ gì trong package Receiver.
Dạ, nhưng Chú đã cheated code. Chú đã đặt interface của receiver bên trong class sender.
Con bắt đầu hiểu vấn đề rồi đó, khá nhanh đấy chứ.
Mà hiểu cái gì vậy Chú? ahihi
Đó là các nguyên lý của kiến trúc phần mềm. Senders sở hữu các interfaces mà receivers phải implement.
Chà..! vậy là con phải dùng các lớp lồng nhau (nested-classes).
Nested-classes chỉ là một trong những cách để đạt được điều đó. Còn nhiều cách khác nữa.
OK Chú. Bây giờ quay lại vấn đề với database mà Chú cháu mình đã nói lúc đầu đi. Chú giải quyết nó thế nào.
Con hãy xem code sau đây nhé. Đầu tiên là source code dành cho business rule.
package businessRules;
import entities.Something;
public class BusinessRule {
private BusinessRuleGateway gateway;
public BusinessRule(BusinessRuleGateway gateway) {
this.gateway = gateway;
}
public void execute(String id) {
gateway.startTransaction();
Something thing = gateway.getSomething(id);
thing.makeChanges();
gateway.saveSomething(thing);
gateway.endTransaction();
}
}
Code cho nghiệp vụ ít quá vậy Chú.
Ví dụ đơn giản cho dễ hiểu thôi con trai. Con có thể thêm nhiều class mới, viết code implement cho nhiều nghiệp vụ khác nếu con muốn.
Dạ, vậy Gateway là gì thế Chú?
Nó cung cấp tất cả các phương thức (methods) để cho business rule truy cập xuống database. Code implemented của nó như sau:
Con hãy chú ý là nó nằm trong package businessRules.
Dạ, con thấy rồi. Còn lớp Something là gì vậy Chú?
Nó là 1 object của business. Chú đặt nó trong package tên là entities.
package entities;
public class Something {
public void makeChanges() {
//...
}
}
Cuối cùng là viết code implement cho BusinessRuleGateway. Đây là class biết về database thực sự đang dùng. Trong ví dụ này, Chú sẽ dùng MySql.
package database;
import businessRules.BusinessRuleGateway;
import entities.Something;
public class MySqlBusinessRuleGateway implements BusinessRuleGateway {
public Something getSomething(String id) {
// use MySql to get a thing.
}
public void startTransaction() {
// start MySql transaction
}
public void saveSomething(Something thing) {
// save thing in MySql
}
public void endTransaction() {
// end MySql transaction
}
}
Một lần nữa, con hãy để ý là các business rules (nghiệp vụ) gọi database lúc runtime (chạy chương trình), nhưng lúc compile time (lúc viết code) thì database package lại phụ thuộc vào businessRules package.
Dạ dạ, con nghĩ là con đã hiểu. Chú dùng đa hình (polymorphism) để ẩn đi implementation của database package từ businessRules package. Nhưng Chú vẫn phải có một interface để cung cấp tất cả các thứ trong database mà business rule cần.
Không phải tất cả. Chúng ta không cung cấp tất cả các thứ trong database cho business rule. Thay vào đó, chúng ta tạo các interface trong business rule chỉ cung cấp những thứ liên quan đến database mà nó cần. Các implemenations của các interfaces này có thể gọi đến các chức năng cụ thể như: insert, delete, update trên database tương ứng mà nó đang dùng.
Dạ! nhưng mà nếu như business rules cần tất cả các chức năng liên quan đến database, như vậy thì Chú phải đặt tất cả các methods đó vào trong gateway interface.
Haizz, hình như con vẫn chưa hiểu vấn đề.
Hiểu gì nữa chứ? Con hiểu quá rõ vấn đề rồi mà.
Mỗi business rule định nghĩa 1 interface để thao tác với database mà nó cần.
Chờ đã, Chú nói cái gì con chưa rõ lắm?
Cái này gọi là Interface Segregation Principle. Mỗi class business rule sẽ chỉ dùng một số chức năng để thao tác với database. Và do đó, mỗi business rule sẽ cung cấp một interface và expose một số methods để thao tác với database.
Nhưng như vậy thì Chú phải có rất nhiều interfaces và phải có rất nhiều class để implement cho các interfaces đó.
À, đúng rồi. Chú thấy giờ con đang bắt đầu hiểu rồi đó.
Nhưng code sẽ nhiều hơn, tốn thời gian hơn? Tại sao mình phải làm vậy chứ?
Thật ra, đó là cách giúp con viết code rõ ràng và tiết kiệm thời gian.
Thôi mà Chú. Điều đó làm code phình to lên và viết nhiều code hơn thì có.
Ngược lại, đây là những quyết định kiến trúc quan trọng cho phép con trì hoãn các quyết định không liên quan.
Chú nói vậy nghĩa là sao?
Nà, có phải lúc đầu con nói là con muốn trở thành một Software Architecture? Con muốn đưa ra những quyết định quan trọng phải không?
Dạ, đó là những gì con muốn.
Trong số các quyết định con đưa ra là về: database, web api và các frameworks.
Dạ đúng rồi, nhưng Chú lại nói là những quyết định đó không quan trọng. Chúng là những thứ không liên quan.
Chính xác, những quyết định này không quan trọng cũng không liên quan. Những quyết định quan trọng mà một Software Architecture đưa ra là những quyết định giúp con KHÔNG đưa ra quyết định về database nào, web api thế nào, dùng framework nào quá sớm.
Nhưng Chú cũng phải đưa ra những quyết định này trước khi làm!
Không, không nên đâu con. Thực sự thì, con cần phải làm mọi cách để làm thế nào để có thể trì hoãn các quyết định đó càng trễ càng tốt, bởi vì làm như vậy sẽ giúp con có thêm nhiều thông tin hơn.
Điều tệ hại là nếu 1 kiến trúc sư, anh ta đã quyết định sử dụng database ngay ban đầu, và sau đó nhận ra rằng chỉ cần lưu files là đủ.
Điều tệ hại là nếu 1 kiến trúc sư, anh ta ngay từ ban đầu suy nghĩ rằng sẽ build ứng dụng trên web-server, nhưng sau đó mới nhận ra rằng, tất cả các teams thực sự chỉ cần là 1 socket interface đơn giản.
Điều tệ hại là nếu 1 kiến trúc sư, anh ta và team của mình đã sớm lựa chọn framework cho dự án, và sau đó nhận ra rằng framework cung cấp nhiều cái mà họ không cần và lại ko đáp ứng hết cái họ cần rồi tự đặt mình vào thế khó.
May mắn là team mà các kiến trúc sư đã xây dựng lên kiến trúc bằng cách nào đó cho phép họ trì hoãn các quyết định đến khi họ thực sự có đủ thông tin để đưa ra lựa chọn cuối cùng.
May mắn là team mà các kiến trúc sư là người biết cách tách kiến trúc của họ ra khỏi các device IO chậm chạp, tốn resouce và các framework để có thể tạo ra các bộ test case nhanh và nhẹ.
May mắn là team mà các kiến trúc sư chỉ quan tâm đến các vấn đề thực sự quan trọng, trì hoãn những cái không quan trọng khác.
Thua luôn, con hết hiểu nổi Chú đang nói cái gì luôn rồi.
Có lẽ con sẽ cần vài năm nữa hoặc hơn… nếu con vẫn chưa thực sự đặt chân vào công việc của 1 kiến trúc sư thực thụ, cậu bé à.
Bài viết được sự cho phép của tác giả Nguyễn Hữu Đồng
Cuộc sống thiệt là thú vị, đã code là phải có bug, muốn không có bug thì đừng code và đôi khi chúng ta cũng phải chấp nhận code là một tính năng và sống chung với nó. Lúc hệ thống của mình nhỏ, xoay đi quảnh lại mình cũng chỉ làm những việc mình làm hằng ngày, chạy task dể serve client, không có cơ hội nhìn ra xem người ta đang làm gì, xã hội phát triển như thế nào rồi, và may mắn thay mình được tạo cơ hội để bước ra, vẫy vùng trên con sông lớn, dù chưa biết mình sẽ đi về đâu nhưng thà một phút huy hoàng rồi chợ tắt còn hơn le lói cả trăm năm, huy hoàng với bản thân thôi cũng đáng giá rồi.
Lan man quá, vào vấn đề chính nào, cái RabbitMQ là gì và tại sao chúng ta nên dùng nó ? Hiện nay ở cái thời mà hệ thống web app của chúng ta lớn lên từng ngày, phân chia thành nhiều node, mỗi node lo làm một việc riêng hoặc hỗ trợ lẫn nhau để xử lí yêu cầu từ người dùng, việc đó đòi phải chúng nó phải chia sẻ được tài nguyên cho nhau và biết được mình đang được giao những gì và lấy danh sách những việc cần làm ở đâu.
Hay đơn giản với một công việc, sự kiện những mỗi thợ lại làm những việc khác nhau, ví dụ khi có chương trình mới sắp lên sóng, mọi người được thông báo và mỗi người lại làm việc theo đúng phần việc của mình.
Áp dụng vào hệ thống web, khi có một yêu cầu được gửi tới bảng thông báo, node thì truy xuất trong database lấy giữ liệu để chuẩn bị gửi cho khách hàng, node thì có nhiệm vụ ghi chú lại lại hôm nay hệ thống đã làm những gì. Mỗi node một việc, nó có thể nhận thông báo từ bảng thông báo hay lại làm nhiệm vụ của một phát thanh viên, thông báo việc đến cho các node còn lại.
Cái thứ đó cái hệ thống thông báo đó bao gồm cả các node, ngừời ta gọi là “message broker system”. Hiểu rõ hơn là hệ thống giao tiếp bằng tin nhắn giữa các hệ thống.
Như trên hình các bạn thấy, hệ thống của chúng ta gồm 4 thành phần “Producers”, “Exchanges”, “Queue” và “Consumer”. Theo hình sẽ thì ta thấy mô hình hoạt động khá đơn giản. Sẽ có một node nào đó tạo ra một tin nhắn, sau đó node đó sẽ gửi tin nhắn đó tới một trong số các Exchange sau đó Exchange sẽ phân phối tin nhắn đó tới các hàng chờ tin nhắn và sau đó, Consumer sẽ nhận tin nhắn từ hàng chờ đó và xử lí nó.
Áp dụng vào thực tế ngoài đời sống, ví dụ bạn là một nhà máy sản xuất bia, và tất nhiên bạn cần khách hàng tiêu thụ bia, bạn không thể gửi trực tiếp sản phẩm của bạn tới từng khách hàng được vì việc này rất tốn chi phí và bạn sẽ phải làm quá nhiều việc dẫn đến việc gì cũng biết mà không biết làm một việc thật tốt. Bạn cần các nhà phân phối bia và các nhà phân phối bia này cũng có thêm một vài đại lí nhỏ và cũng tương tự nhà sản xuất bia, các nhà phân phối này chỉ làm 1 việc là đi phân phối bia tới các đại lí nhỏ, đại lí nhỏ lại phân phối tới các quán tạp hoá, quán nhậu và cuối cùng tới tay ngừời tiêu dùng. Ở đây nhà sản xuất bia tương ứng với Producer, các nhà phân phối tương ứng với các Exchange, các đại lí (các hệ thống bán lẻ) tương ứng với Queue và khách hàng tương ứng với Consumer.
Bạn gái kia xinh qúa trời luôn 😀
Khách hàng uống bia, bia ngon thì khen, bia giờ thì chê, có người còn trả lại bia đòi lại tiền, consumer cũng vậy nếu consumer làm xong việc mà nó nhận từ Queue nó sẽ báo với queue là việc đó xong rồi, cho việc khác còn không thì nó sẽ báo với queue đưa việc đó cho consumer khác làm.
Có nhiều loại Exchange và cũng có loại Queue dễ tính hay khó tính, Exchange sẽ dựa vào các queue đăng kí nhận hàng từ exchange đó và phân phố tin nhắn sao cho hợp lí nhất. Sơ qua thì có 6 loại exchange từ loại chuyên chạy xe đi hỏi từng đại lí có ai muốn lấy hàng hay không cho đến loại exchange giao gì đại lí cũng lấy.
Direct Exchange
Đây là loại Exchange được dùng phổ biến nhất, nó sẽ chuyển tin nhắn đến các queue dựa vào Routing key, đúng thì gửi không đúng thì thôi, không ai nhận thì thôi.
Default exchange
Đây là loại phóng khoáng nhất và vô danh( tức là không có tên à không nó có tên là Default exchange đấy chứ ….. ), tin nhắn sẽ được vận chuyển thẳng tới Queue có tên tùng với Routing key trên tin nhắn.
Topic Exchange
Cũng vận chuyển tin nhắn tới queue đựa vào Routing key nhưng nó khá rộng rãi khi dựa vào Wildcard để xem 2 routing key có match với nhau hay không, ví dụ, “dongden” và “dongden.dev” là 2 routing key match với nhau rồi, vậy thì tin nhắn sẽ được vận đưa tới queue đó.
Header Exchange
Theo cách này mỗi queue khi khai báo nhận tin nhắn từ exchange sẽ phải khi báo rõ mình sẽ nhận tin nhắn có phần header như thế nào, bao gồm những trường và từ khoá như thế nào, exchange sẽ dựa vào tin nhắn và các điều kiện đó mà phân phối tin nhắn.
Fanout Exchange
Đúng như nghĩa fanout exchange “thổi” tin nhắn đến cho mọi queue mà đăng kí nhận từ nó.
Sơ qua vài loại đó thôi nếu bạn muốn tìm hiểu sâu hơn thì vào đây nhé 😀
Lý thuyết suông thì chán lắm “show me the code”
Ở bài viết này mình sẽ làm một ví dụ đơn giản, mình sẽ viết một con server có cho người dùng upload ảnh và sau đó mình sẽ tạo ảnh thumbna và upload chúng lên google storage.
Ở đây mình dùng Golang với Framework Gin để handle việc nhận form và lưu trữ file xuống local.
App của mình sẽ có một Producer chuyên gửi tin nhắn tới Exchange và 2 consumer làm hai việc khác nhau là Resize ảnh và Upload ảnh trong queue lên Google Storage.
package publisher
import (
"github.com/streadway/amqp"
"os"
)
var conn *amqp.Connection
var C *amqp.Channel
func JoinNetWork(){
conn,_ = amqp.Dial(os.Getenv("AMQP_URL"))
C,_ = conn.Channel()
C.ExchangeDeclare("ProcessImage",amqp.ExchangeHeaders,true,false,false,false,nil)
C.ExchangeDeclare("UploadImage",amqp.ExchangeHeaders,true,false,false,false,nil)
}
Như các bạn trong hình, sau khi mình lưu xuống local mình có hai function để kêu thằng Publisher để message vào Queue để hai anh chàng Consumer kia làm việc.
Ở đây mình dùng 3 connection và dùng 3 channel trên 3 connection đó, dùng 2 Exchange khác nhau để cho nó rõ ràng, các bạn có thể dùng 1 exchange duy nhất nếu các bạn muốn.
Cùng xem hai Consumer cuả mình có gì nào.
package consumer
import (
"encoding/json"
mystorage "github.com/dongnguyenltqb/go-rabbit/storage"
"github.com/dongnguyenltqb/go-rabbit/utils"
"github.com/streadway/amqp"
"os"
)
var C2 *amqp.Channel
var tasks_upload <- chan amqp.Delivery
func uploadWorker(pool <- chan amqp.Delivery){
for{
task := <- pool
var object mystorage.ObjectAddress
if err := json.Unmarshal(task.Body,&object); err != nil{
task.Reject(true)
utils.Logger("error",err)
continue
}
finished := make(chan bool)
go mystorage.UploadToGCloudStorage(object.FileName,finished)
if result := <- finished ; result == true {
task.Ack(false)
} else {
task.Reject(true)
}
}
}
func runUploadWorker(numWorker int){
for i:=1;i<numWorker;i++{
go uploadWorker(tasks_upload)
}
}
func InitUploadConsumer(){
conn,err := amqp.Dial(os.Getenv("AMQP_URL"))
C2,err = conn.Channel()
if err!=nil {
panic(err)
}
C2.QueueDeclare("UploadImageToGCloud",true,false,false,false,nil)
C2.QueueBind("UploadImageToGCloud","","UploadImage",true, map[string]interface{}{
"type":"image/jpeg",
"job":"upload",
})
tasks_upload,_ = C2.Consume("UploadImageToGCloud","UploadImage",false,true,false,false,nil)
go runUploadWorker(NumWorker)
}
Đầu tiên là upload_consumer, nó sẽ đăng kí lắng nghe trên UploadImage exchange và mỗi khi nào có tin nhắn mới nó sẽ dựa vào thông tin có trong tin nhắn đó để xử lí, nếu xử lí ko được thì nó lại lại và làm tiếp cái khác nếu có.
Tiếp theo là resize_consumer, cũng hoạt động tương tự chỉ khác là sau khi Resize xong nó lại gọi thằng Publisher ra nhờ Publiser gửi tin nhắn lên exchange rằng có cái gì đó mới cần dược Upload Consumer xử lí.
package consumer
import (
"encoding/json"
"fmt"
"github.com/disintegration/imaging"
mystorage "github.com/dongnguyenltqb/go-rabbit/storage"
"github.com/dongnguyenltqb/go-rabbit/utils"
"github.com/streadway/amqp"
"os"
"strings"
)
var C1 *amqp.Channel
var NumWorker int
func ResizeWorker(pool <-chan amqp.Delivery){
for{
task := <- pool
fmt.Println(utils.ApplyStyle("bold","yellow","Resizing image"))
var object mystorage.ObjectAddress
if err := json.Unmarshal(task.Body,&object);err != nil {
task.Reject(true)
utils.Logger("error",err)
continue
}
srcImage, err := imaging.Open("storage/image/"+object.FileName)
if err != nil {
task.Reject(true)
utils.Logger("error",err)
continue
}
dstImage200 := imaging.Resize(srcImage, 200, 0, imaging.Lanczos)
resizedFileName := "200@"+strings.TrimLeft(object.FileName,"/image/")
err = imaging.Save(dstImage200,"storage/image/"+resizedFileName)
if err != nil {
task.Reject(true)
utils.Logger("error",err)
continue
}
task.Ack(false)
resizedObject := mystorage.ObjectAddress{
FileName: resizedFileName,
}
go mystorage.PushTaskToExchangeUploadImage(resizedObject)
}
}
func runResizeWorker(numWorker int){
for i:=0;i<=numWorker;i++{
go ResizeWorker(tasks_resize)
}
}
var tasks_resize <- chan amqp.Delivery
func InitResizeConsumer(){
conn,err := amqp.Dial(os.Getenv("AMQP_URL"))
C1,err = conn.Channel()
if err!=nil {
panic(err)
}
C1.QueueDeclare("ResizeImage",true,false,false,false,nil)
C1.QueueBind("ResizeImage","","ProcessImage",true, map[string]interface{}{
"type":"image/jpeg",
"job":"resize",
})
tasks_resize,_ = C1.Consume("ResizeImage","ResizeImageWorker",false,true,false,false,nil)
go runResizeWorker(NumWorker)
}
Về cơ bản App sau này mình có thể clone app của mình ra thành nhiều thành phần nhỏ khác nhau và làm mỗi một việc như “ Handle Upload Form”, “Upload” và “Resize” chúng nó có thể giao tiếp với nhau dễ dàng qua RabbitMQ.
Các bạn có thể clone source code của mình ở đây và bình luận giúp mình chỗ nào cần cải thiện, nếu hay các bạn vỗ tay cho mình nhé.
12h11 đêm rồi, mình chắc cũng nên dừng bút tại đây, các ơn các bạn đã đọc bài. Hẹn gặp lại trong bài viết sau.
Có bao giờ bạn từng thắc mắc là chiếc máy tính mà bạn đang sử dụng có từ khi nào chưa? và hình dáng ban đầu của nó ra sao, các máy tính thời xưa trông sẽ như thế nào không?
Vâng ! Phải trải qua giai đoạn gần 2 thế kỉ hình thành, phát triển và tồn tại thì chúng ta mới có những chiếc máy tính mạnh mẽ mà gọn nhẹ như hiện nay đấy
Và hôm nay, hãy cùng Blog Chia Sẻ Kiến Thức tóm lược lại các mốc thời gian quan trọng trong quá trình phát triển của máy tính nhé.
#1. Mục đích người ta phát minh ra máy tính?
Xin khẳng định ngay với các bạn rằng, mục đích ban đầu của máy tính không phải là để giải trí, chơi game đâu nhé. Mà mục đích của nó là để tính toán sao cho nhanh nhất và hiệu quả nhất có thể.
Vào những năm 1880, dân số Mỹ nhiều đến mức phải mất hơn 7 năm để các nhà dân số tính toán và lập bảng kết quả điều tra dân số.
Chính vì thế mà nhu cầu về một chiếc máy có khả năng tính toán nhanh và chính xác là vô cùng quan trọng và cần thiết.
Lưu ý: đây chỉ là bài viết tóm lược các mốc thời gian được công bố, có thể sẽ không đầy đủ 100% nhưng nói chung là nó cũng cho chúng ta thấy được cái nhìn khái quát nhất về lịch sử hình thành của chiếc máy tính hiện đại như ngày nay. OK !
#2. Giai đoạn sơ khai, các máy tính “cơ học”
Năm 1801: Ông Joseph Marie Jacquard người Pháp, do nhu cầu muốn tối đa hóa tốc độ và tối ưu nguồn nhân công nên đã phát minh ra máy dệt sử dụng thẻ gỗ đục lỗ để tự động dệt các thiết kế vải.
=> Đây cũng chính là ý tưởng và mô hình cho chiếc máy tính đầu tiên.
Năm 1822: Charles Babbage – một nhà toán học người Anh đã có ý tưởng về một máy tính có thể điều khiển bằng hơi nước, có thể tính toán các bảng số.
Sau đó, ông đệ trình lên chính phủ Anh và đã được chính phủ Anh tài trợ cho ông kinh phí nghiên cứu và phát triển.
Tuy nhiên, có lẽ do những rào cản công nghệ thời bấy giờ mà dự án đã thất bại. Phải đến hơn một thế kỉ sau thì chiếc máy tính đầu tiên mới được ra đời, nhưng theo nhiều nguồn tin thì ông vẫn được xem như là “cha đẻ” của máy tính.
Năm 1890: Như đã đề cập ở trên, nhằm đáp ứng nhu cầu tính toán điều tra dân số. Ông Herman Hollerith đã thiết kế một hệ thống thẻ đục lỗ để tính toán cuộc điều tra dân số năm 1880, và chiếc máy này đã giúp hoàn thành công việc trong ba năm và tiết kiệm được hàng triệu đô cho chính phủ.
Và từ những gì đã làm được, cũng như mong muốn của ông trong tương lai thì ông đã thành lập ra một công ty – nó là tiền thân của tập đoàn IBM hiện nay.
Năm 1936: Nhà khoa học thiên tài trên rất nhiều lĩnh vực – Alan Turing trình bày khái niệm về một cỗ máy có khả năng tính toán bất cứ thứ gì có thể tính toán được. Các khái niệm cốt lõi của máy tính hiện đại dựa trên ý tưởng này của ông.
#3. Giai đoạn cận máy tính kỹ thuật số
Năm 1941: Atanasoff (người Mỹ) và sinh viên của ông (Clifford Berry), đã thiết kế ra một chiếc máy tính có khả năng giải quyết 29 phương trình cùng lúc.
Đây được xem là chiếc máy tính kỹ thuật số đầu tiên trên thế giới, và nó có khả năng lưu trữ thông tin trên bộ nhớ của chính nó.
Năm 1943 – 1944: Tại Đại học Pennsylvania (một trường đại học danh tiếng và lâu đời bậc nhất của nước Mỹ cho tới hiện tại), 2 giáo sư là John Mauchly và J. Presper Eckert cũng đã cho ra đời Electronic Numerical Integrator and Calculator (ENIAC).
Chiếc máy tính này có kích thước rất đồ sộ, chiếm hết một căn phòng với diện tích 6x12m, cao 2.4m. Với khả năng xử lý 5.000 phép tính/giây – nhanh hơn bất kì một máy móc nào thời bấy giờ.
#4. Giai đoạn của máy tính kỹ thuật số phát triển vũ bão
Năm 1947: William Shockley, John Bardeen và Walter Brattain – 3 con người này đã thay đổi cả thế giới.
Tại Bell Laboratories (Phòng thí nghiệm Bell) đã phát minh ra bóng bán dẫn. Có thể nói mọi thiết bị điện tử mà chúng ta đang dùng ngày nay là đều từ phát minh này mà có được.
Năm 1953: Con trai của Giám đốc điều hành IBM, Thomas Johnson Watson Sr đã phát minh ra IBM 701 EDPM để giúp cho Liên Hợp Quốc có thể dễ dàng theo dõi Triều Tiên trong chiến tranh.
Năm 1954: Để đáp ứng nhu cầu quốc phòng thì hệ thống phòng thủ tính toán khổng lồ SAGE đã được thiết kế với nhiệm vụ là để theo dõi rada thời gian thực. Hệ thống khổng lồ này nặng tới 300 tấn và chiếm diện tích cả một gian phòng.
Và cũng trong năm này thì ngôn ngữ lập trình FORTRAN (viết tắt của từ FORmula TRANslation) được phát triển bởi một nhóm lập trình viên tại IBM do John Backus dẫn đầu.
Năm 1958: Jack Kilby và Robert Noyce cho ra đời mạch tích hợp, được gọi là chip máy tính. Có thể nói đây là phát minh quan trọng bậc nhất trong ngành công nghiệp máy tính.
Cũng chính vì công trình vĩ đại này mà Jack Kilby đã nhận được giải Nobel Vật lý năm 2000.
Năm 1960: NEAC 2203 – một chiếc máy tính bán dẫn của hãng Nippon (NEC) được ra đời với mục đích cho các lĩnh vực kinh doanh, khoa học, ứng dụng kỹ thuật.
=> Và đây cũng là một trong những chiếc máy tính bán dẫn sớm nhất ở Nhật Bản.
Năm 1964: Nhà phát minh Douglas Engelbart đã công khai nguyên mẫu của máy tính hiện đại, với chuột và giao diện người dùng đồ họa (GUI).
Đây thực sự là một bước tiến giúp máy tính tiến gần hơn với người dùng phổ thông, khi mà trước đó máy tính chỉ được dùng cho mục đích khoa học và quân sự là chính.
Cũng vào năm 1964 thì IBM System/360 được giới thiệu là một chiếc máy tính có thể sử dụng được cho cả mục đích thương mại lẫn khoa học mà không cần nâng cấp phần mềm.
System/360 với phiên bản cao cấp hơn có vai trò lớn trong các sứ mệnh của con tàu vũ trụ Apollo của NASA khám phá vũ trụ thời đó.
Năm 1964: CDC 6600 ra đời bởi kiến trúc sư máy tính đại tài Seymour Cray, nó là bộ máy nhanh nhất trên thế giới vào thời điểm đó.
Và cho đến tận năm 1969, chính Cray đã phá vỡ kỉ lục đó với việc thiết kế ra “siêu máy tính” tiếp theo của ông.
Năm 1965: Công ty DEC cho ra đời DEC PDP-8, đây là chiếc máy tính mini đầu tiên được thương mại hóa thành công. DEC PDP-8 đã bán được hơn 50.000 chiếc thời bấy giờ.
Chúng có thể thực hiện mọi công việc mà System/360 có thể làm được, nhưng giá thành thì chỉ khoảng 16.000 USD, trong khi System/360 của IBM lên tới hàng trăm ngàn USD.
Năm 1969: Tại phòng nghiên cứu của Bell ( Bell Labs ) sản xuất UNIX, một hệ điều hành đa nền tảng hàng đầu tiên thế giới..
Được viết bằng ngôn ngữ lập trình C, UNIX sớm trở thành hệ điều hành được lựa chọn tại nhiều công ty lớn và các tổ chức chính phủ. Tuy nhiên, nó không được nhiều người dùng phổ lựa chọn, đơn giản bởi vì nó khá là phức tạp.
Năm 1970: Công ty Intel mới thành lập và đã công bố sản phẩm Intel 1103, và Dynamic Access Memory (DRAM) đầu tiên của họ.
Năm 1971: Kenbak-1 ra đời, sản phẩm này được coi là máy tính cá nhân đầu tiên trên thế giới nhưng nó sớm thất bại về mặt thương mại hóa, vì xử lí chậm chạp, không có bộ vi xử lý và không bán ra được nhiều.
Cũng trong thời gian này thì một lãnh đạo của một nhóm kỹ sư của IBM (có tên là Alan Shugart) đã phát minh ra “đĩa mềm”
Năm 1973: Một thành viên trong đội nghiên cứu của hãng Xerox (có tên Robert Metcalfe), đã phát triển ra Ethernet để kết nối nhiều máy tính và phần cứng khác.
Năm 1974 – 1977: Một loạt các máy tính cá nhân lẫn công ty ra đời như: Scelbi & Mark-8 Altair, IBM 5100, TRS-80 và PEToreore.
Năm 1975: Altair 8800 là bộ máy tính ra đời bởi MITS. Và cũng từ đây, 2 chuyên viên máy tính Paul Allen và Bill Gates đã đề nghị viết phần mềm cho Altair, với ý tưởng sử dụng ngôn ngữ BASIC mới.
Sau đó thì vào ngày 4 tháng 4, cả hai đã thành lập công ty phần mềm cho riêng họ, và đó chính là tập đoàn Microsoft bây giờ.
Năm 1976: Apple I được hình thành bởi Steve Wozniak, sau đó ông cùng hợp tác với Steve Jobs. Và Apple I cũng chính là chiếc máy tính đầu tiên có bảng mạch đơn.
Nói chung là Steve Jobs và Steve Wozniak đã đặt nền móng cho sự ra đời của máy tính Apple và cũng như đế chế Apple hiện tại (vào đúng ngày cá tháng 4).
Năm 1976: Cũng trong năm đó thì Cray-1 (một sản phẩm của kiến trúc sư máy tính Seymour Cray thiết kế) được đánh giá là chiếc máy tính mạnh mẽ nhất thời bấy giờ.
Mặc dù có giá lên tới 5 – 10 triệu USD thời bấy giờ nhưng vẫn rất đắt hàng. Do nó vượt trội hẳn so với các đối thủ khác trên thị trường thời điểm đó.
Năm 1977: TRS-80 của Radio Shack lần đầu tiên được thương mại với 3.000 máy, và chúng được bán rất chạy.
Năm 1977: Stave Jobs và Wozniak đã cho ra mắt Apple II tại hội chợ công nghệ West Coast Computer Faire đầu tiên.
Năm 1978-1979: VisiCalc – chương trình bảng tính trên máy tính đầu tiên đã ra đời. Việc xử lý văn bản đã trở nên dễ dàng hơn rất nhiều, chế chức năng in ấn đã được bổ sung.
Năm 1981: Acorn – máy tính cá nhân đầu tiên của IBM đã được giới thiệu. Acorn sử dụng con chip của Intel, chạy trên hệ điều hành MS-DOS của Microsoft, hai ổ đĩa mềm và màn hình màu tùy chọn.
Chiếc máy này đã thành công và thuật ngữ “PC” cũng đã trở nên thông dụng từ đây !
Năm 1981: Osborne 1 là chiếc máy tính di động được thương mại hóa đầu tiên, nó nặng tới 10,8kg và có giá dưới 2000 USD.
Năm 1983: Lisa của hãng Apple là chiếc máy tính cá nhân đầu tiên có GUI. Ngoài ra thì Lisa cũng có một menu sổ xuống và các icon biểu tượng. Mặc dù nó thất bại nhưng cuối cùng được phát triển thành Macintosh.
Năm 1983: Hewlett-Packard 150 ra đời. HP 150 là chiếc máy tính áp dụng công nghệ màn hình cảm ứng đầu tiên được thương mại hóa.
Kích thước màn hình cảm ứng là 9-inch, được trang bị các bộ thu và phát hồng ngoại ở xung quanh để phát hiện ra vị trí ngón tay của người dùng.
Năm 1985: Microsoft đã công bố hệ điều hành Windows. Đây là sự đáp trả của Microsoft đối với GUI của Apple.
Năm 1985: Tiên miền .com đầu tiên đã được đăng ký vào ngày 15 tháng 3.
Năm 1986: Công ty Compaq đã cho ra mắt Deskpro 386. Với kiến trúc 32-bit của nó cung cấp tốc độ tương đương với máy tính mainframe.
Năm 1990: Tim Berners-Lee – một nhà nghiên cứu tại CERN đã phát triển ra HTML (HyperText Markup Language), tạo ra World Wide Web (www).
Năm 1993: Đây được xem là khoảng thời gian mà máy tính có tiến bộ vượt bậc nhất, đó là nhờ bộ vi xử lý Pentium huyền thoại của Intel. Nó đã thúc đẩy việc sử dụng đồ họa và âm nhạc trên máy tính.
Năm 1994: Máy tính PC đã không còn dành cho công việc nữa, nó đã có thể trở thành chiếc máy giải trí với những tựa game thời đó như “Command & Conquer”, “Alone in the Dark 2”, “Theme Park”….
Năm 2001: Apple cho ra đời hệ điều hành Mac OS X, cung cấp khả năng đa tác vụ ưu tiên, cùng nhiều tính năng hay ho khác.
Ngay sau đó thì Microsoft cũng tung ra Windows XP, có GUI được thiết kế lại với nhiều thay đổi đáng kể.
Năm 2003: Thương mại hóa bộ xử lý 64-bit đầu tiên, Athlon 64 của AMD.
Năm 2006: Apple giới thiệu chiếc MacBook Pro thần thánh, một chiếc máy tính di động lõi kép dựa trên Intel đầu tiên, cũng như là iMac dựa trên Intel.
Năm 2009: Microsoft tung ra hệ điều hành Windows 7 với vô số các cải tiến đáng kể về trải nghiệm người dùng.
Năm 2011: Google phát hành Chromebook, máy tính xách tay chạy hệ điều hành Chrome OS do chính Google phát triển.
Năm 2015: Microsoft phát hành Windows 10 đến tay người dùng. Và cho đến nay, năm 2021 thì Windows 10 vẫn đang được cải tiến từng ngày.
Năm 2016: Chiếc máy tính lượng tử đầu tiên có thể lập trình lại đã được tạo ra. “Trước đây, chưa có bất kỳ nền tảng máy tính lượng tử nào có khả năng lập trình các thuật toán mới vào hệ thống của họ. Chúng thường được thiết kế riêng để giải quyết một thuật toán cụ thể,” theo lời Shantanu Debnath, nhà vật lý lượng tử và kỹ sư quang học tại Đại học Maryland, College Park.
Năm 2017: Phát triển một chương trình mới mang tên “Molecular Informatics” sử dụng các phân tử như máy tính. Anne Fischer, quản lý chương trình tại Văn phòng Khoa học Quốc phòng của DARPA, cho biết: “Hóa học cung cấp một tập hợp các tính chất phong phú mà chúng ta có thể khai thác để lưu trữ và xử lý thông tin một cách nhanh chóng và có thể mở rộng. Hàng triệu phân tử tồn tại, và mỗi phân tử có cấu trúc nguyên tử ba chiều độc đáo cũng như các biến số như hình dạng, kích thước hoặc thậm chí màu sắc. Sự phong phú này cung cấp một không gian thiết kế rộng lớn để khám phá các cách mới và đa giá trị để mã hóa và xử lý dữ liệu vượt ra ngoài các số 0 và 1 của các kiến trúc số hiện tại.”
Năm 2019: Một nhóm nghiên cứu tại Google trở thành những người đầu tiên chứng minh được “quyền tối thượng lượng tử” — tạo ra một máy tính lượng tử có thể thực hiện các tính toán vượt trội hơn so với máy tính cổ điển mạnh nhất. Họ mô tả chiếc máy tính này, có tên gọi “Sycamore,” trong một bài báo cùng năm trên tạp chí Nature. Đạt được lợi thế lượng tử – khi một máy tính lượng tử giải quyết vấn đề với các ứng dụng thực tế nhanh hơn máy tính cổ điển mạnh nhất – vẫn còn là một chặng đường dài.
Năm 2022: Siêu máy tính đầu tiên đạt mức exascale và cũng là nhanh nhất thế giới, Frontier, đã được đưa vào hoạt động tại Cơ sở Tính toán Lãnh đạo Oak Ridge (OLCF) ở Tennessee. Được xây dựng bởi Hewlett Packard Enterprise (HPE) với chi phí 600 triệu USD, Frontier sử dụng gần 10.000 CPU AMD EPYC 7453 với 64 lõi và gần 40.000 GPU AMD Radeon Instinct MI250X. Máy này đánh dấu kỷ nguyên của tính toán exascale, đề cập đến các hệ thống có thể đạt hơn một exaFLOP sức mạnh – được dùng để đo hiệu suất của hệ thống. Chỉ có một máy – Frontier – hiện có khả năng đạt được mức hiệu suất này. Hiện nó đang được sử dụng như một công cụ hỗ trợ khám phá khoa học.
#5. Đánh giá sự phát triển của máy tính
Như các bạn có thể thấy, từ năm 2001 cho tới nay thì ngành công nghiệp máy tính nói chung đã phát triển không ngừng.
PC đã trở thành thiết bị giải trí đa phương tiện, một thiết bị làm việc không thể thiếu cho tất cả mọi đối tượng, từ phổ thông cho tới doanh nghiệp hay chính phủ.
Sự phát triển của máy tính được song hành với sự phát triển của ngành bán dẫn, của những thế hệ mạch tích hợp ngày càng mạnh mẽ. Và tất nhiên, không thể không kể tới sự phát triển về phần mềm theo máy để đáp ứng các nhu cầu của con người.
Trong tương lai, khi giới hạn vật lý của bóng bán dẫn ngày càng gần, chúng ta sẽ chứng kiến những chiếc máy tính thế hệ mới – máy tính lượng tử. Không còn là bóng bán dẫn đơn thuần mà là từ những hạt cơ bản và tốc độ là gấp nhiều lần hiện nay.
Trong quá trình tổng hợp sẽ không tránh khỏi những thiếu sót, mong các bạn hãy thông cảm và nếu có bất kỳ ý kiến gì thì hãy để lại comment phía bên dưới nhé !
CV là thứ không thể thiếu khi apply vào các vị trí tuyển dụng tại Việt Nam, nghe CV thì rất quen nhưng bạn đã thật sự biết CV là gì và vì sao nó lại quan trọng trong quá trình ứng tuyển của bạn chưa? Cùng TopDev theo dõi bài viết dưới đây, chúng tôi sẽ giải đáp tất tần tật về CV và hướng dẫn cách viết CV xin việc gây ấn tượng với nhà tuyển dụng.
Tổng quan về CV
CV là gì?
CV là gì?
CV là viết tắt của cụm từ Curriculum Vitae xuất phát từ tiếng La-tinh, được dịch sang tiếng Anh là course of life. CV là bản ghi lại chi tiết về những sự kiện trong cuộc đời ứng viên, bao gồm quá trình học tập, thành tựu nghiên cứu, kinh nghiệm làm việc và các kỹ năng,…
CV còn có một tên gọi khác ở Việt Nam là hồ sơ xin việc (nhưng khác với bộ hồ sơ xin việc truyền thống). CV sẽ giúp nhà tuyển dụng có cái nhìn tổng quan về bạn. Từ đó quyết định bạn có phù hợp với vị trí họ tuyển dụng và có nên mời bạn đi phỏng vấn hay không.
CV nên bao gồm những gì?
Muốn gây ấn tượng, trước khi cố gắng tạo ra sự khác biệt bạn cần đảm bảo đã cung cấp đủ những gì nhà tuyển dụng cần. Các thông tin chia sẻ dưới đây sẽ cho bạn biết một CV xin việc cần có những gì:
1. Thông tin cá nhân
Vì có vai trò như một sơ yếu lý lịch chính vì thế ứng viên cần cung cấp đầy đủ các thông tin cá nhân cho nhà tuyển dụng. Các thông tin này thường sẽ bao gồm:
Họ và tên đầy đủ của bản thân
Ngày tháng năm sinh
Nơi sinh sống hiện tại
Số điện thoại liên lạc
Địa chỉ email
Các thông tin này thường được viết đầu tiên và ở trên cùng trong bố cục CV để nhà tuyển dụng dễ dàng quan sát được. Chẳng hạn địa chỉ nhà bạn quá xa với công ty thì có thuận tiện khi đi làm hay không, hoặc độ tuổi của ứng viên có đáp ứng được yêu cầu của công ty hay không… Nếu không thỏa mãn những điều kiện này, CV sẽ được bỏ qua mà không xem tiếp đến các thông tin tiếp theo.
Thông tin này bắt buộc phải xuất hiện trong tất cả mọi CV. Với trường hợp bạn là sinh viên mới tốt nghiệp chưa có kinh nghiệm làm việc thực tế tại một công ty ở vai trò chính thức nào thì các thông tin này nên được thay thế bằng kinh nghiệm tham gia các hoạt động khi còn ở trường đại học hoặc việc làm thêm.
Mục đích chính của phần thông tin về kinh nghiệm làm việc là để nhà tuyển dụng có thể dễ dàng quan sát và nắm bắt được những kinh nghiệm bạn sở hữu có đáp ứng được vị trí mà họ đang tuyển hay không. Chính vì thế hãy liệt kê những kinh nghiệm cần thiết thay vì liệt kê một cách dàn trải tất cả mọi thứ. Mục kinh nghiệm làm việc quá dài dòng và dàn trải nhiều thông tin sẽ không được nhà tuyển dụng đánh giá cao.
CV cần có những gì?
3. Trình độ học vấn và các chứng chỉ
Trong thông tin này, ứng viên nên đề cập đến việc mình đang học trường nào, đã tốt nghiệp hay chưa và chuyên ngành mình đã theo học. Ngoài ra, nếu đang theo học các khóa học chuyên môn có liên quan đến công việc cũng có thể đề cập đến trong CV như một cách để thể hiện năng lực của bạn.
Thông thường trong phần thông tin học vấn, ứng viên sẽ điền tên trường, ngành theo học và thời gian học (nên điền năm bắt đầu và năm tốt nghiệp). Nếu điểm GPA tốt nghiệp cao bạn hoàn toàn có thể thêm vào trong CV để tạo ấn tượng với nhà tuyển dụng.
Hoặc trong thời gian học, bạn có tham gia nghiên cứu khoa học hay thực hiện các đề án nghiệp vụ có tính chất phục vụ cho công việc mình đang ứng tuyển thì cũng có thể thêm vào trong CV. Một bằng cấp khác quan trọng không kém là chứng chỉ tiếng Anh và tin học. Ứng viên có thể điền thông tin chứng chỉ vào CV nếu cảm thấy cần thiết.
Về kỹ năng chuyên môn, có một sai lầm mà nhiều người mắc phải là tự đưa ra các kỹ năng và thang điểm cho kỹ năng đó của mình. Thực tế thì việc làm này không thể hiện tính khách quan và không có bất cứ tiêu chuẩn nào cho việc chấm điểm đó của bạn cả. Vậy nên hãy từ bỏ cách trình bày kỹ năng như thế này trong CV của mình.
Thay vào đó, hãy liệt kê những kỹ năng quan trọng và theo bạn, là cần thiết cho công việc mà bạn đang ứng tuyển. Chẳng hạn, với vị trí ứng tuyển liên quan đến công việc của lập trình viên, bạn nên trình bày các kỹ năng liên quan đến kỹ thuật như ngôn ngữ lập trình có thể sử dụng,… Kết hợp thêm với một số kỹ năng mềm khác sẽ giúp bạn dễ dàng hơn trong việc chinh phục nhà tuyển dụng.
Nội dung này có thể được chia sẻ ngắn gọn trong vài dòng để nhà tuyển dụng có thể thấy được mục tiêu ngắn hạn và dài hạn của bạn trong công việc này là gì, định hướng phát triển của bạn trong tương lai ra sao.
Tuy nhiên, cũng có nhiều ứng viên lựa chọn không chia sẻ về mục tiêu công việc trong CV. Điều này hoàn toàn phụ thuộc vào mong muốn của bạn, nếu CV đã quá dài thì có thể lược bỏ bớt phần thông tin này và trao đổi chi tiết hơn khi đến với buổi phỏng vấn.
Hiện nay, có khá nhiều công cụ tạo CV miễn phí khác nhau mà ứng viên có thể tham khảo. Với TopDevCV, các ứng viên trong lĩnh vực CNTT có thể dễ dàng tạo được cho mình chiếc CV với đầy đủ các thông tin cần thiết với vai trò là một lập trình viên.
Vai trò của CV là gì?
Có thể nói CV đóng vai trò chủ đạo khi đi xin việc cũng như tuyển dụng. Vì nếu không có sự hiện diện của CV thì các nhà tuyển dụng không thể nắm được thông tin gì về người ứng tuyển. Vì thế, CV là giấy tờ mang thông tin có vai trò rất quan trọng đối với cả 2 phía người ứng tuyển và người tuyển dụng… Hiện nay, nếu người ứng tuyển không thể cung cấp cv; thì 100% người tuyển dụng sẽ không quan tâm ngay từ đầu để tránh mất thời gian với ứng viên này.
Một đơn xin việc hoàn chỉnh sẽ không thể thiếu 1 thư xin việc (cover letter) và CV. Có một vài công ty sẽ yêu cầu thêm một vài thông tin xác nhận từ địa phương. Nhưng có một số thì không. Những thông tin đó sẽ được bổ sung sau khi được trúng tuyển vị trí làm việc; chứ nó không thật sự cần thiết khi chỉ vừa mới đi xin việc.
Viết một CV ấn tượng là bước quan trọng để thu hút sự chú ý của nhà tuyển dụng và tạo ra cơ hội cho bạn trong quá trình tìm kiếm việc làm. Dưới đây là hướng dẫn các bước để viết một CV chuyên nghiệp và ấn tượng:
1. Thông tin cá nhân + vị trí ứng tuyển
Tên đầy đủ: Đặt ở vị trí trung tâm và sử dụng font chữ lớn hơn các phần khác.
Vị trí ứng tuyển: Càng cụ thể càng tốt (tránh ghi chung chung: Thực tập sinh, Nhân viên văn phòng,…)
Hình ảnh: Nếu bạn có một tấm ảnh chuyên nghiệp và tươi tắn có thể gây ấn tượng tốt với nhà tuyển dụng (nếu bạn không tự tin về hình ảnh thì phần này không bắt buộc).
Thông tin liên lạc: Bao gồm địa chỉ email, số điện thoại, và địa chỉ nhà (có thể không cần quá chi tiết). Đảm bảo email chuyên nghiệp.
Liên kết mạng xã hội chuyên nghiệp: LinkedIn hoặc GitHub (nếu có).
Phần thông tin mở đầu CV chuẩn
2. Tóm tắt mục tiêu nghề nghiệp
Viết một đoạn tóm tắt ngắn gọn (2-3 câu) về kinh nghiệm, kỹ năng chính và mục tiêu nghề nghiệp của bạn. Tập trung vào những gì bạn có thể mang lại cho nhà tuyển dụng.
Ví dụ: Tôi là một chuyên gia phần mềm với 5 năm kinh nghiệm trong lĩnh vực phát triển ứng dụng web. Tôi có kỹ năng chuyên môn về JavaScript, Python và có khả năng làm việc nhóm xuất sắc. Mục tiêu của tôi là áp dụng kỹ năng và kinh nghiệm để gắn bó và đóng góp vào sự phát triển của công ty.
3. Kinh nghiệm làm việc
Liệt kê theo thứ tự thời gian ngược: Bắt đầu từ công việc hiện tại hoặc gần đây nhất.
Thông tin công việc: Bao gồm tên công ty, vị trí công việc, thời gian làm việc và mô tả công việc.
Thành tựu và kết quả cụ thể: Nêu rõ các thành tựu và kết quả bạn đạt được. Sử dụng số liệu và con số để làm nổi bật hiệu quả công việc (ví dụ: “Tăng doanh số bán hàng lên 20% trong 6 tháng”).
Ví dụ:
Chuyên viên Phát triển Phần mềm - Công ty ABC
01/2020 - Hiện tại
- Phát triển và duy trì các ứng dụng web sử dụng JavaScript và Python.
- Tăng hiệu suất hệ thống lên 30% thông qua tối ưu mã và nâng cấp cơ sở dữ liệu.
- Dẫn dắt nhóm 5 người trong dự án triển khai hệ thống CRM mới, hoàn thành trước thời hạn 2 tháng.
Nhân viên IT - Công ty XYZ
06/2017 - 12/2019
- Quản lý và bảo trì hệ thống mạng và máy chủ.
- Giảm thời gian sự cố hệ thống xuống 50% bằng cách cải tiến quy trình và công cụ giám sát.
4. Học vấn
Thông tin chi tiết: Tên trường, bằng cấp, chuyên ngành và thời gian học.
Thành tích học tập: Nếu có thành tích nổi bật như học bổng, giải thưởng hoặc điểm GPA cao, hãy liệt kê chúng.
5. Kỹ năng
Kỹ năng chuyên môn: Liệt kê các kỹ năng liên quan trực tiếp đến công việc bạn đang ứng tuyển (ví dụ: kỹ năng lập trình, kỹ năng phân tích dữ liệu).
Kỹ năng mềm: Bao gồm kỹ năng giao tiếp, làm việc nhóm, quản lý thời gian, v.v.
6. Chứng chỉ và khóa học
Chứng chỉ chuyên môn: Liệt kê các chứng chỉ liên quan đến công việc (ví dụ: chứng chỉ PMP, chứng chỉ Google Analytics).
Khóa học: Bao gồm các khóa học trực tuyến hoặc đào tạo liên quan mà bạn đã hoàn thành.
7. Dự án
Dự án cá nhân hoặc nhóm: Nêu rõ các dự án mà bạn đã tham gia hoặc thực hiện, mô tả ngắn gọn về mục tiêu dự án và kết quả đạt được.
Công nghệ và kỹ thuật sử dụng: Liệt kê các công nghệ, công cụ và kỹ thuật bạn đã sử dụng trong dự án.
8. Hoạt động ngoại khóa và tình nguyện
Hoạt động liên quan: Bao gồm các hoạt động ngoại khóa, câu lạc bộ, tổ chức tình nguyện mà bạn đã tham gia và có liên quan đến công việc.
9. Trình độ ngoại ngữ
Liệt kê rõ các ngôn ngữ bạn biết và mức độ thành thạo của bạn, kèm theo thông tin về chứng chỉ bạn đạt được như IELTs 7.0 hay tiếng Nhật N4,… mục này có thể là điểm cộng cực kì lớn nếu bạn apply vào các vị trí cần ngoại ngữ hoặc công ty nước ngoài.
Đầu tiên, bạn nên chú ý những nền tảng thông tin về kinh nghiệm đặc thù của vị trí mà bạn ứng tuyển nên được viết kĩ càng. Và tất nhiên, nó cần nổi bật hơn các phần kinh nghiệm khác. Ví dụ nếu bạn ứng tuyển vị trí kỹ sư lập trình, thì bạn nên sử dụng mẫu cv lập trình được thiết kế đặc thù; chỉ đưa những kinh nghiệm liên quan đến vị trí lập trình viên vào.
Đặc biệt đối với những công ty bạn chỉ làm ngắn hạn dưới 6 tháng thì đừng nên viết vào cv nhé. Vì nhà tuyển dụng sẽ nghĩ bạn là người thường xuyên nhảy việc trong thời gian ngắn. Và chắc hẳn đó sẽ đem đến ấn tượng xấu cho họ.
Ưu tiên các kỹ năng cần thiết
Việc ưu tiên viết kỹ năng liên quan đến vị trí ứng tuyển đầu tiên sẽ giúp nhà tuyển dụng dù chưa đọc hết cv của bạn. Nhưng cũng 1 phần nào hiểu được bạn đã từng có kinh nghiệm và phù hợp ở vị trí này.
Bên cạnh đó bạn nên nhớ, hãy luôn trung thực với bất cứ thông tin nào mà bạn cung cấp trong cv nhé. Rất khó có thể qua mặt đc các nhà tuyển dụng. Họ đã có kinh nghiệm tuyển dụng qua hàng trăm người . Việc bạn nói dối sẽ rất dễ lộ tẩy trước cái nhìn của họ.
Các mẫu cv online thường chỉ gói gọn trong 1 mặt giấy A4, thông tin liên hệ, kinh nghiệm, kỹ năng nên được tóm tắt hàm xúc, đủ ý nhất có thể. Tránh viết lan man, kể lể dài dòng gây khó hiểu làm HR không hiểu bạn thật sự giỏi ở mảng nào.
Trong phần hình ảnh cá nhân được đính trong cv bạn nên sử dụng hình có tông màu sáng sủa, rõ ràng mặt mũi; không dùng hình chụp tự sướng và đặc biệt là bạn phải dùng hình chính chủ nhé!
Chú trọng đến email rất quan trọng!
Cả email của bạn cũng nên dùng tên thật chứ đừng dùng các email thời “trẻ trâu” của bạn. Cách viết email xin việc cũng rất quan trọng. Bạn không nên đề cập quá nhiều thông tin đã trong email vì những thông đó đã có trong CV.
Email chỉ nên là 1 đoạn giới thiệu bạn biết đến tin tuyển dụng như thế nào. Bạn cảm thấy bạn phù hợp với vị trí của công ty ra sao. Sau đó đính kèm file CV tiếng Anh hoặc tiếng Việt tùy yêu cầu công ty; hoặc nếu công ty không ghi rõ yêu cầu thì bạn có thể đính kèm cả 2 phiên bản cv tiếng Anh và Việt.
Sau bài viết các bạn đã hiểu cv là gì chưa nào? Tất cả những ý trên là câu trả lời cho câu hỏi cv là gì và kèm thêm các tips hiệu quả để các bạn có thể hoàn thiện cv của chính mình và gây được ấn tượng với nhà tuyển dụng.
Quan tâm đến sự trải nghiệm gián tiếp
Nếu là những người mới, có thể chiếc CV cho sinh viên IT mới ra trường (CV IT student) dường như còn quá “non” để đủ sức cạnh tranh. Tuy nhiên, kinh nghiệm nhiều hay ít không quan trọng. Bạn vẫn có thể tạo được lợi thế nếu có sự chuẩn bị khoa học nhất.
Cách ứng viên nhận biết về sự trải nghiệm của bản thân rất quan trọng.
Thách thức lớn nhất đối với các ứng viên nằm ở vấn đề kinh nghiệm. Thế đâu là giải pháp hoàn hảo cho việc xoay chuyển các thách thức này?
Nếu là một ứng viên mới, đừng e ngại về năng lực. Bạn hãy liệt kê những công việc tình nguyện, hoặc các dự án về công nghệ mà bạn/team đã thực hiện, cộng tác,… Ngoài ra, nếu có các sản phẩm khoa học về ngành IT hay đã từng thực tập; làm báo cáo về một vấn đề chuyên sâu nào đó thuộc lĩnh vực IT, hãy tự tin chia sẻ với nhà tuyển dụng.
Đó được gọi là trải nghiệm gián tiếp. Tức sự cộng hưởng về mức độ am hiểu của ứng viên về một khía cạnh có liên quan đến việc giải quyết các vấn đề mà nhà tuyển dụng đặt ra.
Bạn phải tin rằng bạn đang dẫn dắt nhà tuyển dụng đi đúng hướng. Đồng thời, sự lựa chọn thông minh từ các trải nghiệm cá nhân sẽ phản ánh tính xác thực; khả năng phân tích về kiến thức và tiềm năng phát triển của bạn.
Văn phong ngôn ngữ thật sự là điểm nhấn!
Nếu một CV sở hữu cách định dạng – bố cục trình bày (format và visual), tổ chức nội dung (content) đầy đủ, thu hút thì chưa chủ để tạo nên một CV IT chuyên nghiệp. Điểm nhấn quan trọng nhất nằm ở văn phong ngôn ngữ.
Văn phong ngôn ngữ có giá trị quan trọng đối với chất lương CV IT.
Không một nhà tuyển dụng nào dành 5 phút để đọc một CV chứa các câu cú dài ngoằn, phức tạp. Thậm chí, cách viết quá hời hợt; không có sự hiểu biết về văn viết cơ bản sẽ khiến CV của bạn bị out ngay lập tức.
Cách diễn đạt trong CV cần rõ ràng, tránh mơ hồ và thiếu khả thi. Chẳng hạn, bạn ứng tuyển vị trí về Mobile App Developer, thì tính tư duy mạch lạc trong CV IT Developer được nhà tuyển dụng rất quan tâm. Đừng biến CV của bạn trở nên khó đọc, khó hiểu và không có giá trị.
Lời kết
Hãy đọc lại thông tin trong CV để chắc chắn rằng nội dung đều được liên kết với nhau một cách tốt nhất. Chính việc kiểm tra sẽ giúp CV của bạn chỉn chu hơn.
Một điều quan trọng nữa là bạn có thể cập nhật những nội dụng mới. Đâu là điểm mạnh – điểm yếu để định hướng truyền tải nội dung trong CV IT Developer một cách hợp lý. CV cần được bạn update lại nếu bạn có những thay đổi tốt hơn trong hành trình nghề nghiệp. Đó có thể là các kinh nghiệm mới, các dự án với quy mô lớn hơn. Hãy đầu tư cho CV để sẵn sàng cho cuộc chơi tuyển dụng bất cứ lúc nào!