Home Blog Page 74

Chia sẻ 6 cách sửa lỗi bàn phím máy tính bị lag, phản hồi chậm

sửa lỗi bàn phím
Chia sẻ 6 cách sửa lỗi bàn phím máy tính bị lag, phản hồi chậm

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

Bạn đã bao giờ cảm thấy khó chịu với bàn phím mà bạn đang gõ chưa, nhất là đối với bàn phím rời (kết nối với máy tính thông qua Bluetooh) thì hay có hiện tượng giật, lag và delay nhẹ. Tức là bạn gõ được một lúc rồi thì chữ mới hiện ra ấy.

Tuy nhiên, trước khi đến với những cách khắc phục bên dưới thì bạn cần phải đảm bảo rằng nguyên nhân không phải đến từ những lỗi khác. Bởi đôi khi máy tính của bạn bị chậm cũng là nguyên nhân khiến bàn phím của bạn bị delay.

Vậy nên, hãy thử khởi động lại máy tính và kiểm tra lại bàn phím một lần nữa xem sao, hoặc nếu có sẵn một cái bàn phím khác thì có thể kết nối thử xem có bị hiện tượng tương tự như vậy không.

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

#1. Tắt tính năng Filter Keys

Filter Keys có cách hoạt động tương tự Sticky Keys. Nói một cách dễ hiểu thì Filter Keys là khả năng tiếp cận giúp bạn điều chỉnh phản hồi của bàn phím khi thao tác tổ hợp phím lặp lại đi lặp lại sẽ được bỏ qua. Đây có thể là nguyên nhân gây ra độ trễ cho bàn phím. Bạn có thể tắt Filter Keys bằng cách sau:

+ Bước 1: Mở Windows Settings lên bằng cách nhấn tổ hợp phím Win + I.

cach-giam-do-tre-ban-phim-tren-windows (1)

+ Bước 2: Bạn tìm đến tính năng Ease of Access => và bấm chọn tính năng này.

cach-giam-do-tre-ban-phim-tren-windows (2)

+ Bước 3: Bạn vào tab Keyboard => sau đó ở tùy chọn Use Filter Keys, bạn chọn OFF.

cach-giam-do-tre-ban-phim-tren-windows (3)

#2. Thay đổi thuộc tính bàn phím

Vâng, thay đổi thuộc tính bàn phím cũng là một cách để giúp bạn giải quyết vấn đề bị delay khi gõ phím.

+ Bước 1: Bạn nhấn tổ hợp phím Win + R để mở hộp thoại Run => sau đó nhập lệnh control keyboard => và bấm Enter để mở Keyboard Properties.

cach-giam-do-tre-ban-phim-tren-windows (8)

+ Bước 2: Ở khu vực Character repeart có hai thanh trượt là Repeart delay và Repeart rate. Bạn hãy điều chỉnh lại mức độ của 2 thanh trượt này và test thử bằng cách viết chữ vào ô bên dưới.

cach-giam-do-tre-ban-phim-tren-windows (9)

+ Bước 3: Sau khi tìm thấy mức Repeart delay và Repeart rate “lí tưởng” thì bạn bấm Apply => và OK để kết thúc. Đây thực chất là cách điều chỉnh tốc độ chuột nhé các bạn !

#3. Sử dụng tính năng Keyboard Troubleshooter

Windows cung cấp cho chúng ta một số công cụ hỗ trợ khắc phục sự cố trong quá trình sử dụng Windows 10, trong đó có cả công cụ phát hiện và sửa lỗi liên quan đến bàn phím. Vậy nên, nếu bạn đang gặp vấn đề về bàn phím thì không có lý do gì chúng ta lại bỏ qua công cụ này cả.

+ Bước 1: Mở Windows Settings lên bằng cách sử dụng tổ hợp phím Win + I trên bàn phím.

+ Bước 2: Tìm đến phần Update & Security => và chọn tính năng Troubleshoot.

cach-giam-do-tre-ban-phim-tren-windows (10)

+ Bước 3: Sau đó bạn bấm vào Additional troubleshooters, bạn tìm và bấm chọn Keyboard => chọn tiếp Run the troubleshooter để Windows thực hiện quá trình Fix lỗi của nó.

cach-giam-do-tre-ban-phim-tren-windows (11)

#4. Cập nhật lại Driver bàn phím

Đôi khi lỗi bàn phím bị trễ tín hiệu cũng có thể do driver bàn phím của nó đã lỗi thời, hoặc bị xung đột. Để cập nhật lại driver, bạn làm như sau:

+ Bước 1: Nhấn tổ hợp phím Win + X => sau đó nhấn vào Device Manager.

Hoặc một cách khác là nhấn chuột phải vào This PC trên màn hình Desktop => chọn Manage => chọn Device Manager.

cach-giam-do-tre-ban-phim-tren-windows (4)

+ Bước 2: Bạn tìm đến driver bàn phím => sau đó nhấp đúp chuột vào nó.

cach-giam-do-tre-ban-phim-tren-windows (5)

+ Bước 3: Bạn vào tab Driver => sau đó nhấn vào Update Driver.

cach-giam-do-tre-ban-phim-tren-windows (6)

+ Bước 4: Chọn Search automatically for drivers.

cach-giam-do-tre-ban-phim-tren-windows (7)

+ Bước 5: Đợi một lúc để Update Driver (nếu có).

NOTE: Nếu cách trên không có tác dụng thì bạn nên Update Driver thông qua Windows Update, hoặc tham khảo bài viết hướng dẫn cách update driver cho máy tính chuẩn nhất nhé.

  12 loại bàn phím cho lập trình viên (Phần 1)
  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"

#5. Đối với bàn phím không dây

Đây là cách sửa lỗi với bàn phím không dây. Nếu bạn sử dụng bàn phím có dây thì hãy bỏ qua cách này nhé.

cach-giam-do-tre-ban-phim-tren-windows (1)

+ Thay pin

Có thể bàn phím bị delay hoặc viết không ra chữ là do Pin đã cạn kiệt. Thay pin bàn phím hoặc sạc Pin cho bàn phím và thử lại xem vấn đề có được giải quyết không.

+ Kiểm tra kết nối

Bạn hãy thử gắn lại USB Receiver của bàn phím vào một khe USB khác. Nếu có thể, hãy đặt bàn phím gần với máy tính của bạn để đảm bảo kết nối được tốt nhất.

#6. Thay bàn phím mới

Và cuối cùng, nếu như đã thử hết cách rồi, và bạn cũng đã thử mang bàn phím đó kết nối sang một máy tính khác nhưng vẫn bị hiện tượng như vậy thì khả năng cao là bàn phím bị lỗi rồi. Bạn vui lòng xuống tiền mua một em bàn phím khác nhé

#7. Lời kết

Ok, trên đây là 5 cách giúp bạn kiểm tra và sửa lỗi bàn phím máy tính khi bị trễ, bị delay hiệu quả nhất. Ngoài những cách mà mình chia sẻ bên trên ra, nếu bạn còn biết thêm phương pháp nào hiệu quả khác nữa thì đừng quên chia sẻ lại cho mọi người thông qua khung comment bên dưới nhé.

CTV: Hoàng Tuấn – Blogchiasekienthuc.com

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

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

Làm thế nào để Test Jersey Rest API với JUnit?

test jersey rest api
Làm thế nào để Test Jersey Rest API với JUnit?

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

Trong bài này tôi sẽ hướng dẫn các bạn cách viết Unit Test để test Jersey REST API sử dụng Jersey Test.

Một số kiến thức bạn cần nắm trước khi xem phần tiếp theo của bài viết này:

Test REST API cần test những gì?

Khi test một resource REST API, thông thường có một vài thứ cần test như sau:

  • HTTP response code : 200 OK, 201 Created, 204 NO Content, …
  • HTTP headers trong response: Content-Type, Content-Encoding, Content-Length, Content-Language, …
  • Payload (JSON, XML).
  Giới thiệu JUnit
  Liệu tôi có làm Junior Developer "mãn kiếp"?

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

Tạo Jersey Project

Tương tự như các bài viết trước, chúng ta sẽ tạo Jersey project với cấu trúc như sau:

Thêm thư viện Jersey test sau vào file pom.xml:

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.test-framework.providers/jersey-test-framework-provider-grizzly2 -->         <dependency>             <groupId>org.glassfish.jersey.test-framework.providers</groupId>             <artifactId>jersey-test-framework-provider-grizzly2</artifactId>             <version>2.29</version>         </dependency>

Xây dựng Jersey Rest API

Giả sử chúng ta có các API sau:

Jersey implement các API như sau:

package com.gpcoder.api;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.SecurityContext;

import com.gpcoder.model.Order;

// URI:
// http(s)://:(port)/// // http://localhost:8080/api/orders
@Path("/orders")
public class OrderService {

@GET
@Path("/{id}")
public Response get(@PathParam("id") int id) {
Order order = new Order();
order.setId(1);
order.setName("gpcoder");
return Response.ok(order).build();
}

@POST
public Response insert(Order order, @Context SecurityContext securityContext) {
int newOrderId = 999;
return Response.status(Status.CREATED).entity(newOrderId).build();
}

@PUT
@Path("/{id}")
public Response update(@PathParam("id") int id, Order order) {
return Response.ok().build();
}

@DELETE
@Path("/{id}")
public Response delete(@PathParam("id") int id) {
return Response.status(Status.NO_CONTENT).build();
}
}

Test Jersey Rest API với JUnit và JerseyTest

Để test Jersey REST API chúng ta sẽ sử dụng thư viện JUnit Test và Jersey Test .

package com.gpcoder.api;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

import com.gpcoder.model.Order;

public class OrderServiceTest extends JerseyTest {

@Override
public Application configure() {
return new ResourceConfig(OrderService.class);
}

@Test
public void testGetById() {
Response response = target("/orders/1").request().accept(MediaType.APPLICATION_JSON).get();
assertEquals("Should return status 200", 200, response.getStatus());
assertNotNull("Should return user object as json", response.getEntity());
assertEquals("Http Content-Type should be: ", MediaType.APPLICATION_JSON,
response.getHeaderString(HttpHeaders.CONTENT_TYPE));
assertThat("Should return new order contains gpcoder string",
response.readEntity(String.class), containsString("gpcoder"));
}

@Test
public void testCreate() {
Order order = new Order(1, "gpcoder");
Response response = target("/orders").request().post(Entity.entity(order, MediaType.APPLICATION_JSON));
assertEquals("Should return status 201", 201, response.getStatus());
assertNotNull("Should return new order id", response.readEntity(Integer.class));
}

@Test
public void testUpdate() {
Order order = new Order(1, "gpcoder edited");
Response response = target("/orders/1").request().put(Entity.entity(order, MediaType.APPLICATION_JSON));
assertEquals("Should return status 200", 200, response.getStatus());
}

@Test
public void testDelete() {
Response response = target("/orders/1").request().delete();
assertEquals("Should return status 204", 204, response.getStatus());
}
}

Giải thích đôi chút về chương trình trên:

  • Đầu tiên, chúng ta tạo một class Test extend từ JerseyTest. Đây là bắt buộc nếu muốn test JAX-RS và Jersey-based applications sử dụng Jersey test framework.
  • Override phương thức configure() : chỉ định resource cần test.
  • Tiếp theo viết các method JUnit test.
  • Để call các REST API, chúng ta sẽ sử dụng phương thức target()request() để tạo WebTarget, Builder tương tự như cách sử dụng Jersey Client.
  • Cuối cùng gửi các request thông qua các phương thức: post()get()put()delete().

Trên đây là một số hướng dẫn cơ bản để test REST API sử dụng thư viện Jersey test. Trong bài viết tiếp theo, tôi sẽ hướng dẫn các bạn một thư viện khác rất mạnh mẽ để test web service là REST Assured.

Tài liệu tham khảo:

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

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

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

Vì sao feedback rất quan trọng?

sự quan trọng của feedback
Vì sao feedback rất quan trọng?

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

Có một điều chắc các bạn cũng nhận ra, là khi làm việc với nhiều khách hàng Âu Mỹ hay Nhật, họ thường rất chịu khó đưa ra lời khen ngợi khi chúng ta làm gì đó tốt, thậm chí là chưa tốt, và họ cũng không ngần ngại chỉ trích hay góp ý khi có điều gì đó ngứa tai gai mắt.

Đây là một kĩ năng communication rất quan trọng. Gọi là Giving Feedback.

  10 Công cụ Go-To Tech dành riêng cho các Software Developer
  10 kênh Youtube học lập trình không thể bỏ qua dành cho Junior Web Developer / Designer

Xem thêm tuyển dụng C++ hấp dẫn trên TopDev


Feedback có thể hiểu là đưa ra ý kiến phản hồi cho một ai đó về một cái gì đó sau một chuyện gì đó.

Có 3 loại feedback thường thấy, đó là:

  • Positive Feedback: phản hồi dương tính, à nhầm mang tính tích cực, đưa ra để cho đối phương biết mình ghi nhận những cố gắng của họ, rằng đang làm tốt một việc gì đó, khích lệ họ để keep it up.
  • Constructive Feedback: phản hồi mang tính xây dựng, đưa ra với mục đích cho đối phương biết hành động của họ cần phải thay đổi.
  • Destructive Feedback: đây là thể loại constructive feedback phiên bản lỗi, được đưa ra một cách vội vã thiếu tế nhị, không đúng nơi đúng chỗ, hoặc đúng người nhưng sai thời điểm. Cũng là loại feedback phổ biến nhất ở trên đường, cũng như ở trên mạng. Tác dụng của nó là zero, còn tác hại thì vô cùng. Mình nghĩ người ta hay đưa ra kiểu feedback này chỉ vì ngứa mồm. Ở nhiều nơi mà cuộc sống khắc nghiệt, thì người đưa ra feedback có khả năng nhận được gói mát xa tẩm quất miễn phí chỉ cần trả tiền viện phí.

Ví dụ ở đoạn mở bài có nhắc tới, bạn làm gì cũng đc khách hàng khen, kể cả trễ deadline, thì đó gọi là positive feedback. Khi đồng đội mình hoàn thành dự án và launch thành công thì các sếp thường mở launch party và đọc tên từng người để ghi nhận công lao, đó là positive feedback. Coi Rap Việt ta thường thấy các bạn thí sinh shout out to my teacher Binz hay to anh em homie DCOD thì đó cũng là positive feedback.

Khi bạn thấy một ai đó làm gì sai, bạn muốn họ sửa, hoặc bạn tìm ra một con bug của một phần mềm nào đó và bạn viết bug report, bạn muốn đưa ra một ý tưởng gì đó để cải thiện, cũng lại coi Rap Việt bạn thấy Binz hay đưa ra phân tích về flow, vần của thí sinh, hay bạn thấy anh em WeBuild đưa ra feedback là ko biêt bao giờ huytd lại drop project, phần lớn trong số đó là constructive feedback mặc dầu tùy theo cách đưa ra feedback, nó sẽ trở thành destructive feedback.

Vậy thì phải đưa ra feedback như thế nào?

Có 2 yếu tố quan trọng khi đưa ra feedback đó là:

  • Be specific: đưa ra feedback đúng nơi đúng chỗ và đúng nội dung, và feedback như nào để người ta có thể take action được. Bạn không nên thấy một người mới start một cái side project và bay vào nói “Để xem khi nào anh drop”, vì nó ko add thêm value gì cho anh ấy cả, và khi nghe feedback như thế thì bạn expect họ sẽ làm gì?
  • Be timely: Thường thì real time feedback là tốt nhất, nhưng nếu tình thế ko cho phép thì cũng nên đưa ra feedback trong vòng 48 tiếng đồng hồ (ví dụ các bạn gái khi thấy người yêu mãi chơi game ko lo xếp quần áo, thì thay vì chạy tới rút dây máy PS5, nên bình tĩnh chờ người ta đánh xong ván đã, rồi hãy bắt úp mặt vô tường quỳ gối, nhưng cũng đừng nên chờ 1 tuần sau mới lôi ra nhắc lại chuyện cũ để rồi bị nói là nắng mưa vô cớ).

Để đưa ra feedback một cách tốt hơn, người ta nghĩ ra rất nhiều mô hình, các bạn có thể search thêm với từ khóa “Feedback Model”, hoặc đọc thêm tại đây hoặc đây.

Nhìn chung, các mô hình này đều xoay quanh 4 yếu tố:

  • Context: Nói về tình huống khi bạn nhìn thấy sự việc xảy ra.
  • Behavior: Nói về hành vi của những người liên quan đế vấn đề bạn đang feedback. Nói một cách khách quan nhất, và đừng có đánh giá gì về hành động đó cả.
  • Impact: Nói về ảnh hưởng mà hành động đó gây ra, và nó tác động đến bạn hoặc những người xung quanh như nào.
  • Follow Up: Đưa ra gợi ý về những gì người nhận feedback cần hoặc nên làm.

Ví dụ, bạn đang review code và phát hiện ra một vấn đề gì đó nên sửa:

  • “Code như cức, senior rồi mà còn code như này à?!” – Destructive feedback
  • “Tôi thấy chỗ này bạn xài let với const hơi lộn xộn, nó không ảnh hưởng gì nhiều về mặt logic nhưng làm vậy code style sẽ trở nên thiếu đồng nhất, tôi nghĩ bạn nên sửa hết về let, ý bạn sao?” – Constructive feedback

Một ví dụ khác, bạn Tèo vừa bỏ ra 1 ngày trời để setup mấy cái github actions giúp tự động chạy unit test trên mỗi PR của team, giúp nâng cao chất lượng code của cả team, là một teammate, bạn có thể làm gì?

  • Lên slack và post: “Shout out to my Tèo homie, cái github actions tự động chạy test của bạn ấy giúp cho cả team mình thấy yên tâm hơn khi fix code. Keep it up man!” – Positive feedback
  • Im lặng ko nói gì – No feedback = Destructive feedback, đến kì lương sau thì ko ai thấy Tèo đi làm nữa.

Một ví dụ khác nữa, lên WeBuild thấy một bạn thành viên mới post lên rằng: “Hi @channel, mình là mem mới, rất vui được làm quen với các bạn”, phản ứng của mọi người là:

  • Đồng loạt thả những cái reaction giận dữ, vào comment: “Bớ admin ơi có đứa tag channel!!!”, “Bà nội mày ai cho mày tag channel!!!!”, rồi thi nhau leave room – Destructive feedback, bị chửi bạn mem mới kia sẽ lồng lộn lên chửi lại rồi bỏ WeBuild mà đi, có khi đi nơi khác mà chửi WeBuild ko thương tiếc.
  • Vào comment hoặc ping riêng một cách nhã nhặn: “Bạn ơi, vừa rồi mình thấy bạn tag channel ở #general, đây là public channel nên có mấy nghìn thành viên lận, tag vậy sẽ làm phiền mọi người đấy, bạn edit lại đi nha.” – Constructive feedback, nếu nhận được phản hồi như thế này, mình không nghĩ có ai cảm thấy offense và sẽ vui vẻ sửa sai ngay.

Các bạn thấy đấy, việc đưa ra feedback là rất quan trọng và cần thiết, và đưa ra feedback như nào lại quan trọng không kém. Cái ranh giới giữa constructive feedback và destructive feedback nó chỉ cách nhau một cái ngứa mồm và một nhịp cảm xúc.

Be a good communicator, don’t be that person.

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

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

Xem thêm tuyển dụng các vị trí CNTT hấp dẫn trên TopDev

Định nghĩa request body và response với RAML

request body và response
Định nghĩa request body và response với RAML

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

Đối với các request với HTTP method là POST, PUT, DELETE, thông thường chúng ta sẽ cần định nghĩa request body. Với RAML thì chúng ta sẽ định nghĩa cấu trúc của request body như thế nào và làm thế nào để định nghĩa response với RAML. Trong bài viết này, chúng ta hãy cùng nhau tìm hiểu các bạn nhé!

  Định nghĩa request URL với RAML
  10 Java Web Framework tốt nhất

Xem thêm tuyển dụng AngularJS lương cao trên TopDev

Giả sử mình định nghĩa một request để thêm mới thông tin sinh viên với nội dung ban đầu như sau:

#%RAML 1.0
baseUri: https://localhost:8081/api
title: Student Management System
version: 1.0

/students:
post:
description: Add new student

Để định nghĩa request body cho request này, chúng ta sẽ khai báo thêm section body với content-type, kiểu dữ liệu và có thể thêm example cho request body này nữa. Ví dụ như sau:

/students:
post:
description: Add new student
body:
application/json:
type: Student
example: { "id" : 5, "name" : "Khanh" }

Như các bạn thấy, mình đã định nghĩa content-type cho data trong request body trong ví dụ này của mình là application/json với kiểu dữ liệu là Student như sau:

types:
Student:
type: object
properties:
id:
required: true
type: integer
name:
required: true
type: string

Để định nghĩa response cho một request trong RAML, chúng ta sẽ sử dụng section responses. RAML cho phép chúng ta định nghĩa response cho từng HTTP  status code và với mỗi response, tương tự như request body, chúng ta cũng có thể định nghĩa response body. Ví dụ như sau:

/students:
post:
description: Add new student
body:
application/json:
type: Student
example: { "id" : 5, "name" : "Khanh" }
responses:
201:
body:
application/json:
type: String
example: "Created"

Như các bạn thấy, ngay sau khi khai báo section cho HTTP status code, chúng ta sẽ khai báo section body để khai báo nội dung của response body. Chúng ta cũng có thể khai báo content-type, kiểu dữ liệu, example tương tự như request body.

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

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

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

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

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

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

Trong bài viết “Giới thiệu về Stream API trong Java 8” , chúng ta đã tìm hiểu về các đặc điểm, các làm việc của Stream trong Java 8. Ở bài viết này, tôi muốn giải thích kỹ hơn về cơ chế Lazy Evaluation của Stream trong Java 8.

  10 tips để trở thành Java Developer xịn hơn
  Những mã xấu mà Java 8 có thể khử

Xem thêm tuyển dụng Java lương cao trên TopDev

Như chúng ta đã biết, Stream có một đặc điểm rất quan trọng là cho phép tối ưu hóa hiệu xuất của chương trình thông qua cơ chế lazy evaluation, nghĩa là chúng không được thực hiện cho đến khi cần thiết. Các hoạt động tính toán trên source data chỉ được thực hiện khi một terminal operation được khởi tạo và các source element chỉ được sử dụng khi cần.

Hãy xem ví dụ sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
class Employee {
    String name;
    String department;
    int salary;
}
class EmployeeRepository {
    private static final Map<Integer, Employee> employees = new HashMap<>();
    static {
        employees.put(1, new Employee("gpcoder 1", "A", 50));
        employees.put(2, new Employee("gpcoder 2", "B", 100));
        employees.put(3, new Employee("gpcoder 3", "A", 150));
        employees.put(4, new Employee("gpcoder 4", "B", 200));
    }
    
    public Employee findById(Integer id) {
        System.out.println("findById: " + id);
        return employees.get(id);
    }
}
class EmployeeFilter {
    
    public static Predicate<Employee> filterDepartmentEqualsWith(String department) {
        return e -> {
            System.out.println("filterDepartmentEqualsWith: " + e);
            return e.getDepartment().equals(department);
        };
    }
    
    public static Predicate<Employee> filterSalaryGreaterThan(int salary) {
        return e -> {
            System.out.println("filterSalaryGreaterThan: " + e);
            return e.getSalary() >= salary;
        };
    }
}
public class Java8StreamDeeply {
    
    public static void main(String[] args) {
        EmployeeRepository employeeRepository = new EmployeeRepository();
        
        Integer[] empIds = { 1, 2, 3, 4 };
        
        Stream.of(empIds)
          .map(employeeRepository::findById)
          .filter(EmployeeFilter.filterSalaryGreaterThan(100))
          .filter(EmployeeFilter.filterDepartmentEqualsWith("A"))
          .findFirst();
    }
}

Chạy chương trình trên, chúng ta có kết quả như sau:

1
2
3
4
5
6
7
8
findById: 1
filterSalaryGreaterThan: Employee(name=gpcoder 1, department=A, salary=50)
findById: 2
filterSalaryGreaterThan: Employee(name=gpcoder 2, department=B, salary=100)
filterDepartmentEqualsWith: Employee(name=gpcoder 2, department=B, salary=100)
findById: 3
filterSalaryGreaterThan: Employee(name=gpcoder 3, department=A, salary=150)
filterDepartmentEqualsWith: Employee(name=gpcoder 3, department=A, salary=150)

Như bạn thấy, chương trình của chúng ta có 4 phần tử nhưng chỉ 3 phần tử được thực thi. Tại sao vậy?

Trong ví dụ trên, tôi sử dụng 3 Intermediate operations: 1 map() và 2 filter() operations. Chúng ta có 4 phần tử ở Stream source, mỗi phần tử có thể sẽ được thực thi 1 lần qua tất cả intermediate operation.

Đầu tiên, nó sẽ kiểm tra tất cả các operation trên phần tử có id là 1. Vì salary của nó không thõa filter salary, nên xử lý sẽ chuyển sang phần tử kế tiếp – id là 2. Không thực hiện trên filter deparment.

Tiếp theo, id 2 chỉ thõa mãn điều kiện salary, không thõa mãn điều kiện department, nên xử lý chuyển sang phần tử kế tiếp – id là 3.

Tại id 3, thõa mãn tất cả điều kiện ở trên và Stream evaluate yêu cầu Terminal Operations findFirst() và trả về kết quả.

Các operation trên các phần tử còn lại sẽ không được thực thi – id 4.

Có thể thấy rằng, Stream hoạt động tuần tự trên từng phần tử của source, duyệt qua tất cả các immediate operations, rồi đến terminal operation, cuối cùng mới chuyển sang phần tử kế tiếp (có thể không chuyển sang phần tử kế tiếp nếu đã thõa mãn mong muốn của terminal operation).

Tóm lại, quá trình xử lý các Stream một cách lười biếng (lazy) cho phép tránh việc kiểm tra tất cả dữ liệu khi không cần thiết. Cách làm này giúp cho Stream hoạt động rất hiệu quả khi có nhiều intermediate operation và nguồn dữ liệu là lớn.

Bài viết đến đây là hết, sau bài này hy vọng các bạn hiểu rõ hơn về Stream trong Java 8 và vận dụng nó thích hợp để đạt được hiệu quả tốt hơn.

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

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

Xem thêm tuyển dụng các vị trí CNTT hấp dẫn trên TopDev

Định nghĩa request URL với RAML

request url
Định nghĩa request URL với RAML

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

Trong bài viết trước, mình đã giới thiệu với các bạn về RAML để định nghĩa API spec. Trong bài viết này, mình sẽ hướng dẫn các bạn chi tiết hơn cách định nghĩa request URL với RAML như thế nào các bạn nhé!

  cURL là gì? Cách sử dụng Curl
  How to Design System like TinyURL – P1

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

Để làm ví dụ cho bài viết này, đầu tiên, mình sẽ tạo mới một tập tin .raml với thông tin về API quản lý sinh viên bao gồm thêm, xoá, sửa, tìm kiếm với nội dung ban đầu như sau:

#%RAML 1.0
baseUri: https://localhost:8081/api
title: Student Management System
version: 1.0

Chúng ta sẽ định nghĩa một số request như sau:

  • GET /students để lấy danh sách sinh viên
  • POST /students để thêm mới sinh viên
  • PUT /students/{id} để cập nhập một sinh viên với id được truyền trong request
  • DELETE /students/{id} để xoá một sinh viên với id được truyền trong request
  • GET /students/find-by-name?name=<student-name>
  • GET /students/find-by-ids?id=<id1>,<id2>

Với những request như trên, các bạn có thể định nghĩa một root request “/students” như sau:

/students:

Các bạn cứ hình dung một request URL sẽ chia thành nhiều cấp từ trái sang phải. Ví dụ như request /api/students/find sẽ có 3 cấp là api rồi đến students rồi đến find. Các cấp này ngăn cách bởi dấu “/”. Mỗi cấp sẽ là một level trong tập tin .raml theo thứ tự đó nên trong ví dụ trên của mình, root request cho tất cả các request sẽ là “/students”.

 

Cho root request này, chúng ta có 2 request là GET và POST để lấy thông tin tất cả sinh viên và thêm mới sinh viên, nên các bạn chỉ cần khai báo những request này như sau:

/students:
get:
post:

Các bạn có thể thêm description cho mỗi request nếu muốn, ví dụ như:

/students:
get:
description: Get all students
post:
description: Add new student

Tiếp theo, chúng ta có 2 request với /students/{id} với PUT và DELETE HTTP method, dùng để cập nhập và xoá thông tin của một sinh viên nào đó. Vì chúng ta đã định nghĩa root request với “/students” rồi nên giờ các bạn chỉ cần định nghĩa cho 2 request mới này như sau:

/students:
get:
post:

/{id}:
put:
description: Update information for a student
delete:
description: Delete information of a student

Các bạn có thể định nghĩa thêm thông tin của các path parameter, thông tin về mục đích của path parameter, kiểu dữ liệu là gì, example về giá trị của chúng nữa. Để làm được điều này, chúng ta sẽ dùng section uriParameters. Ví dụ mình có thể định nghĩa thông tin cho path parameter {id} trong ví dụ trên như sau:

/students:
get:
description: Get all students
post:
description: Add new student

/{id}:
uriParameters:
id:
description: Id of the student
type: string
example: "1"
put:
description: Update information for a student
delete:
description: Delete information of a student

Đối với request /students/find-by-name?name=<student-name>, chúng ta cần định nghĩa thêm section /find-by-name với root request là “/students” như sau:

/students:
get:
description: Get all students
post:
description: Add new student

/{id}:
uriParameters:
id:
description: Id of the student
type: string
example: "1"
put:
description: Update information for a student
delete:
description: Delete information of a student

/find-by-name:
get:
description: Find student by name

HTTP method của request này là GET và mình cũng đã thêm description cho request này.

Đối với request /students/find-by-name này, chúng ta có thêm request parameter tên là name. Chúng ta có thể định nghĩa thông tin request parameter này như sau:

/students:
get:
description: Get all students
post:
description: Add new student

/{id}:
uriParameters:
id:
description: Id of the student
type: string
example: "1"
put:
description: Update information for a student
delete:
description: Delete information of a student

/find-by-name:
get:
description: Find student by name
queryParameters:
name: 
description: Name of student
type: string
example: "Khanh"

Như các bạn thấy, mình sử dụng section queryParameters để định thông tin cho tất cả các request parameter của request. Request parameter trong ví dụ này của mình có kiểu dữ liệu String. Các bạn có thể định nghĩa request parameter này có bắt buộc hay không sử dụng thuộc tính “required: false” hoặc sử dụng question mark như sau:

queryParameters:
name?: 
description: Name of student
type: string
example: "Khanh"

Trong ví dụ của mình thì request parameter name là bắt buộc các bạn nhé!

Đối với những request có matrix parameter như /students/find-by-ids?id=<id1>,<id2> thì các bạn có thể định nghĩa matrix parameter đó với type là array. Ví dụ như sau:

/students:
get:
description: Get all students
post:
description: Add new student

/{id}:
uriParameters:
id:
description: Id of the Student
type: string
example: "1"
put:
description: Update information for a student
delete:
description: Delete information of a student

/find-by-name:
get:
description: Find student by name
queryParameters:
name: 
description: Name of student
type: string
example: "Khanh"
/find-by-ids:
get:
description: Find list of students by a list of Ids
queryParameters:
ids: 
description: List of Ids
type: number[]
example: "1,2,3"

Toàn bộ nội dung của tập tin .raml của ví dụ trong bài viết này như sau:

#%RAML 1.0
baseUri: https://localhost:8081/api
title: Student Management System
version: 1.0

/students:
get:
description: Get all students
post:
description: Add new student

/{id}:
uriParameters:
id:
description: Id of the Student
type: string
example: "1"
put:
description: Update information for a student
delete:
description: Delete information of a student

/find-by-name:
get:
description: Find student by name
queryParameters:
name: 
description: Name of student
type: string
example: "Khanh"
/find-by-ids:
get:
description: Find list of students by list of Ids
queryParameters:
ids: 
description: List of Ids
type: number[]
example: "1,2,3"

Giới thiệu Castle Mock – Mock REST APIs và SOAP web-services

castle mock
Giới thiệu Castle Mock – Mock REST APIs và SOAP web-services

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

Trong quá trình phát triển hệ thống hoặc quá trình testing, một trong những vấn đề khó khăn là khi hệ thống của bạn cần tích hợp với một bên thứ ba (3rd party). Do sử dụng API của bên thứ ba nên chúng ta có thể gặp một số vấn đề sau:

  • Bên thứ ba không có hoặc không cung cấp hệ thống test cho chúng ta.
  • Bên thứ 3 đang phát triển API song song với chúng ta hoặc chưa hoàn thành API cho chúng ta sử dụng.
  • Không thể gọi API thật để test: gặp vấn đề về chi phí và bảo mật.
  • Gọi service của bên thứ ba để viết Unit Test rất chậm và đôi khi service của họ die dẫn đến Unit Test của chúng ta failed không mong muốn.
  AspectMock là gì? Tại sao dùng AspectMock với Codeception
  Hướng dẫn tạo mock API Server với Post Man

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

Để giải quyết vấn đề này, mình cần thu thập API document của họ, và dựng nên con mock service, trả về đúng những trường hợp cần sử dụng trong requirement API document và để team tích hợp.

Trong bài viết này mình sẽ giới thiệu về 1 Mock service rất dễ sử dụng là Castle Mock.

Giới thiệu Castle Mock

Castle Mock là một ứng dụng web cung cấp chức năng để giả lập API RESTful và SOAP web service. Chức năng này cho phép các developer phía client có thể giả lập các behavior và response ở phía server.

Một số tính năng nỗi bật của Castle Mock:

  • SOAP & REST: Có thể Mock cho cả SOAP and REST. Có thể được cấu hình bằng cách import các file định nghĩa service như: WSDL, WADL, Swagger và RAML. Các web service được xác định trong các file cấu hình sẽ được Castle Mock giả lập một cách tự động.
  • Proxy và record responses: Castle Mock có thể được sử dụng như một proxy giữa Client và Server. SOAP và REST có thể được mock hoặc chuyển tiếp đến service thật. Phản hồi (response) từ các yêu cầu được chuyển tiếp có thể được ghi lại tự động và được sử dụng để tạo các phản hồi giả (mocked response).
  • Logging: Tất cả các request gửi đến và response gửi đi sẽ được ghi lại, giúp chúng ta dễ dàng theo dõi cũng như debug khi cân thiết.
  • Easy installation: Castle Mock được xây dựng bằng Java và bản thân ứng dụng được dễ dàng triển khai trên máy chủ Apache Tomcat thông qua WAR file. Ngoài ra, Castle mock cũng dễ dàng được setup và deploy trên Docker.
  • Open source: Castle Mock hoàn toàn miễn phí và là nguồn mở (Giấy phép Apache 2.0). Source code của nó có thể được tìm thấy trên Github.

Download và cài đặt Castle Mock

Yêu cầu cài đặt các phần mềm:

Hướng dẫn cài đặt Java 8

Các bạn xem lại bài viết “Hướng dẫn cài đặt JDK“.

Cài đặt và cấu hình Tomcat Server

Các bạn xem lại bài viết “Triển khai ứng dụng Jersey REST Web service lên Tomcat Server“.

Download và cài đặt Castle Mock

Truy cập link sau để download Castle Mock: https://castlemock.com/use-castle-mock/

Sau khi đã download thành công file .war, chúng ta tiến hành deploy nó lên Apache Tomcat server.

Mặc định Tomcat chỉ cho phép upload tối đa 50MB. Do file castlemock lớn hơn nên mình cần config lại limit size cho phép upload lên tomcat server. Các bạn mở file webapps/manager/WEB-INF/web.xml trong thư mục Tomcat.

Truy cập link sau và deploy castle mock: http://localhost:8090/manager

  • Context Path: /castlemock
  • Chọn file castlemock.war đã download ở trên.

Sau khi đã deploy xong, các bạn truy cập địa chỉ sau: http://localhost:8090/castlemock

Bạn sẽ được yêu cầu nhập username và password truy cập ứng dụng castle mock:

1
2
Username: admin
Password: admin

Sử dụng Castle Mock

Tạo Mock project và tạo các mock REST and SOAP APIs.

REST project

Create a REST project

Trên trang Overview, click “New project” button để bắt đầu tạo một project mới. Nhập tên project, description và chọn chọn loại project là REST.

Tiếp theo, chọn project đã tạo:

Upload API specifications

Mock service có thể được tạo bằng nhiều cách. Sau khi đã tạo project, chúng ta có thể tạo các mock service thủ công hoặc upload file đặc tả API (API specification) nếu đã được định nghĩa từ trước.

Castle Mock hỗ trợ các loại API specification: Swagger, RAML, WADL. Để đơn giản trong bài này, tôi sử dụng Swagger.

Giả sử chúng ta cần tạo mock các API của Swagger sau: http://petstore.swagger.io/ . File mô tả các API này được định nghĩa trong file swagger.json tại link https://petstore.swagger.io/v2/swagger.json

Click button Upload và chọn Swagger:

Chúng ta có 2 lựa chọn: nhập link đến file đặc tả API hoặc upload một file mới. Sau đó check chọn “Generate response for each operation” để swagger tự tạo response cho mỗi API.

Click button Link Swagger hoặc Upload để tạo mock service.

Click lên tên Application:

Create mocked responses

Click tên Resource “/user” -> tên Method “createUser”, chúng ta có kết quả sau:

Sau khi import và check “Generate response …”, Castle Mock giúp chúng ta tạo 1 response như trên.

Một Method có thể có nhiều Response, mỗi Response có Name, HTTP status code, Header và resposne message.

Chúng ta có thể tạo một response mới bằng cách click vào button Create Resposne như sau:

Chúng ta có 2 response:

Update method – Response strategy

Chúng ta có thể tạo nhiều response, như vậy Castle Mock lựa chọn response nào để trả kết quả về cho request? Đó chính là cấu hình response strategy.

Castle Mock hỗ trợ các loại response strategy:

  • Random (ngẫu nhiên): chiến lược này lựa chọn một mock response ngẫu nhiên.
  • Sequence (tuần tự): chiến lược này lựa chọn một mock response theo trình tự. Trình tự được xác định theo thứ tự các mock response được tạo. Trình tự sẽ bắt đầu lại từ đầu khi nó đã đến response cuối cùng.
  • Ngoài ra còn có: Query match, XPath match, JSON Path match, Header Query match.

Để cấu hình Response Strategy, click button “Update method“:

Update method – Method type

Castle Mock hỗ trợ tất cả Method type: GET, PUT, POST, DELETE, …

Update method – Method status

Một mock api có một mode. Mode sẽ xác định cách mock web service sẽ hoạt động như thế nào. Các mode được Castle mock hỗ trợ:

  • Mocked : mode này sẽ sử dụng các mock response đã định nghĩa.
  • Disabled : mode này làm service bị disable. Phía end user sẽ nhận được thông báo lỗi nếu cố gắng gọi một ws bị vô hiệu hóa.
  • Forward requests: mode này sẽ chuyển tiếp sẽ chuyển tiếp tất cả các request đến điểm cuối bên ngoài (service thật). Mode này có thể được sử dụng khi chỉ một số ws bị mock, trong khi phần còn lại sẽ gọi đến ws thật.
  • Record responses : mode này sẽ chuyển tiếp tất cả các request đến điểm cuối bên ngoài và tạo phản hồi giả (mock response) cho các response được trả về từ điểm cuối bên ngoài.
  • Recording once : mode này sẽ thực hiện giống như mode Record response, nhưng sẽ chỉ thực hiện một lần. Khi đã xong, ws sẽ chuyển sang chế độ Mocked thay thế.
  • Echo : mode này sẽ trả về request như là một response.

Update method – Simulate netword deplay

Các request trên internet có độ trễ (deplay) là không tránh khỏi, chúng ta có thể dễ dàng mô phỏng độ trễ phản hồi response một cách dễ dàng thông qua option này.

Test các Mock REST API được tạo bởi Castle Mock với Postman

Để test Mock REST API được tạo bởi Castle Mock, các bạn có thể click lên Resource và lấy thông tin resource như sau:

Mở Postman và gọi đến REST API trên, chúng ta sẽ lần lượt nhận được response status 200 và 400.

SOAP project

Create a SOAP project

Tương tự như tạo REST Project, các bạn chọn loại project là SOAP.

Import WSDL file

Mock SOAP web service được tạo bằng cách import file WSDL – file mô tả SOAP web service. Trên trang SOAP project, click “Upload WSDL” button để upload một file WSDL hoặc trỏ đến URL của file WSDL.

Để đơn giản tôi sẽ sử dụng API Calculator từ http://www.dneonline.com/calculator.asmx với link WSDL như sau: http://www.dneonline.com/calculator.asmx?WSDL

Sau khi Link WSDL:

Chúng ta có thể xem chi tiết API đã import với các response được tạo:

Create mocked responses

Tương tự như REST, chúng ta có thể tạo nhiều Mock response nếu cần.

Test các Mock SOAP API được tạo bởi Castle Mock với SOAP UI

Để test Mock SOAP API được tạo bởi Castle Mock, các bạn có thể click lên tên Project và lấy thông tin URL của file WSDL như sau:

Mở SOAP UI, và import file mock WSDL trên để test.

Bài viết đến đây là hết. Chúc các bạn thành công trong việc sử dụng hiệu quả Mock service :).

Ah, ngoài ra còn một công cụ khác cũng có tính năng tương tự là mountebank. Công cụ này được xây dựng trên nền node.js, các bạn có thể tìm hiểu thêm document trên trang chủ của mountebank nếu thích.

Tài liệu tham khảo:

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

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

Xem thêm tuyển dụng các vị trí IT hấp dẫn trên TopDev

Offline token với Keycloak

offline token
Offline token với Keycloak

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

Offline access là một tính năng của OpenID Connect được định nghĩa tại https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess. Nó giúp cho application với offline token (một loại của refresh token) có thể lấy access token và sử dụng resource mà không cần user phải đăng nhập trong thời gian dài hoặc mãi mãi. Keycloak hỗ trợ chúng ta làm việc với offline access bằng cách sử dụng offline token. Cụ thể như thế nào? Chúng ta hãy cùng nhau tìm hiểu trong bài viết này các bạn nhé!

  Authorization Code grant type với Proof Key for Code Exchange (PKCE) trong OAuth 2.1
  C Token là gì? Cú pháp trong lập trình C/C++

Xem thêm nhiều việc làm NextJS lương cao trên TopDev

Để làm ví dụ, mình sẽ tạo mới một client với grant type Authorization Code trong Keycloak như sau:

 

Điều đầu tiên các bạn cần phải biết là làm thế nào chúng ta lấy được offline token.

Rất đơn giản, trong request lấy authorization code cho client, chúng ta cần truyền thêm scope là offline_access là được:

 

Keycloak sẽ hỏi chúng ta có cho phép Client Application Offline Access hay không?

Nếu các bạn đồng ý thì sau khi có authorization code, request lấy access token cho client này:

 

parse nội dung của refresh token, các bạn sẽ thấy nội dung payload như sau:

Type của token này là Offline thay vì Refresh và các bạn có thể thấy, không có claim “exp” với expiration time như khi chúng ta parse access token:

 

Chúng ta có thể sử dụng offline token này để lấy access token mới tương tự như refresh token.

Ví dụ như sau:

Điểm khác biệt giữa offline token và refresh token là không có expiration time cho offline token.

 

Mặc định thì offline token là nó sẽ luôn valid dù user không đăng nhập hoặc server bị restart, chỉ trừ khi nó bị revoke. Tuy nhiên, các bạn cần sử dụng offline token này ít nhất là một lần trong khoảng thời gian mặc định là 30 ngày, kể từ lần sử dụng gần nhất. Đó là bởi vì, một offline token sẽ associate với một offline session. Và offline session này chỉ có thời gian chờ (idle time) mặc định là 30 ngày như mình nói ở trên. Ở Realm level thì giá trị 30 ngày này được cấu hình trong tab Tokens của Realm Settings, field Offline Session Idle:

Ở tab Tokens này, như các bạn thấy, chúng ta còn có 1 field khác liên quan đến offline session nữa, tên là Offline Session Max Limited. Ý nghĩa của field này là nếu các bạn enable, offline token sẽ bị expired trong thời gian mặc định là 60 ngày, dù chúng ta có sử dụng offline token này bao nhiêu lần đi chẳng nữa:

Các bạn có thể thay đổi các cấu hình liên quan đến offline session ở Realm level nếu muốn, các client sẽ kế thừa cấu hình này. Còn nếu muốn cấu hình cụ thể cho một client nào đó thì hãy expand phần Advance Settings trong mỗi client:

chúng ta có thể thay đổi cấu hình của Client Offline Session Idle và Client Offline Session Max ở đây.

Các bạn có thể xem tất cả các offline token của một client bằng cách vào tab Offline Access của client đó

Tối Ưu Hóa Quy Trình Kiểm Soát Chất Lượng Với 7 Công Cụ QC

7 công cụ qc
Tối Ưu Hóa Quy Trình Kiểm Soát Chất Lượng Với 7 Công Cụ QC

7 công cụ QC đã và đang trở nên quen thuộc với những nhân viên đảm nhận ở vị trí Quality Control trong mỗi nhà máy sản xuất. Và dĩ nhiên chúng là cánh tay đắc lực giúp doanh nghiệp tiết kiệm chi phí vận hành khi đề ra mục tiêu chinh phục khách hàng. Ngày nay có không ít doanh nghiệp đã và đang ứng dụng 7 công cụ QC. Đây được xem là bài toán thông minh  giúp các doanh nghiệp quy mô vừa – nhỏ, thậm chí là các tập đoàn đa quốc gia giải quyết tối ưu những vấn đề về quản trị chi phí vận hành sản phẩm, dịch vụ. 

7 công cụ qc
7 công cụ qc

Công cụ quản lý chất lượng là gì?

QC (Quality Control) hay còn gọi là kiểm soát chất lượng là quy trình quan trọng để kiểm tra, đánh giá và vận hành thử trước khi một sản phẩm/ dịch vụ nào đó chạm tới tay người tiêu dùng. Liệu doanh nghiệp có thể tối ưu hóa hoạt động kinh doanh nhờ sử dụng công cụ kiểm soát chất lượng? 

Hiện nay, hoạt động kiểm soát chất lượng được ứng dụng trong nhiều lĩnh vực kinh tế khác nhau, từ quản lý công nghiệp đến kinh doanh thương mại. Bất kể doanh nghiệp quy mô vừa – nhỏ hay đến các tập đoàn lớn đều cho rằng quản lý chất lượng là một trong những khâu yếu tố quyết định việc sống còn của doanh nghiệp.

  Dù là nhân viên hay ông chủ, bạn cũng cần phải nắm 4 nguyên tắc này để nâng cao chất lượng công việc
  5 tips cải tiến chất lượng phát triển Mobile App

7 công cụ QC phổ biến được các doanh nghiệp đánh giá cao hiện nay

 Hiện nay, các công ty sử dụng tới 7 công cụ QC khác nhau để theo dõi, phân tích và đánh giá chất lượng của sản phẩm hoặc dịch vụ.

1. Lưu đồ (Flowchart)

Việc ai là cha đẻ phát minh ra lưu đồ vẫn là một ẩn số. Song ngày nay lưu đồ được áp dụng rộng rãi vì nó tóm tắt được các bước của một quy trình, có liên quan chặt chẽ với nhau để chỉ ra hoạt động hiệu quả trong hoạt động thực tế. Việc sử dụng công cụ QC này sẽ giúp nhân viên vận hành sản phẩm theo một quy trình cụ thể, rõ ràng và khoa học hơn. 

Lưu đồ dùng để kiểm soát quy trình hỗ trợ khách hàng

2. Biểu đồ mật độ phân bố (Histogram)

Về tổng thể thì đây là biểu đồ dạng cột đơn giản thể hiện tần suất của sản phẩm/dịch vụ xuất hiện ở thị trường nào đó. Qua đó nhân viên QC có thể đánh giá tình hình phân bố của sản phẩm/ dịch vụ. Và trên cơ sở này để có những can thiệp kịp thời để đảm bảo tình hình kinh doanh, sản xuất nhờ sử dụng công cụ QC này. 

Biểu đồ mật độ tần suất số lần phản ứng

3. Biểu đồ Pareto (Pareto Chart)

Là biểu đồ kết hợp đơn giản trong đó các đối tượng được sắp xếp từ tần số cao nhất đến tần số thấp nhất. Pareto cho phép các nhà phân tích kinh tế quan sát giá trị tuyệt đối đại diện cho nguyên nhân của sai số trong cột. Đồng thời, phần trăm lỗi tích lũy cũng được hiển thị dưới dạng một dòng.

4. Phiếu kiểm tra (Check sheet)

Việc thu thập, ghi chép dữ liệu từ phiếu kiểm tra đóng vai trò quan trọng trong việc đánh giá, đưa ra hướng giải quyết thích hợp. Phiếu kiểm tra được sử dụng linh hoạt từ việc điều tra nguyên nhân sản phẩm bị trả lại, kiểm tra, tìm nguyên nhân gây ra lỗi cho đến kiểm tra xác nhận trước khi trưng cầu ý kiến khách hàng. 

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

5. Biểu đồ quan hệ nhân quả (Cause & Effect Diagram)

Khi có sự cố phát sinh về chất lượng thì việc áp dụng biểu đồ quan hệ nhân quả sẽ giúp nhân viên QC tìm ra được nguyên nhân cội nguồn nằm ở đâu.  Trên thực tế, một vấn đề có thể xuất phát từ nhiều nguyên nhân khác nhau và ở chúng có sự phân cấp với nhau. Ví dụ như nguyên nhân thứ cấp gián tiếp xuất phát từ nguyên nhân thứ cấp trực tiếp, và tất cả đều xuất phát từ nguyên nhân gốc. Việc áp dụng biểu đồ quan hệ nhân quả sẽ giúp nhân viên QC dễ điều tra được sự cố của sản phẩm đó bắt nguồn từ đâu và đưa ra hướng giải quyết kịp thời. 

6. Biểu đồ phân tán (Scatter Diagram)

Mối tương quan giữa nguyên nhân và kết quả hoặc chất lượng bị ảnh hưởng bởi các yếu tố được thể hiện bằng biểu đồ này. Có nhiều yếu tố tác động qua lại và có tính kết hợp ảnh hưởng đến chất lượng của sản phẩm hay dịch vụ. Biểu đồ này có thể mô tả tình hình chất lượng bằng hai hay nhiều đối tượng cùng một lúc. 

7. Biểu đồ kiểm soát (Control Charts)

Biểu đồ kiểm soát được phát triển từ biểu đồ chạy (R – Chart), nhưng được thêm phần giới hạn kiểm soát trên và kiểm soát dưới. Cộng thêm công thức tính năng lực quá trình (Cp, Cpk) giúp nhân viên QC dễ dàng phân tích quan sát quá trình đó có nằm trong thông số có thể chấp nhận được hay không. 

Tìm việc làm QA QC lương cao trên TopDev

Tầm quan trọng của việc ứng dụng công cụ quản lý chất lượng trong sản xuất kinh doanh

Bất kỳ một công ty sản xuất muốn đưa sản phẩm/ dịch vụ của mình tiếp cận người dùng ở phân khúc thị trường nào đó sẽ không thể bỏ qua khâu kiểm soát chất lượng. Hay nói cách khác đầu tư vào đội ngũ QC (Quality Control) luôn đóng vai trò quan trọng giúp công ty  đó cho ra đời những sản phẩm hoàn hảo nhất đến khách hàng của mình. 

Thông thường đội QC sẽ đảm nhận vai trò khi làm việc trực tiếp tại nhà máy, phân xưởng và giám sát chặt chẽ từng công đoạn để đảm bảo rủi ro thấp nhất cho sản phẩm/ dịch vụ nào đó. Ngoài ra nhân viên QC sẽ bắt đầu từ khâu nhập nguyên liệu cho đến khi sản xuất ra sản phẩm đến tay người tiêu dùng cuối cùng. Công việc của nhân viên QC trong doanh nghiệp được thực hiện thường xuyên và liên tục, đòi hỏi họ phải chịu được nhiều áp lực. 

Trên đây là những chia sẻ về 7 công cụ QC vốn quen thuộc trong doanh nghiệp sản xuất. Nếu bạn đang tìm giải pháp để giúp quy trình kiểm soát được diễn ra tiết kiệm và khoa học, hãy tìm hiểu những công cụ QC được nêu trên để công việc trở nên dễ dàng hơn. 

Intern: Hồ Ngọc Bích

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

Xem thêm tuyển dụng việc làm IT hấp dẫn trên TopDev

Hướng dẫn cài đặt và cấu hình Nginx Amplify Agent trên Centos 7

nginx amplify agent
Hướng dẫn cài đặt và cấu hình Nginx Amplify Agent trên Centos 7

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

1. Chuẩn bị cài đặt Nginx Amplify Agent:

– Nginx chỉ hoạt động trên server chạy hệ điều hành Linux:

  • Ubuntu 12.04, 14.04, 16.04
  • Debian 7, 8
  • CentOS 6, 7
  • Red Hat 6, 7 (and systems based on it, e.g. Oracle Server)
  • Amazon Linux (latest release)
  • Gentoo Linux (experimental Ebuild)

– Hệ thống đã cài đặt Nginx từ version 1.10 trở lên

– NGINX Amplify Agent chỉ hoạt động  Python 2.6 và 2.7. Python 3 thì không hoạt động.

  App User Centricity: Làm sao tăng tỷ lệ duy trì lên 66%?
  Cài đặt ConfigServer Security and Firewall (CSF) và Webmin trên CentOS 7

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

2. Cài đặt và cấu hình Nginx Amplify Agent

1. Cài đặt

yum info nginx-amplify-agent

2. Cập nhật

yum update nginx-amplify-agent

3. Start service

systemctl start amplify-agent
# Restart service
systemctl restart amplify-agen

4. Gỡ cài đặt

yum remove nginx-amplify-agent

5. Kích hoat với API key

Bạn lấy mã cài đặt kích hoạt trên UI web Nginx Amplify Agent

Sau đó chạy đoạn code đó

# curl -sS -L -O \
https://github.com/nginxinc/nginx-amplify-agent/raw/master/packages/install.sh && \
API_KEY='ffeedd0102030405060708090a0b0c' sh ./install.sh

6. Kiểm tra Amplify Agent đã started

ps ax | grep -i 'amplify\-'

Cuối  cùng enjoy nhé! Cài đặt vô cùng đơn giản đúng không 😀

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

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

Xem thêm tuyển dụng các vị trí CNTT hấp dẫn trên TopDev

Lấy access token sử dụng refresh token với Keycloak

access token
Lấy access token sử dụng refresh token với Keycloak

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

Mình đã giới thiệu về Refresh Token grant type trong OAuth 2.0 trong bài viết về Các loại grant types trong OAuth 2.0. Trong bài viết này, mình sẽ hướng dẫn các bạn cách chúng ta lấy mới access token sử dụng refresh token với Keycloak là như thế nào các bạn nhé!

  Authorization Code grant type với Proof Key for Code Exchange (PKCE) trong OAuth 2.1
  Thêm mới client hỗ trợ OAuth Authorization Code grant type trong Keycloak

Đầu tiên, mình sẽ tạo mới trong Keycloak một client với Authorization Code grant type để làm ví dụ:

Thực hiện lấy access token cho client này, các bạn sẽ thấy kết quả như sau:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJZR29TSXBPblRKeTJmbjhzLWk4WlBKMC1xWkxybEEtNVI4ZjhXbTFjYjVVIn0.eyJleHAiOjE2MzU2NDMxMDYsImlhdCI6MTYzNTY0MjgwNiwiYXV0aF90aW1lIjoxNjM1NjQyNzk0LCJqdGkiOiJjZTY4ZDIxYS04YzdkLTQ1YWItOWMxNC1jYzdkMTM5NWNmOGMiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvaHVvbmdkYW5qYXZhIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjhhNTA5MmZhLWQ4MTUtNDYyMC05MmFiLTRhYzg3NTQyNjg1YyIsInR5cCI6IkJlYXJlciIsImF6cCI6Imh1b25nZGFuamF2YV9hdXRob3JpemF0aW9uX2NvZGUiLCJub25jZSI6IjllZW1meGhiazYiLCJzZXNzaW9uX3N0YXRlIjoiN2E4ZGMxODktMTVlZS00ZWZhLWEwZGEtNmY5ZjdlY2Y2MjczIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1odW9uZ2RhbmphdmEiXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiS2hhbmggTmd1eWVuIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiaHVvbmdkYW5qYXZhIiwibG9jYWxlIjoiZW4iLCJnaXZlbl9uYW1lIjoiS2hhbmgiLCJmYW1pbHlfbmFtZSI6Ik5ndXllbiIsImVtYWlsIjoiaHVvbmdkYW5qYXZhLmNvbUBnbWFpbC5jb20ifQ.JgklBAraEs__i2CHI0z7KQZBy5JeIVfBPzP4cORxNEcI53zbGEmsCqHZoNt0qwcURGc9EV77jzOnqlq6j7wWPhtwhpzOHT3JupqGD86CyaUJ9rh-GrhnKDy7YMTp9337X7J2qzp5YIIK0tmroGjNR7dIpHn1ThatNLM-8w2KnydT7DhYjHx1gaX7HKXAuaiBhNbR7PYrS1-FsbxT--QjNNs-mgTXl7OVnqpCPcRCt8pBPu15kPbP00i7zJ7AaSmZfPNBt7rFPGkaYAX5kIi8FY0wf2RZuFMcgDpg-01rzfTkoWIXCdDSQPBagAveQUE6viaC-nsV7_-5zTCvGch_0A",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI5ZjYzNWQ5Mi1hOTdjLTQwMjktODE2YS05ZWU3YjAxMmE3NDUifQ.eyJleHAiOjE2MzU2NDQ2MDYsImlhdCI6MTYzNTY0MjgwNiwianRpIjoiYTZmYmQwMDUtNGZlOC00NTdjLWEwZmEtMDA5ODBiZjY4NmE0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2h1b25nZGFuamF2YSIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9odW9uZ2RhbmphdmEiLCJzdWIiOiI4YTUwOTJmYS1kODE1LTQ2MjAtOTJhYi00YWM4NzU0MjY4NWMiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiaHVvbmdkYW5qYXZhX2F1dGhvcml6YXRpb25fY29kZSIsIm5vbmNlIjoiOWVlbWZ4aGJrNiIsInNlc3Npb25fc3RhdGUiOiI3YThkYzE4OS0xNWVlLTRlZmEtYTBkYS02ZjlmN2VjZjYyNzMiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIn0.zMYO5ZRupTskEs9QxJdnP3d24qcHavrLKG4pkQ-OLN8",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJZR29TSXBPblRKeTJmbjhzLWk4WlBKMC1xWkxybEEtNVI4ZjhXbTFjYjVVIn0.eyJleHAiOjE2MzU2NDMxMDYsImlhdCI6MTYzNTY0MjgwNiwiYXV0aF90aW1lIjoxNjM1NjQyNzk0LCJqdGkiOiI3NGFkNGMyNC1mYTliLTQ4MWMtYTgwZS1jMTVhNDk1NmU0ZDciLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvaHVvbmdkYW5qYXZhIiwiYXVkIjoiaHVvbmdkYW5qYXZhX2F1dGhvcml6YXRpb25fY29kZSIsInN1YiI6IjhhNTA5MmZhLWQ4MTUtNDYyMC05MmFiLTRhYzg3NTQyNjg1YyIsInR5cCI6IklEIiwiYXpwIjoiaHVvbmdkYW5qYXZhX2F1dGhvcml6YXRpb25fY29kZSIsIm5vbmNlIjoiOWVlbWZ4aGJrNiIsInNlc3Npb25fc3RhdGUiOiI3YThkYzE4OS0xNWVlLTRlZmEtYTBkYS02ZjlmN2VjZjYyNzMiLCJhdF9oYXNoIjoiRWpfZGlIMURTa0lINzlsMGpqMENsQSIsImFjciI6IjEiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJLaGFuaCBOZ3V5ZW4iLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJodW9uZ2RhbmphdmEiLCJsb2NhbGUiOiJlbiIsImdpdmVuX25hbWUiOiJLaGFuaCIsImZhbWlseV9uYW1lIjoiTmd1eWVuIiwiZW1haWwiOiJodW9uZ2RhbmphdmEuY29tQGdtYWlsLmNvbSJ9.Cm9kcio4DYM8f3WN_KQ5UJIe-RX8rRLKP0wlLJqwObE0tIxXAEqVOzr7gAv9WEpy_wDO3mC7NN4ZyfX8iQlm47UCdnFo-50vbeUDdfa1wtSM2FfnPOhV_76KwVDgD1KqImlHGdb0QbvzxAMS25RPrWeYWQsoJlVFqcOC52_sqQ217vJyuytComZ7BJ_otiKLSiUTmAAgmhc3UAiXjKseefzv858fn8b0Z-tVEJh-CfjwhnazRsxj5ukGYknX56wJHNGT35JU_Wph7rzv9EsRNm36_0Vt-7LyLBKrwWWV55MoPL_il7nzxUrehhfSzAzBzOSMhYqCuSfAAErKUKJGHw",
"not-before-policy": 0,
"session_state": "7a8dc189-15ee-4efa-a0da-6f9f7ecf6273",
"scope": "openid email profile"
}

Nội dung của refresh token nếu mình decode nó sử dụng https://jwt.io/ cơ bản như sau:

Các bạn để ý đến claim “typ” trong nội dung của refresh token trên nhé! Ở đây giá trị của claim này là Refresh, chúng ta còn có một số type khác của refresh token nữa, chẳng hạn như Offline,…

Refresh token sẽ luôn được trả về cùng với access token, giúp chúng ta có thể lấy access token mới mà không cần user phải đăng nhập trở lại.

Để lấy access token mới với refresh token thì trong request để lấy access token, các bạn chỉ cần truyền grant_type=refresh_token, giá trị của refresh token mà chúng ta có trong request lấy access token trước, client ID và client secret.

Với ví dụ này của mình, các bạn có thể lấy access token mới bằng cách request như sau:

Như các bạn thấy, với Refresh Token grant type, chúng ta không cần user phải đăng nhập nữa.

Một refresh token sẽ luôn có expiration time, mặc định của Keycloak là 30 phút các bạn nhé! Mỗi khi một access token mới được issue thì refresh token sẽ được issue lại, và các bạn có thể sử dụng cái mới nhất để expiration time được lâu hơn.

Chúng ta có thể sử dụng một refresh token để request access token nhiều lần. Tuy nhiên, các bạn có thể giới hạn số lần mà một refresh token có thể được sử dụng, bằng cách vào tab Tokens của Realm Settings, cấu hình field Revoke Refresh Token. Nếu các bạn turn on field này, thì có thể cấu hình số lần một refresh token được sử dụng lại:

Mặc định các bạn chỉ có thể sử dụng refresh token một lần thôi các bạn nhé!

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

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

3D Artist Là Gì? Các Mức Lương Hấp Dẫn Trong Nghề 3D Artist

nghề 3d artist
3D Artist là gì? Các mức lương hấp dẫn trong nghề 3D Artist

Nghề 3D Artist cũng được xem là họ hàng chung của “Art” trong giới mỹ thuật nhưng khác với “Art”, người nghệ sĩ có thể diễn đạt, trình bày những tác phẩm của họ ở bất cứ đâu thì “3D Artist” chỉ có thể được những người nghệ sĩ thể hiện trên các hình ảnh máy tính, được tạo nên nhờ những công cụ phần mềm hỗ trợ. Có thể nói những tác phẩm của một dân trong “Nghề 3D Artist” được tạo nên từ những dòng thuật toán trên nền tảng dữ liệu.

nghề 3d artist

 Nghề 3D Artist là gì?

3D Artist là một nhà thiết kế đồ họa chuyên biệt, họ là những người thông thạo công nghệ máy tính và phần mềm thiết kế mới nhất. Với một 3D Artist, trách nhiệm và nghĩa vụ của bạn bao gồm thiết kế và tạo hoạt ảnh 3D cho các ngành khác nhau bao gồm ứng dụng di động, y học, khoa học, trò chơi điện tử và tiếp thị. 

Một 3D Artist sử dụng năng khiếu nghệ thuật và sự sáng tạo cùng với chuyên môn kỹ thuật của mình để đáp ứng nhu cầu của mọi khách hàng dù cho nó có thật sự oái oăm đến mức nào. Có cả một nền tảng nghệ thuật về nhiếp ảnh hoặc vẽ cũng như các kỹ năng máy tính đặc biệt có thể rất hữu ích trong sự nghiệp này.

Các công cụ hỗ trợ cho dân 3D Artist

 Để dân 3D Artist tạo ra được những tác phẩm thì họ cần có những công cụ hỗ trợ, nên ở đây chúng ta sẽ nói đến Blender Blugin. Blender là một trong các công cụ phổ biến trong Ngành 3D Artist.

Blender Plugin là gì?

Blender được biết là một công cụ phần mềm 3D được sử dụng rất phổ biến, rộng rãi vì rất nhiều tính năng hữu ích với tính chất hỗ trợ mã nguồn miễn phí. Có một điều đặc biệt là phần mềm Blender ngày càng có thêm nhiều Plugin được hỗ trợ có thể tích hợp với nó.

Trong bài viết này, sẽ được nói đến các Plugin Blender có tầm quan trọng và hữu ích có thể giúp một dân 3D Artist tạo ra được nhiều tác phẩm đắt giá hơn. Trong đó, ngoại trừ các Plugin buộc người dùng phải trả phí thì Blender cùng có hỗ trợ một số các Plugin miễn phí giúp dân 3D Artist mới vào nghề hay điều kiện kinh tế chưa ổn có thể trãi nghiệm và sử dụng. 

Các Blender Plugin dành cho dân 3D Artist

Dưới đây, sẽ là 10 loại Plugin hữu ích, phổ biến hàng đầu được sử dụng trong Blender:

  1. Amaranth
  2. RetopFlow
  3. TexTools
  4. Speed ​​Sculpt 
  5. Edge Flow
  6. BoxCutter
  7. HardOps
  8. Boolean
  9. MESHmachine
  10. Gaffer
  11. Blam

3d artist

Một số mức lương của dân trong nghề 3D Artist hiện nay

Trong giới 3D Artist mức lương sẽ tuỳ thuộc vào từng yếu tố như độ tuổi, vị trí như Animation Director, Producer, Graphic Designer,…  , và dưới đây sẽ là những mức lương trung bình hằng tháng được khảo sát chung trên thế giới để một dân 3D Artist mới dấn thân vào hoặc đã đi làm tham khảo. Dưới đây là một số ngành nghề tiêu biểu của nghề 3D Artist tại thị trường Việt Nam.

Thu nhập của một 3D Artist vị trí Animation Director (đạo diễn hình ảnh)

Đạo diễn hoạt hình làm việc trong nhiều lĩnh vực bao gồm: xưởng phim, xưởng sản xuất truyền hình, công ty game và công ty quảng cáo… Mức lương hàng năm của đạo diễn hình ảnh rơi vào khoảng 71,350 USD. Trong khi đó, 10% nhà quay phim kiếm được dưới 32.080 USD/năm và 10% khác kiếm được hơn 187.200 USD  vào năm. Các đạo diễn độc lập cũng có thu nhập cao nhất trong ngành giải trí, với New York là 112.060 USD/năm.

Xem thêm các công việc tuyển dụng 3D Artist lương cao trên TopDev

Thu nhập của một 3D Artist vị trí Producer (nhà sản xuất)

Hầu hết những người trong nghề, cụ thể là một dân 3D Artist đều cho rằng công việc của một giám đốc sản xuất là không thể thiếu trong bất kỳ nhà máy, công ty nào. Giám đốc sản xuất trực tiếp tham gia vào việc lập kế hoạch, kiểm soát và giám sát quá trình sản xuất để đảm bảo giao  sản phẩm kịp thời, đúng yêu cầu về số lượng theo tiêu chuẩn chất lượng đề ra trong kế hoạch. Mức lương quản lý sản xuất nhìn chung dao động từ 615.38 USD đến 879.11 USD/tháng, tùy thuộc vào kỹ năng, kinh nghiệm của ứng viên và quy mô công ty.

Thu nhập của một 3D Artist vị trí Graphic Designer (Thiết kế đồ hoạ)

Thiết kế đồ họa là một trong những ngành nghề không ngừng phát triển, đặc biệt là trong thời đại công nghệ 4.0 hiện nay. Điều này  kéo theo hu cầu nhân lực của nghề 3D Artist không ngừng tăng lên.Nhân viên thiết kế đồ họa là những chuyên gia dùng các phần mềm thiết kế đồ họa để trực quan hóa ý tưởng từ văn bản, nội dung thành hình ảnh, logo, catalogue tạp chí, quảng cáo, … Mức lương trung bình của một nhà thiết kế đồ họa tại Việt Nam dao động vào khoảng từ 351.64 USD đến 879.11 USD// tháng.  Ngoài ra, mức lương thiết kế đồ họa phụ thuộc vào số năm kinh nghiệm.

Ngoài câc vị trí công việc trên thì nghề 3D Artist vẫn còn những vị trí công việc khác như Series Director (đạo diễn series phim), Storyboarder (họa sĩ vẽ storyboard),  Art Director (giám đốc nghệ thuật),…

Những nội dung trên chỉ mới là một phần của cả một giới 3D Artist, là một dân 3D Artist sẽ cần phải biết và tìm tòi thêm rất nhiều thứ. Một 3D Artist cần phải trãi qua quá trình học tập từng bước, từng chi tiết để trãi nghiệm những gì đã học liên quan trong nghề 3D Artist. 

Intern: Trương Thị Hồng Anh

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

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

Format (Làm đẹp) code php trong VS Code

format code php

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

Chào các bạn,

Đây là bài viết tiếp theo của bài Code PHP chuẩn convention với PHP CodeSniffer. Trong bài này, mình sẽ hướng dẫn các bạn auto check lỗi và format code PHP trong Vs Code – một trong những code editor được yêu thích nhất hiện nay.

Lưu ý, để hiểu bài viết này hơn, thì bạn cần đảm bảo các yêu cầu sau:

  • Máy tính đã cài composer ở dạng global.
  • Máy tính đã cài PHP CodeSniffer ở dạng global.
  • Bạn hiểu ý nghĩa của 2 công cụ phpcs và phpcbf.
  • Bạn hiểu ý nghĩa của file cấu hình phpcs.xml trong dự án.

Nếu không, hãy đọc phần trước của bài viết này, tại đó mình có cung cấp các nội dung hữu ích về các yêu cầu trên.

  10 Frameworks tốt nhất hiện nay cho PHP
  4 lý do để VS Code là Text Editor ưa thích của mọi lập trình viên

I. GIỚI THIỆU VỀ TÍNH NĂNG FORMAT CODE TRONG VS CODE

Giống như nhiều editor khác, VS Code có tính năng tự động format code của bạn cho chuẩn hơn.

Hình ảnh mượn tạm từ một nguồn khác phambinh.net 

Phím tắt để format code trên VS Code tương ứng với từng hệ điều hành như sau:

  1. Trên Windows: Shift + Alt + F.
  2. Trên Mac: Shift + Option + F.
  3. Trên Linux: Ctrl + Shift + I.

Tuy nhiên, mặc định thì VS Code không tích hợp sẵn việc format code PHP, mà chúng ta phải cài thêm từ extension bên ngoài, và mình sẽ hướng dẫn các bạn cài ở ngay mục phía dưới đây.

II. FORMAT CODE PHP TRONG VS CODE VỚI PHP SNIFFER & BEAUTIFIER

Mình đã dùng thử khá nhiều extension format code PHP, thì thấy có thằng PHP Sniffer & Beautifier này là dễ dùng và dễ tùy biến nhất. Để cài đặt extension này, các bạn vào mục Extensions của VS Code, tìm kiếm với từ khóa là “Sniffer & Beautifier” sẽ ra.

Cách tìm và cài đặt extension trong VS Code

Chúng ta tiến hành cài đặt bình thường như các extension khác, và sau khi cài đặt xong, thì hãy đi đến phần cài đặt riêng của extension này như hình dưới.

Đi đến trang cài đặt riêng cho extension

Tại trang cài đặt riêng của extension Sniffer & Beautifier, có 3 thông tin setting quan trọng là Allowed Auto RulesetsExecutable Path CBF và Executable Path CS. Mình sẽ hướng dẫn các bạn các cấu hình các thông tin này sao cho phù hợp ngay sau đây.

Các setting quan trọng

2.1 Cấu hình thông tin Allowed Auto Rulesets

Tại mục (1) như trong hình, hãy bấm vào Edit in settings.json, và đảm bảo ở phpsab.allowedAutoRulesets được cấu hình như sau:

Để dễ copy, thì mình viết các value ra đây nhé:

1
2
3
4
5
6
7
8
9
10
11
12
{
    // ...
    "phpsab.allowedAutoRulesets": [
        ".phpcs.xml",
        ".phpcs.xml.dist",
        "phpcs.xml",
        "phpcs.xml.dist",   
        "phpcs.ruleset.xml",
        "ruleset.xml"
    ],
    // ...
}

2.2 Cấu hình 2 thông tin Executable Path CBF và Executable Path CS

Tại mục (2) như trong hình, chúng ta cần điền đường dẫn tới 2 công cụ là phpcbf và phpcs. Mình sẽ hướng dẫn các bạn cách lấy thông qua mấy bước đơn giản dưới đây.

Chạy lệnh sau để lấy ra đường dẫn tới thư mục home của composer:

composer config --list --global | grep "home"

Kết quả sẽ có dạng như sau, và phần bôi đậm chính là đường dẫn bạn cần quan tâm.

Lưu ý: mỗi máy sẽ cho ra một kết quả khác nhau, và bên dưới là kết quả trên máy của mình

[home] /Users/admin/.composer

Sau khi có đường dẫn home, thì đường dẫn tới phpcs và phpcbf sẽ có dạng như sau:

# Đường dẫn tới phpcbf
/Users/admin/.composer/vendor/bin/phpcbf

# Đường dẫn tới phpcs
/Users/admin/.composer/vendor/bin/phpcs

Vậy là chúng ta đã có đường dẫn tới phpcbf và phpcs, giờ chỉ cần điền chúng lần lượt mục Executable Path CBF và Executable Path CS trong trang cài đặt của extension Sniffer & Beautifier là xong.

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

III. Dùng thử

Khởi tạo một dự án mới với 1 file phpcs.xml ở thư mục gốc, có rules theo PSR12 như sau:

1
2
3
4
<?xml version="1.0"?>
<ruleset name="PHP Standards">
    <rule ref="PSR12" />
</ruleset>

Tạo tiếp 1 file PHP có sẵn một vài lỗi convention:

1
2
3
4
5
6
7
8
9
<?php
// File này cố tình code sai convention
 
function sum ($a ,$b){
    return $a+$b;
}
 
echo sum(1,2);

Bật dự án lên bằng VS Code, và bạn sẽ thấy nó báo rất nhiều lỗi convention như sau:

Rất nhiều lõi convention được phát hiện

Và để fix hết các lỗi này, bạn chỉ cần Nhấn chuột phải chọn Format document, hoặc sử dụng tổ hợp phím format code như mình hướng dẫn ở đầu bài. Và dưới đây là kết quả sau khi format lại code, bạn sẽ thấy các lỗi convention trên đã được fix.

Các lỗi convention đã được fix.

Công việc tích hợp Sniffer & Beautifier vào VS Code để format code PHP đến đây là kết thúc, chúc các bạn thử nghiệm thành công.

Hẹn gặp lại bạn trong các bài viết tiếp theo.

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

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

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

Kinh Nghiệm Phỏng Vấn Dành Cho Các IT Support Tương Lai

kinh nghiệm phỏng vấn it support
Kinh Nghiệm Phỏng Vấn Dành Cho Các IT Support Tương Lai

IT Support là một công việc hấp dẫn trên thị trường việc làm công nghệ hiện nay. Nhiều bạn trẻ lựa chọn theo đuổi vị trí này với mong muốn được gắn bó và phát triển trong một môi trường làm việc tốt hơn, thu nhập và cơ hội nghề nghiệp cũng hấp dẫn hơn. Nếu đang cân nhắc đến công việc này, việc tìm hiểu qua những câu hỏi phỏng vấn thường xuất hiện hay một số kinh nghiệm phỏng vấn IT Support từ người đi trước là rất cần thiết. Trau dồi thêm kỹ năng với bài viết này nhé!

kinh nghiệm phỏng vấn it support
Colleagues on coffee break. Side view of cheerful young man and woman sitting at the table and chatting while man holding cup of hot drink

Một số câu hỏi thường xuyên xuất hiện khi phỏng vấn IT Support

1. Điểm mạnh, điểm yếu trong quá trình làm việc của bạn là gì?

Đây là câu hỏi gần như luôn xuất hiện ở bất cứ buổi phỏng vấn cho vị trí công việc nào. Đối với công việc IT Support đây càng là yếu tố quan trọng vì bạn phải thường xuyên tiếp xúc với khách hàng cũng như đàm phán công việc với các phòng ban liên quan.

Để trả lời tốt câu hỏi này với vai trò là một IT Support tương lai, điểm mạnh bạn nên nêu ra có thể là khả năng xử lý vấn đề, nhanh nhạy trong việc nắm bắt các sai sót và tìm cách khắc phục, linh hoạt cũng như có kỹ năng giao tiếp tốt.

Điểm yếu bạn có thể chia sẻ thành thật với nhà tuyển dụng và chắc chắn phải nói được cách mà bạn đang cố gắng để khắc phục điều này. Không có ai hoàn hảo, do đó yếu điểm chắc chắn sẽ xuất hiện, quan trọng là cách bạn khắc phục và cải thiện nó như thế nào. Nhà tuyển dụng sẽ đánh giá cao điều đó.

Xem thêm IT Support Là Làm Gì? Phát Triển Sự Nghiệp Với Vị Trí IT Support

2. Bạn đã có kinh nghiệm làm việc liên quan đến công việc IT Support chưa?

Với câu hỏi này, nhà tuyển dụng sẽ biết được bạn đã có kinh nghiệm làm việc trước đây chưa cũng như những kỹ năng mà bạn có có đáp ứng được yêu cầu của công ty với vị trí này không. Vẫn là điều quan trọng nhất trong mọi cuộc phỏng vấn, hãy thành thật. Kể cả bạn chưa có kinh nghiệm hay kinh nghiệm chưa đủ nhiều thì cũng hãy chia sẻ thành thật.

Điều quan trọng là tâm thế sẵn sàng học hỏi của bạn sẽ giúp nhà tuyển dụng đánh giá cao thái độ và có hướng đào tạo phù hợp thay vì nói quá đà về những gì mình có. Nhà tuyển dụng là những người đi trước và họ đủ năng lực để nhận biết những gì bạn nói có trung thực khi trả lời phỏng vấn hay không.

kinh nghiệm làm IT Support
Một số câu hỏi phỏng vấn vị trí IT Support

3. Theo bạn, đâu là yếu tố giúp bạn thành công với chuyên môn hiện tại của mình?

Đây là một câu hỏi rất hay để nhà tuyển dụng có thể xác định được mục tiêu và khoảng thời gian gắn bó của bạn với công việc của mình. Không có một khuôn mẫu chung hoàn hảo nào cho những câu hỏi như thế này, bạn hãy chia sẻ về hành trình theo đuổi đam mê của mình hay lí do tại sao bạn lại chọn gắn bó với công việc IT Support cho đến thời điểm hiện tại.

Song song với quá trình đó, bạn đừng quên chia sẻ những thành tựu mình đã đạt được trong suốt thời gian làm việc của mình. Và nhấn mạnh đâu là yếu tố giúp bạn có được những thành tựu đó, cũng như trong thời gian tới bạn sẽ làm những gì để đạt được những mục tiêu cao hơn. Điều đó không chỉ cho thấy ước mơ mà còn thể hiện cả sự nhiệt huyết của bạn với công việc của mình.

  IT Support Là Làm Gì? Phát Triển Sự Nghiệp Với Vị Trí IT Support
  Mẫu bảng mô tả công việc của IT Support

4. Bạn hiểu biết như thế nào về công việc IT Support và tại sao bạn lại chọn ngành nghề này?

Dường như khi đã ứng tuyển vào vị trí IT Support, ít nhiều ứng viên đều đã tìm hiểu trước và có sự hiểu biết nhất định với ngành mình mong muốn làm việc. Do đó đây có thể là câu hỏi khiến nhiều người cảm thấy đơn giản và không chuẩn bị nhiều, nhưng sự chuẩn bị chưa bao giờ là dư thừa. Hiểu biết càng nhiều càng cho nhà tuyển dụng thấy được sự nghiêm túc và tâm huyết của bạn trong công việc. Không chỉ là IT Support nói chung mà nếu có thể, hãy tìm hiểu thêm về vị trí này tại công ty đang ứng tuyển, nhà tuyển dụng sẽ đánh giá rất cao điều này.

Với câu hỏi về lý do tại sao bạn lại chọn ngành nghề này, bạn có thể dùng đam mê và những tính cách thích hợp của mình với công việc để chia sẻ với người phỏng vấn. IT Support đòi hỏi khả năng xử lý công việc và giải quyết các vấn đề một cách trôi chảy để đảm bảo sự vận hành trôi chảy của công ty. Bạn phải tham gia xử lý các vấn đề liên quan đến internet, mạng máy tính, phần mềm, phần cứng, các vấn đề về bảo mật thông tin,…

phỏng vấn IT Support

Các kinh nghiệm phỏng vấn IT Support nên cân nhắc

Để chuẩn bị cho một cuộc phỏng vấn thành công nhất, ngoài các vấn đề liên quan đến chuyên môn công việc của mình, bạn cũng đừng quên tìm hiểu thêm các thông tin về công ty như hoạt động, sản phẩm và phòng ban mình làm việc nếu có thể. Việc này sẽ rất hữu ích cho quá trình trả lời các câu hỏi của nhà tuyển dụng cũng như giải đáp được các thắc mắc của bạn khi cần.

Xem thêm các chương trình tuyển dụng IT Support lương cao trên TopDev

Ngoài ra cũng đừng quên chuẩn bị kỹ lưỡng cho vẻ ngoài của mình để tạo ấn tượng tốt trong mắt nhà tuyển dụng. Không cần quá cầu kỳ, chỉ cần đảm bảo một bộ trang phục sạch sẽ mà vẻ ngoài gọn gàng là đủ. Và đừng quên đến đúng giờ hẹn và chuẩn bị đủ các giấy tờ cần thiết theo yêu cầu công ty khi đi phỏng vấn.

Như bất cứ vị trí nào khác, để phỏng vấn thành công cho vị trí IT Support, hãy có sự đầu tư chất lượng và kỹ càng. Hi vọng một số thông tin được chia sẻ trong bài viết sẽ giúp bạn có thêm kinh nghiệm phỏng vấn IT Support. Đón đọc thêm nhiều chia sẻ với các chủ đề khác nhau cùng topdev.vn/blog nhé!

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

Xem thêm tuyển dụng việc làm IT hấp dẫn trên TopDev

PHP 8 có gì mới?

điểm mới của php 8
PHP 8 có gì mới?

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

Chào anh em,

PHP đã chính thức phát hành phiên bản 8.0 (26/11/2020), với nhiều cải tiến mới cả về hiệu năng lẫn cũ pháp. Trong bài viết này, chúng ta cùng review các điểm thay đổi có trong PHP 8 nhé.

Trích lời dẫn trên trang chủ PHP.net

PHP 8.0 là một phiên bản cập nhật lớn của PHP. Phiên bản này bao gồm rất nhiều tính năng mới, đồng thời tối ưu cách truyền tham số (có thể đặt tên khi truyền tham số), union types (một biến có thể thuộc một vài kiểu dữ liệu), attributes, constructor, biểu thức match (cú pháp mới, gần giống switch case), toán tử nullsafe (cho phép truy xuất giá trị null một cách an toàn), JIT (trình biên dịch mới, giúp PHP 8 đạt hiệu năng cao), và cải tiến các về type system, xử lý lỗi, và tính nhất quán.

Chúng ta sẽ tìm hiểu lần lượt về các sự thay đổi của PHP 8 so với phiên bản trước lần lượt qua các mục dưới đây.

  Cách thiết lập JIT trong PHP 8
  Callback trong PHP là gì?

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

I. TRUYỀN THAM SỐ THEO TÊN GỌI – PHP 8

Việc một function có nhiều tham số (với mình là từ 3 tham số trở nên), có thể khiến developer lúng túng khi sử dụng vì không nhớ rõ ý nghĩa của từng tham số, cũng như thứ tự truyền của chúng.

Ví dụ, function mkdir() (function giúp tạo thư mục) trong PHP có 4 tham số lần lượt là:

  • $directory: Bắt buộc, là đường dẫn để tạo thư mục
  • $permissions: Không bắt buộc, là khả năng truy cập vào thư mục (kiểu 0777, hay 0655), mặc định là 0777.
  • $recursive: Không bắt buộc, có cho phép tạo thư mục con ngay cả khi thư mục cha không tồn tại (cho phép tạo kiểu đệ quy), mặc định là false.
  • $context: Không bắt buộc, còn ý nghĩa là gì thì mình cũng chẳng hiểu lắm, chưa bao giờ dùng đến tham số này.

Các vấn đề mà một developer có thể gặp phải khi sử dụng mkdir() đó là:

  • Đôi khi không nhớ rõ thứ tự của 2 tham số $permissions và $recursive, không biết tham số nào được viết trước.
  • Nếu muốn đổi giá trị của tham số $recursive từ false thành true, developer buộc phải truyền cả tham số $permissions (vì $permissions đứng trước $recursive).

Cả hai vấn đề trên đều gây bất tiện khi sử dụng, để khắc phục nó, thì PHP cung cấp cú pháp mới cho phép truyền tham số theo tên gọi:

<?php // PHP 7.x mkdir('./hello/world', 0777, true); // PHP 8 mkdir(recursive: true, directory: './hello/world'); // Hoặc mkdir('./hello/world', recursive: true);

Lưu ý:
– Đây chỉ là cú pháp mới mà PHP 8 cung cấp để tiện sử dụng hơn khi cần, còn bạn vẫn có thể sử dụng cú pháp cũ bình thường trên phiên bản PHP 8 này.

– Tên tham số bạn không được phép “tự nghĩ ra” mà phải tuân theo tài liệu của PHP. Như trong ví dụ trên, recursive và directory là 2 tham số mà mình buộc phải tuân theo tài liệu mà PHP cung cấp.

Để xem “tên chuẩn” các tham số, có 2 cách:

Cách 1: Xem tài liệu chính thức trên trang chủ php.net (lưu ý phải xem trên trang chính thức, các trang khác có thể viết không đúng).

Cách 2: Sử dụng ReflectionFunction.

<?php // Muốn xem chi tiết các tham số của function mkdir $refFunc = new ReflectionFunction('mkdir'); foreach ($refFunc->getParameters() as $param) {     print $param . PHP_EOL; } /* Output Parameter #0 [ <required> string $directory ] Parameter #1 [ <optional> int $permissions = 0777 ] Parameter #2 [ <optional> bool $recursive = false ] Parameter #3 [ <optional> $context = null ] */

Lưu ý siêu quan trọng

Khuyên bạn nên sử dụng Cách 2 là chính xác nhất, Cách 1 không hẳn sẽ chính xác với mọi function. Như function mkdir trong ví dụ trên, thì tài liệu PHP viết sai 2 tên tham số là pathname và mode, đáng lẽ nó phải là directory và permissions mới đúng.

Tài liệu PHP ghi sai tên tham số, đáng lẽ phải là directory và permissions mới đúng.

II. TỐI GIẢN CÁCH SET THUỘC TÍNH TỪ CONTRUCTOR – PHP 8

Việc khởi tạo giá trị cho thuộc tính trong contructor của PHP 7 thường được viết như sau:

<?php // PHP 7 class Point {   public float $x;   public float $y;   public float $z;   public function __construct(     float $x = 0.0,     float $y = 0.0,     float $z = 0.0,   ) {     $this->x = $x;     $this->y = $y;     $this->z = $z;   } }

Nhưng với PHP 8, bạn có thể viết ngắn gọn thành

<?php // PHP 8 class Point {   public function __construct(     public float $x = 0.0,     public float $y = 0.0,     public float $z = 0.0,   ) {} }

III. UNION TYPES – PHP 8

PHP ngày càng hoàn thiện hơn về độ chặt chẽ của dữ liệu, trong phiên bản PHP 7.4, chúng ta có thể khai báo kiểu dữ liệu cho thuộc tính của lớp, tuy nhiên nó vẫn gặp một vài bất tiện. Nhưng bất tiện này đã khắc phục trong phiên bản 8 với khái niệm Union types – Cho phép một thuộc tính có thể thuộc nhiều kiểu dữ liệu.

<?php // PHP 7 class Number {     // Giả sử có một biến $numeber, và ta mong muốn nó ở dạng số     // Số thì có nhiều kiểu, số nguyên, số thập phân.     private $number;     // Nhưng hơi buồn     // Chúng ta không thể chỉ ra biến $number chỉ được phép thuộc dạng số với PHP 7     public function __construct($number)     {         $this->number = $number;     } } // Dẫn đến việc khởi tạo class, ta vẫn có thể truyền string như thường // Và không gặp một lỗi nào cả new Number('NaN'); // PHP 8 class Number {     // PHP 8 cho phép bạn khai báo biến $number chỉ được phép thuộc một trong 2 kiểu dữ liệu int hoặc float     // Khắc phục vấn đề của PHP 7 nêu trên     public function __construct(         private int|float $number     ) {} } // Nếu dùng thế này, bạn sẽ gặp lỗi new Number('NaN');

IV. NULLSAFE OPERATOR – PHP 8

Nullsafe operator – tạm dịch là Toán tử null an toàn. Cho phép bạn truy cập vào giá trị của một thuộc tính ở giá trị null mà không bị lỗi.

Ở các phiên bản PHP trước, để chắc chắn trước khi truy cập vào một giá trị, ta thường kiểm tra nó khác null để tránh lỗi, và nhìn nó có vẻ dài dòng như sau:

<?php $country =  null; if ($session !== null) {   $user = $session->user;   if ($user !== null) {     $address = $user->getAddress();     if ($address !== null) {       $country = $address->country;     }   } }

Nhưng với PHP 8, bạn có thể rút gọn thành:

<?php $country = $session?->user?->getAddress()?->country;

Khi bất kỳ thuộc tính nào trong “chuỗi” $session?->user?->getAddress()?->country là null, thì $country sẽ nhận giá trị là null và không có lỗi nào xảy ra.

V. BIỂU THỨC MATCH – PHP 8

Một biểu thức mới khá tương đồng với lệnh switch case được đưa vào trong phiên bản PHP 8 lần này là match, nhưng có một số điểm khác biệt sau:

  • match là một biểu thức, nghĩa là giá trị của nó có thể được trả về, bạn có thể dễ dàng lưu nó vào một biến để xử lý cho tiện.
  • Mỗi một nhánh của match chỉ được xử lý trên một dòng, nghĩa là bạn không cần break
  • match so sánh chặt chẽ về kiểu dữ liệu, giống như bạn so sánh sử dụng === vậy.

Bạn có thể xem ví dụ sau để hiểu rõ hơn:

<?php // PHP 7 switch (8.0) {   case '8.0':     $result = "Oh no!";     break;   case 8.0:     $result = "This is what I expected";     break; } echo $result; // Oh no! // PHP 8 $result = match (8.0) {   '8.0' => "Oh no!",   8.0 => "This is what I expected", }; echo $result; // This is what I expected

Lưu ýmatch khá tương đồng với switch case, nhưng không thể thay thế hẳn switch case.

VI. TRÌNH BIÊN DỊCH JIT – PHP 8

Hiểu nhanh thì JIT (Just In Time) là một kỹ thuật được PHP tích hợp vào việc biên dịch code PHP thành mã máy, giúp PHP 8 đạt được hiệu năng cao gấp 1,5 – 2 lần so với PHP 7. Nhưng đừng vội mừng, hãy xem biểu đồ dưới đây và mình sẽ giải thích cho bạn hiểu:

Biểu đồ so sánh tốc độ của PHP khi có JIT và không có JIT.

Trong biểu đồ trên:

  • bench.php, micro_bech.php, N-body, Mandelbrot đều là các bài test trên ứng dụng PHP đơn giản.
  • Các bài test còn lại, lần lượt test trên các ứng dụng PHP có độ phức tạp tăng dần.
  • Đường màu đen, kẻ dọc ở biểu đồ trên là ngưỡng tối đa khi PHP không sử dụng JIT.

Từ biểu đồ trên, rút ra nhận xét rằng:

Chỉ có ứng dụng PHP đơn giản khi áp dụng JIT mới có hiệu năng cao, còn các ứng dụng PHP phức tạp, sử dụng các framework, cms phổ biến như WordPress, Symfony (Chắc laravel cũng không ngoại lệ) thì sử dụng JIT lại không đem lại nhiều lợi ích. Thậm chí như trường hợp của Symfony khi áp dụng JIT còn làm ứng dụng chạy chậm hơn so với lúc không áp dụng.

Để nói hết về JIT thì bài viết này là chưa đủ, mình sẽ trình bày chi tiết ở một bài viết khác về cách cài đặt, ưu nhược điểm, cũng như phân tích nên dùng JIT trong dự án thực tế hay không.

VII. MỘT SỐ CẬP NHẬT KHÁC TRÊN PHP 8

Một số cập nhật điển hình khác trên PHP 8 như sau:

  • Thay vì sử dụng PHPDoc để chú thích, PHP 8 đã cung cấp thêm cấu trúc metadata.
<?php // PHP 7 class PostsController {     /**      * @Route("/api/posts/{id}", methods={"GET"})      */     public function get($id) { /* ... */ } } // PHP 8 class PostsController {     #[Route("/api/posts/{id}", methods: ["GET"])]     public function get($id) { /* ... */ } }
  • Toán tử @ vốn để “câm lặng lỗi” không còn được sử dụng ở PHP 8.
<?php // Khi thêm @ phía trước, nếu function có thực hiện lỗi cũng sẽ không báo lỗi // Nhưng đó đã là quá khứ rồi. // Ở PHP 8 vẫn báo lỗi bình thường @unlink('hello/world');
  • Cụm try {} catch () {} có thể không cần biến $exception trong catch.
<?php // PHP 7 try {     1/0; } catch (\Exception) { // Sẽ báo lỗi cú pháp ở dòng này     die('Something wrong'); } // PHP 8 try {     1/0; } catch (\Exception) { // Chạy bình thường     die('Something wrong'); }
  • Cho phép dấu phẩy ở cuối danh sách tham số.
<?php // PHP 7 class Uri {     private function __construct(         ?string $scheme,         ?string $user,         ?string $pass,         ?string $host,         ?int $port,         string $path,         ?string $query,         ?string $fragment // <-- Tham số cuối cùng không được phép có dấu phẩy     ) {         ...     } } // PHP 8 class Uri {     private function __construct(         ?string $scheme,         ?string $user,         ?string $pass,         ?string $host,         ?int $port,         string $path,         ?string $query,         ?string $fragment, // <-- Được phép viết dấu phẩy ở tham số cuối cùng     ) {         ...     } }

VIII. TỔNG KẾT

Trên là những cập nhật điển hình nhất của PHP 8, và bài viết của mình đã nêu được khoảng 80% những gì PHP cập nhật trong phiên bản lần này. Nếu muốn tìm hiểu chi tiết, bạn có thể đọc từ tài liệu chính thức của PHP.

Xin chào, hẹn gặp lại.

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

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

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

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

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

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

Để làm việc với Apache Kafka, các bạn cần nắm một số khái niệm cơ bản về:

  • Producer
  • Consumer
  • Broker
  • Cluster
  • Topic
  • Topic Partitions
  • Partition Offset
  • Consumer Group
  Apache Kafka là gì?
  Cài đặt Apache Kafka sử dụng Docker Compose

Xem thêm tuyển dụng UI UX Designer hấp dẫn trên TopDev

Producer

Producer là những application produce data và gửi data tới Apache Kafka Server. Data này sẽ là những message có định dạng, được gửi dưới dạng mảng byte tới Apache Kafka server. Ví dụ như các bạn có một tập tin .txt chứa text bên trong, chúng ta có thể dùng Producer để đọc từng dòng trong tập tin này rồi gửi tới Apache Kafka server.

Consumer

Consumer là những application nhận message từ Apache Kafka server với message được gửi từ Publisher. Consumer cần phải subcribe vào một topic nào đó của Apache Kafka server để có thể nhận được tất cả các message được emit vào topic này.

Sau khi nhận được data, Consumer có thể thêm code để xử lý data theo nhu cầu của mình.

Broker

Broker là Apache Kafka server, là cầu nối giữa Message Publisher và Message Consumer, giúp chúng có thể trao đổi message với nhau.

Cluster

Cluster là một group các Brokers hay nói cách khác là group các Apache Kafka server.

Topic

Topic được định nghĩa trong Apache Kafka server, là nơi để Publisher send data và cũng là nơi để Consumer subscribe để nhận data từ Publisher. Sử dụng topic giúp Apache Kafka phân loại được message và Consumer cũng biết là mình lấy data từ đâu.

Topic Partitions

Apache Kafka là một distributed messaging system và chúng ta có thể setup Apache Kafka server với cluster. Trong trường hợp một topic nhận quá nhiều message tại cùng một thời điểm, chúng ta có thể chia topic này thành những partitions được share giữa các Apache Kafka server với nhau trong một cluster được handle các message này.

Một partition sẽ small và independent với các partitions khác. Số lượng partition cho mỗi topic thì tuỳ theo nhu cầu của ứng dụng mà chúng ta có thể quyết định.

Partition Offset

Trong một topic partition, các message sẽ được lưu trữ và đánh dấu theo từng offset. Mỗi khi một message mới vào topic, Apache Kafka server sẽ quyết định message này nằm trong partition nào, offset nào của partition đó. Giá trị của các offset sẽ tăng dần trong một partition và chỉ available cho một Apache Kafka server.

Để lấy được một message trong Apache Kafka server, chúng ta cần chỉ định rõ topic name, partition number và offset number.

Consumer Group

Consumer group là một group các Consumer consume message từ Apache Kafka server. Mỗi một Consumer Group sẽ share với nhau việc handle messsage.

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

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

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

PHP Developer là gì? Lộ trình trở thành PHP Web

php developer
Lộ trình trở thành PHP web developer

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

Hello các bạn,

Trong bài viết này mình sẽ chia sẻ với các bạn lộ trình để trở thành PHP web developer. Thực ra mình không rõ nên coi nội dung dưới đây là lộ trình, là kỹ năng, hay kiến thức nữa, nhưng đại loại nếu bạn muốn trở thành PHP web developer thì nội dung dưới đây sẽ có ích với bạn.

I. PHP WEB DEVELOPER LÀ GÌ

Tìm hiểu qua một chút về “cái đích” mà chúng ta sẽ hướng đến, thì PHP web developer là tên một nghề liên quan đến công việc lập trình web. Trong đó PHP là tên ngôn ngữ lập trình, web developer tạm dịch là “Người phát triển web”, vậy PHP web developer thì hiểu là “Người phát triển web sử dụng ngôn ngữ PHP” (Ngoài PHP thì còn nhiều ngôn ngữ khác cũng làm được web).

Ok, dễ hiểu đúng không. Nhưng thực ra, cái tên “PHP web developer” thì là cách gọi vắn tắt của “PHP/JavaSctipt/HTML/CSS/bla bla,… web developer“, nghĩa là để trở thành PHP web developer thì bạn cần phải học rất nhiều thứ, và PHP chỉ là một trong số chúng.

  10 PHP Instagram Scripts & Widgets tốt nhất
  Câu chuyện trước khi PHP có composer

Xem thêm tuyển dụng PHP lương cao trên TopDev

Giới thiệu thêm

Để tạo ra một trang web, bạn sẽ cần các kiến thức:
– Kiến thức về HTML/CSS/JavaScript: Dùng để tạo giao diện trang web.
– Kiến thức về ngôn ngữ lập trình: Dùng để xử lý các tính năng có trên trang web (hiểu nôm na là vậy), và PHP là một ngôn ngữ lập trình.
– Kiến thức về cơ sở dữ liệu: Là nơi lưu trữ dữ liệu cho trang web. PHP thường kết hợp MySQL – một loại cơ sở dữ liệu.
– Kiến thức về webserver: Là máy chủ để chạy web, Apache và Nginx là 2 loại web server phổ biến.

Bạn thấy không, có phải mỗi PHP đ*o đâu, cả mớ kiến thức đấy chứ. Mà đấy mới chỉ là “phần nổi của tảng băng” thôi đó, phần chìm mình sẽ liệt kê chi tiết trong bài viết, mà nói trước là mình cũng không thể liệt kê hết được vì nó quá nhiều.

II. QUY ƯỚC

Các kiến thức được chia thành 3 level: Hiểu, Biết sử dụng, Sử dụng thành thạo. Trong đó:

  • Hiểu: Đã từng tiếp xúc với kiến thức đó, hiểu ý nghĩa và vai trò, đã từng làm một số ví dụ đơn giản. Mức này rất dễ đạt được.

Tôi Hiểu PHP, vì tôi biết nó phù hợp với các dự án web, tôi cũng từng làm một dự án nhỏ về website tin tức sử dụng PHP để hiểu hơn về nó.

  • Biết sử dụng: Bao gồm Hiểu và đã từng áp dụng kiến thức đó trong một dự án cụ thể, dự án được áp dụng phải đủ lớn, đủ nghiêm túc, không phải là các pet project.
    Lưu ý: Một số từ khác trong bài viết như Biết thiết kếBiết tối ưuBiết vận dụngBiết làm cũng tương đồng với Biết sử dụng.

Tôi biết sử dụng PHP, vì tôi từng sử dụng nó trong một dự thực tế. Tuy đây chỉ là dự án cá nhân, nhưng tôi hoàn thiện nó với thái độ nghiêm túc, cố gắng hoàn thiện ở mức cao nhất có thể. Trong quá trình hoàn thành dự án, tôi vẫn học được thêm nhiều kiến thức mới.

  • Sử dụng thành thạo: Bao gồm Biết sử dụng và lặp đi lặp lại trong một vài dự án, trong quá trình lặp lại không (hoặc ít) học được thêm kinh nghiệm mới.

Tôi sử dụng thành thạo PHP, vì tôi từng tham gia vào nhiều dự án thực tế sử dụng PHP, trong quá trình đó, tôi không (hoặc ít) học được thêm kiến thức mới về PHP.

Nếu so với tháp Bloom trong bài viết Kinh nghiệm làm việc được tính như thế nào, thì:

  • Level Hiểu trong bài viết này tương ứng với level Hiểu của tháp Bloom.
  • Level Biết sử dụng tương ứng với level Vận dụng của tháp Bloom.
  • Level Sử dụng thành thạo tương ứng từ Level Phân tích trở lên của tháp Bloom.

III. LỘ TRÌNH

Lưu ý:
– Lộ trình dưới đây chưa được kiểm chứng, mà chỉ được đúc kết từ kinh nghiệm cá nhân của mình.
– Lộ trình dưới đây đã được mình tối ưu (không quá ngắn cũng không quá dài), đảm bảo phù hợp với nhu cầu tuyển dụng hiện tại.
– Lộ trình dưới đây sẽ được cập nhật thường xuyên.

Level 1: Nhập môn lập trình

Đây là kiến thức cơ bản nhất mà bất kỳ lập trình viên nào cũng phải biết, chứ không riêng web developer:

  • Biết sử dụng ít nhất một ngôn ngữ lập trình.
  • Biết sử dụng một số giải thuật cơ bản: sắp xếp nhanh (quick sort), sắp xếp nổi bọt, tìm kiếm nhị phân, tìm kiếm tuần tự.
  • Biết sử dụng một số cấu trúc dữ liệu cơ bản: stack, queue, linked list.
  • Biết sử dụng lập trình hướng đối tượng.
  • Hiểu một số quy trình phát triển phần mềm: quy trình thác nước, agile/scrum.

Level 2: Nhập môn lập trình web

Đây là các kiến thức mà bất kỳ web developer nào cũng phải biết:

  • Biết sử dụng HTML, CSS, JavaScript.
  • Biết sử dụng một số thư viện web cơ bản: jQuery, bootstrap.
  • Biết sử dụng PHP.
  • Biết sử dụng ít nhất một database quan hệ, gợi ý bạn nên học MySQL.
  • Biết thiết kế database quan hệ (chuẩn 3NF, phi chuẩn, index trong database).
  • Biết chuyển giao diện từ file thiết kế sang giao diện web (biết cắt html).
  • Biết sử dụng mô hình MVC trong lập trình web.
  • Biết sử dụng một số design pattern phổ biến: singleton, factory.
  • Hiểu về cách hoạt động của trang web: backend, frontend, client side, server side, request, response, header.
  • Sử dụng thành thạo coding convention trong PSR.
  • Biết sử dụng CLI.
  • Biết sử dụng một số tool trên CLI: npm, composer.
  • Biết sử dụng Restful API.
  • Hiểu về UI, UX.
  • Biết sử dụng GIT.
  • Biết sử dụng wordpress.
  • Biết sử dụng ít nhất một PHP framework, gợi ý bạn nên học Laravel.
  • Hiểu về một số lỗi bảo mật: xss, csrf, sql injection.
  • Hiểu về SEO.
  • Hiểu về SOLID.

Đang cập nhật thêm…

Level 3: Lập trình web chuyên sâu

Đạt tới “cảnh giới” này, bạn có thể lựa chọn 1 trong 3 hướng phát triển dưới đây:

2.1 Frontend developer

Frontend developer là những người làm về mặt giao diện, trải nghiệm, tương tác của trang web. Bất kể menu, màu chữ, font chữ, các modal bật lên, đóng lại,… tóm lại là những thứ mà người dùng có thể nhìn thấy đều được coi là frontend và đều là công việc của frontend developer.

  • Sử dụng thành thạo HTML, CSS và JS.
  • Sử dụng thành thạo ít nhất một frontend framework: reactjs, angular, vuejs.
  • Sử dụng thành thạo ít nhất một css preprocessor như scss, PostCSS.
  • Sử dụng thành thạo ít nhất một tool build frontend, gợi ý bạn nên chọn webpack.
  • Biết tối ưu SEO.
  • Biết thiết kế UI/UX.
  • Sử dụng thành thạo css BEM rules.

Đang cập nhật thêm…

Tìm việc làm Frontend ngay

2.2 Backend developer

Nếu frontend được thể hiện ngoài giao diện – cái mà người sử dụng có thể dễ dàng nhìn thấy và cảm nhận, thì backend lại là “trái tim” nằm phía sau, âm thầm xử lý các tác vụ mà người dùng thực hiện.

Frontend có thể dễ dàng vẽ lên một cái nút “Đăng nhập”, nhưng bấm vào cái nút đó là hàng loại các thao tác tìm kiếm, kiểm tra, xác minh được thực hiện phía backend.

  • Sử dụng thành thạo PHP
  • Sử dụng thành thạo ít nhất một database, gợi ý bạn nên học MySQL.
  • Sử dụng thành thạo ít nhất một framework, gợi ý bạn nên chọn Laravel.
  • Sử dụng thành thạo lập trình hướng đối tượng.
  • Biết sử dụng Linux.
  • Biết sử dụng ELK stack.
  • Biết sử dụng docker.

Đang cập nhật thêm…

Tìm việc làm Backend ngay

3.3 Full stack developer

Về cơ bản, Fullstack developer là người có thể làm được hết (hoặc phần lớn) các công việc của cả Frontend developer và Backend developer.

  • Experience with Back-end API development by using one of the following programming languages: JavaScript (NodeJS), Java, Ruby, PHP, Python, C#, Golang or Scala
  • Have strong knowledge in REST API
  • Experience with JavaScript or TypeScript with ReactJS, Angular, or Vue. Docker, NoSQL database, Relational database, Scrum/Agile development methodologies

Tìm việc làm Fullstack Developer lương cao

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

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

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

Code PHP chuẩn convention với PHP CodeSniffer

code php
Code PHP chuẩn convention với PHP CodeSniffer

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

Chào các bạn,

Có lẽ không cần dài dòng, nếu chưa biết gì về coding convention thì mình đã có hẳn một bài viết xịn sò là Chuẩn coding convention trong PHP với PSR, bạn có thể tham khảo nếu thấy cần thiết. Còn trong bài viết này, mình sẽ hướng dẫn bạn cách sử dụng công cụ PHP CodeSniffer để kiểm tra convention tự động khi lập trình PHP.

  10 PHP Instagram Scripts & Widgets tốt nhất
  11 cách tăng tốc nhanh cho WordPress bằng file wp-conig.php

I. PHP CODESNIFFER LÀ GÌ?

Vài điểm Hightlight về PHP CodeSniffer như sau:

– PHP CodeSniffer gồm 2 công cụ chính là phpcs, và phpcbf. Trong đó phpcs là công cụ giúp bạn phát hiện lỗi coding convention, còn phpcbf là công cụ giúp bạn tự động tìm và sửa lỗi coding convention – đương nhiên là chỉ sửa được những gì mà nó có thể sửa.
– PHP CodeSniffer là một package PHP, có thể cài đặt bằng composer như nhiều package php bình thường khác, nó có thể cài đặt theo từng dự án, hoặc có thể cài global trên máy tính của developer.
– PHP CodeSniffer kiểm tra lỗi coding convention dựa trên các PSR, và nếu muốn bạn cũng có thể tự tắt/bật một số quy tắc của PSR để phù hợp với từng dự án, từng team phát triển.
– Bạn có thể dễ dàng tích hợp PHP CodeSniffer với các editor phổ biến như Sublime Text, VsCode,… trong bài viết này, mình cũng sẽ hướng dẫn các bạn các tích hợp với VsCode.

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

II. CÀI ĐẶT VÀ SỬ DỤNG PHP CODESNIFFER

2.1 Chuẩn bị

  • PHP 5.4 hoặc phiên bản cao hơn: PHP CodeSniffer được viết bằng PHP, nên máy của bạn chắc chắn cần được cài PHP. Kiểm tra phiên bản PHP bằng cách gõ php -v trên CLI của bạn.
  • Composer: Có nhiều cách để cài đặt PHP CodeSniffer, nhưng bạn nên cài thông qua Composer cho đơn giản, cũng như dễ dàng cập nhật PHP CodeSniffer khi có phiên bản mới. Mà mình nghĩ chẳng có php developer nào lại không có sẵn composer trên máy đâu. Kiểm tra composer đã có hay chưa bằng cách gõ composer trên CLI của bạn.

2.2 Cài đặt PHP CodeSniffer

Như mình đã trình bày, CodeSniffer có thể cài global hoặc cài theo từng dự án, trong bài viết này mình sẽ cài global luôn cho máu.

composer global require "squizlabs/php_codesniffer=*"

Sau khi cài xong, bạn cần tìm được thư mục home của composer, tùy vào từng hệ điều hành mà đường dẫn tới thư mục home sẽ khác nhau. Để tìm thư mục home, bạn chạy lệnh sau:

composer config --list --global | grep "home"

Kết quả sẽ dạng như sau:

[home] /Users/admin/.composer

Thì /Users/admin/.composer chính là thư mục home của composer.

Bước tiếp theo, cùng kiểm tra xem PHP CodeSniffer đã được cài đặt hay chưa, bằng cách chạy lệnh sau:

ls /Users/admin/.composer/vendor/bin

Nếu cài đặt thành công, thì sẽ có kết quả như sau:

phpcbf phpcs

2.3 Chạy thử PHP CodeSniffer

Đây là phần trọng tâm của bài viết, các bạn đọc cẩn thận và làm theo ví dụ nhé.

Tạo trước một file PHP và cố tình code sai convention, để thử xem thằng PHP CodeSniffer có nhận ra hay không.

cd ~ # di chuyển ra thư mục root
mkdir test_php_sniffer # tạo thư mục test_php_sniffer
cd test_php_sniffer # di chuyển vào thư mục vừa tạo
touch test.php # tạo file test.php

Copy nội dung sau bỏ vào file test.php

// File này cố tình code sai convention để thử độ tin cậy của PHP CodeSniffer

function sum ($a ,$b){
return $a+$b;
}

echo sum(1,2);

Chuẩn bị đã xong, giờ mình sẽ chạy lệnh sau để kiểm tra lỗi convention có trong file test.php trên.

cd test_php_sniffer # di chuyển vào thư mục chứa file test.php

/Users/admin/.composer/vendor/bin/phpcs test.php # chạy này

Chạy xong, trên terminal xuất hiện kết quả như sau:

FILE: /Users/admin/test_php_sniffer/test.php
--------------------------------------------------------------------------
FOUND 5 ERRORS AFFECTING 3 LINES
--------------------------------------------------------------------------
2 | ERROR | [ ] You must use "/**" style comments for a file comment
4 | ERROR | [ ] You must use "/**" style comments for a function comment
4 | ERROR | [x] Expected 0 spaces before opening parenthesis; 1 found
4 | ERROR | [x] Opening brace should be on a new line
8 | ERROR | [x] No space found after comma in argument list
--------------------------------------------------------------------------
PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY
--------------------------------------------------------------------------

Time: 51ms; Memory: 4MB

Kết quả trên có 2 chỗ cần chú ý:

  • FOUND 5 ERRORS AFFECTING 3 LINES: Phát hiện được 5 lỗi trên 3 dòng.
  • PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY: Nếu sử dụng phpcbf thì nó nó thể tự động fix được 3 lỗi.

Thử chạy nốt thằng phpcbf để xem nó tự động fix lỗi như thế nào nhé.

/Users/admin/.composer/vendor/bin/phpcbf test.php

Sau khi chạy xong lệnh trên, file test.php sẽ tự động được sửa lại, thành như sau:

Sau khi chạy phpcbf, nhưng vẫn còn tồn đọng một số lỗi convention

Đúng là code được sửa lại thật, nhưng có vẻ vẫn chưa đúng lắm, vẫn có 2 lỗi chưa fix được:

  • Dòng 4 vẫn bị sai convention ở dấu phẩy. Dấu phẩy phải nằm sát biến $a, và cách biến $b một dấu space mới đúng.
  • Dòng 6 vẫn bị sai convention ở dấu +. Phía trước và sau dấu + phải có một dấu space mới đúng.

– Ơ thế hóa ra thằng CodeSniffer này không được việc lắm nhỉ, có lỗi thì fix được có lỗi thì không?

– Không phải đâu nhé, là do mình chưa chỉ rõ chuẩn PSR cho nó thôi. Phần sau đây mình sẽ trình bày luôn.

Bạn tạo tiếp file tên là phpcs.xml ngang hàng với file test.php trên, có nội dung như sau:

<?xml version="1.0"?> <ruleset name="PHP Standards">
   <rule ref="PSR12" /> </ruleset>

Sau đó chạy lại lệnh phpcbf để fix lỗi:

/Users/admin/.composer/vendor/bin/phpcbf test.php

Sau đó cùng xem lại file test.php để xem nó được fix lỗi như thế nào.

Tất cả lỗi convention đã được fix

Bất ngờ chưa, các lỗi convention được fix hết luôn rồi kìa.

Fix được là do file phpcs.xml mình đã chỉ ra code được tuân theo chuẩn PSR12, nhờ đó mà thằng phpcbf sẽ biết đường mà fix theo chuẩn đó.

Qua ví dụ trên, mình đã chỉ các bạn đi qua một lượt các tính năng cơ bản của PHP CodeSniff, bạn có thể tìm hiểu chi tiết hơn ở wiki của PHP_CodeSniffer.

Bộ sưu tập áo thun cho dân IT, đủ các ngôn ngữ lập trình và hệ điều hành.
Click vào ảnh để xem.

III. LỜI KẾT

Bài viết này cũng khá dài rồi, nên mình tạm dừng ở đây, nhưng dự kiến sẽ còn 2 bài viết nữa xoay quanh thằng PHP CodeSniffer này. Một bài mình sẽ chia sẻ các rules trong file phpcs.xml, một bài mình sẽ chia sẻ cách tích hợp PHP_CodeSniffer với VsCode để vừa code vừa kiểm tra lỗi convention tiện lợi hơn. Hẹn gặp lại các bạn nhé.

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

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

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

Cài đặt FTP server sử dụng Docker

cài đặt fpt server
Cài đặt FTP server sử dụng Docker

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

Mình đã hướng dẫn các bạn cách cài đặt FTP server trên Ubuntu. Trong bài viết này, mình sẽ hướng dẫn các bạn cài đặt FTP server sử dụng Docker các bạn nhé!

Chúng ta sẽ sử dụng vsftpd Docker Image ở địa chỉ Docker Hub https://hub.docker.com/r/fauria/vsftpd/.

  20 trường hợp sử dụng lệnh Docker cho developer
  Cách thiết lập một dự án Symfony để làm việc với Docker Subdomains

Xem thêm các chương trình tuyển dụng PHP lương cao trên TopDev

Docker Image này expose nhiều biến môi trường khác nhau giúp chúng ta có thể cấu hình FTP server theo cách mình muốn, bao gồm:

  • FTP_USER
  • FTP_PASS
  • PASV_ADDRESS
  • PASV_ADDR_RESOLVE
  • PASV_ENABLE
  • PASV_MIN_PORT
  • PASV_MAX_PORT
  • XFERLOG_STD_FORMAT
  • LOG_STDOUT
  • FILE_OPEN_MODE
  • LOCAL_UMASK
  • REVERSE_LOOKUP_ENABLE
  • PASV_PROMISCUOUS
  • PORT_PROMISCUOUS

Chi tiết ý nghĩa của mỗi biến môi trường, các bạn có thể đọc thêm tại đây.

Mình sẽ sử dụng default value cho các biến môi trường này nên mình chỉ cần chạy command sau là có thể start được 1 FTP server:

docker pull fauria/vsftpd

và:

docker run -d -p 21:21 -v /Users/khanh/Documents/vsftpd:/home/vsftpd --name vsftpd fauria/vsftpd

Mình mapping thư mục trên máy của mình với thư mục /home/vsftpd để chúng ta có thể dễ dàng làm việc với data trên FTP server này.

Kết quả:

Như các bạn thấy, sau khi chạy docker run command thì mình cũng chạy thêm một command nữa là docker logs để xem thông tin mặc định mà Docker Image này khởi tạo khi chạy Docker Container từ nó. Các bạn có thể sử dụng thông tin username và password được hiển thị ở đây để đăng nhập và làm việc với FTP server, các bạn nhé!

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

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

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

Selenium IDE – Các câu lệnh kiểm tra

selenium ide
Selenium IDE – Các câu lệnh kiểm tra

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

Chào các bạn, như mình đã giới thiệu ở phần trước, Selenium IDE hầu như chỉ record lại những hành động của chúng ta trên trình duyệt. IDE không đủ thông minh để biết được chúng ta muốn kiểm tra những gì trên trang web đó. Bài này, mình sẽ giới thiệu với các bạn một số câu lệnh kiểm tra hay dùng trong Selenium IDE để kiểm tra các đối tượng UI trên trang web.

  Các kiểu “đợi chờ” trong Selenium Webdriver: Implicit wait, Explicit wait và Fluent wait
  Firefox profile preferences để download file với Selenium Webdriver

Xem thêm tuyển Data Science hấp dẫn trên TopDev

Selenium IDE – Tự động kiểm tra

Theo như mình biết thì hiện tại Selenium IDE chỉ hỗ trợ kiểm tra tiêu đề của trang web một cách tự động. Để làm được điều đó, chúng ta cần thiết lập cơ chế của IDE như sau:

B1: Mở Selenium IDE Options bằng menu item Options –> Options

B2: Kích hoạt chức năng “Record assertTitle automatically” trong thẻ General

tu dong kiem tra tieu de

Như vậy, khi chúng ta thực thi record với Selenium IDE, cứ mỗi trang mới được hiển thị, IDE sẽ tự động thêm dòng lệnh kiểm tra tiêu đề trang web cho chúng ta.

Selenium IDE – Các câu lệnh kiểm tra

Để thêm các câu lệnh vào Selenium IDE, các bạn có thể chọn menu item Edit –> Insert New Command, hoặc chọn Insert New Command ở Context Menu

thêm câu lệnh kiểm tra

Các câu lệnh về đối tượng UI

Đối với các đối tượng UI, thông thường chúng ta chỉ có hai loại kiểm tra: Tồn tại hay không tồn tại.

  • verifyElementPresent/assertElementPresent: Hai câu lệnh này dùng để kiểm tra một đối tượng UI tồn tại trên trang web.
  • verifyElementNotPresent/assertElementNotPresent: Hai câu lệnh này dùng để kiểm tra một đối tượng UI không tồn tại trên trang web.

Bên cạnh hai loại kiểm tra chính, Selenium IDE còn hỗ trợ chúng ta kiểm tra đối tượng UI ở mức độ chi tiết hơn như:

Cách hiển thị của đối tượng UI trên trang web:

  • Chiều cao: verifyElementHeight/assertElementHeight – verifyNotElementHeight/assertNotElementHeight
  • Chiều rộng: verifyElementWidth/assertElementWidth – verifyNotElementWidth/assertNotElementWidth
  • Toạ độ trái so với trang web: verifyElementPositionLeft/assertElementPositionLeft – verifyNotElementPositionLeft/assertNotElementPositionLeft
  • Toạ độ trên so với trang web: verifyElementPositionTop/assertElementPositionTop – verifyNotElementPositionTop/assertNotElementPositionTop

Các đối tượng UI được thiết kế với thuộc tính đặc biệt và chúng ta cần kiểm tra thuộc tính đó: verifyAttribute/assertAttribute – verifyNotAttribute/assertNotAttribute

Đối tượng UI đặc biệt như Checkbox hay RadioBox: verifyChecked/assertChecked – verifyNotChecked/assertNotChecked

Các câu lệnh về text

Đôi khi, chúng ta không cần kiểm tra một đối tượng UI, chúng ta chỉ muốn biết một dòng text có hay không có xuất hiện trên trang web. Lúc này, chúng ta có các câu lệnh kiểm tra vể text từ Selenium IDE.

  • verifyTextPresent/assertTextPresent: Hai câu lệnh này dùng để kiểm tra một dòng text tồn tại trên trang web.
  • verifyTextNotPresent/assertTextNotPresent: Hai câu lệnh này dùng để kiểm tra một dòng text không tồn tại trên trang web.

Vì bốn câu lệnh kiểm tra text này không tương tác với đối tượng UI nào, nên phần Target của câu lệnh chính là dòng text mà chúng ta muốn kiểm tra.

Trong trường hợp đặc biệt, chúng ta muốn kiểm tra text của một đối tượng UI xác định, chúng ta có hai câu lệnh verifyText/assertText. Lúc này, target chính là đối tượng UI của chúng ta, và Value chính là dòng text cần kiểm tra.

Các câu lệnh vể tổng thể trang web

Khi chúng ta quan trọng việc thiết kế trang web một cách tổng thể, Selenium IDE hỗ trợ chúng ta các câu lệnh có thể làm việc với toàn bộ trang web.

  • verifyBodyText/assertBodyText: Kiểm tra toàn bộ text trên trang web.
  • verifyCssCount/assertCssCount: Kiểm tra số lượng đối tượng UI sử dụng chung một thiết kế CSS
  • verifyXpathCount/assertXpathCount: Kiểm tra số lượng đối tượng UI có cùng XPath

Trên đây là một số câu lệnh dùng để kiểm tra trang web với Selenium IDE mà mình nghĩ là chúng ta thường xuyên sử dụng. Ngoài ra, Selenium IDE còn hỗ trợ chúng ta rất nhiều câu lệnh để chúng ta có thể sủ dụng trong các trường hợp đặc biệt mà các bạn có thể tìm thấy trong ô Command trên màn hình chính của Selenium IDE.

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

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

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