SBA301DễKỳ 7Chuyên ngành Cập nhật 04/08/2026

Tích hợp ứng dụng trang đơn với Spring Boot - Integrate single page application with Spring Boot

SBA301 - Phát triển ứng dụng trang đơn (Single Page Application) dạy cách dựng một ứng dụng web có hai nửa ghép lại: ReactJS chạy trong trình duyệt và dịch vụ REST viết bằng Spring Boot chạy trên máy chủ. Câu hỏi xuyên suốt là ranh giới giữa hai nửa đó nằm ở đâu, dữ liệu đi qua lại thế nào và ai chịu trách nhiệm phần nào. Nửa trình duyệt bắt đầu từ JSX cùng cách chia giao diện thành component, rồi tới trạng thái: React Hooks với useState, useEffect, useMemo, useCallback, các ràng buộc của Rules of Hooks, và lối giữ state ở component hàm đặt cạnh lối cũ ở component lớp. Bộ component dựng sẵn React-Bootstrap lo phần trình bày. Việc chuyển trang không còn do máy chủ đảm nhận mà do định tuyến phía client với React Router v6, kèm tham số đường dẫn đọc bằng useParams và trang 404 bắt ở cuối bảng route. Để lấy dữ liệu, môn đi qua nền bất đồng bộ của JavaScript gồm Promise và async/await, rồi tới thư viện Axios cho các lời gọi thực tế. Nửa máy chủ mở bằng nền tảng HTTP và nguyên tắc của một REST API, sau đó dựng dịch vụ bằng Spring Boot với các chú giải ánh xạ yêu cầu như RequestBody, PathVariable, RequestParam, cách đặt mã trạng thái và thân phản hồi. Tài liệu cho dịch vụ được sinh sống bằng OpenAPI và Swagger, còn phần kiểm thử dùng bộ khởi tạo spring-boot-starter-test để chạy thử cả tầng web lẫn toàn bộ ứng dụng. Tầng dữ liệu có hai nhánh. Nhánh quan hệ dùng JPA và Hibernate với ánh xạ đối tượng sang bảng, Session và Transaction, khoá lạc quan chống xung đột khi ghi đồng thời, phân trang cùng lựa chọn Slice khi không cần đếm toàn bộ bản ghi, và hbm2ddl sinh lược đồ. Nhánh tài liệu dùng MongoDB với lược đồ linh hoạt, Spring Data MongoDB, MongoTemplate cho truy vấn phức tạp và dịch vụ đám mây MongoDB Atlas. Khép môn là bảo mật với Spring Security, từ xác thực cơ bản và phiên làm việc tới token JWT cho dịch vụ phi trạng thái. Học xong, người học dựng được trọn một ứng dụng trang đơn có đăng nhập, gọi dịch vụ REST, lưu dữ liệu ở cả cơ sở dữ liệu quan hệ lẫn cơ sở dữ liệu tài liệu, và có tài liệu mô tả giao diện lập trình kèm theo.

171Câu hỏi
2Bộ đề
11Chủ đề

Câu hỏi của môn

164/171 câuCòn 7
145How is state initialized in a Class Component?4 lựa chọnTrung bình50% trả lời đúng
AUsing useState().
BUsing this.setState().
CBy assigning a value to this.state in the constructor().
DBy using props.state.
Lời giải
Trong khi khởi tạo một thành phần Class Component, bạn cần phải sử dụng hàm constructor() để khởi tạo trạng thái ban đầu của component. Hàm constructor() được gọi khi component được tạo mới và nó được sử dụng để khởi tạo trạng thái của component. Bạn có thể sử dụng từ khóa 'this.state' để truy cập vào trạng thái của component và gán giá trị cho nó. Ví dụ: constructor(props) { super(props); this.state = { trạng_thái: 'giá_trị' }; }. Điều này giúp bạn có thể truy cập và sử dụng trạng thái trong các phương thức khác của component.
Mở trang câu hỏi này →
146Which React feature helps prevent unnecessary re-renders in functional components?4 lựa chọnTrung bình50% trả lời đúng
AReact.memo
BshouldComponentUpdate
CPureComponent
DuseState
Lời giải
Tính năng React giúp ngăn chặn các re-render không cần thiết trong các thành phần chức năng là React.memo. React.memo là một hàm cao cấp giúp kiểm tra xem props của thành phần đã thay đổi hay chưa. Nếu props không thay đổi, React sẽ không thực hiện re-render. Điều này giúp cải thiện hiệu suất ứng dụng React. Ngoài ra, React.memo cũng có thể được sử dụng để ngăn chặn re-render không cần thiết trong các thành phần con.
Mở trang câu hỏi này →
147Which of the following is a valid way to update state in a Class Component?4 lựa chọnKhó29% trả lời đúng
Athis.state = { newValue: 'new' };
Bthis.setState({ newValue: 'new' });
CuseState('new');
Dstate.update({newValue: 'new'});
Lời giải
Để cập nhật trạng thái trong một Component lớp, chúng ta có thể sử dụng phương thức setState(). Phương thức này cho phép cập nhật trạng thái của Component một cách an toàn và hiệu quả. Khi sử dụng setState(), Component sẽ được cập nhật ngay lập tức và trạng thái mới sẽ được lưu trữ trong bộ nhớ đệm. Sau đó, trạng thái mới sẽ được cập nhật vào bộ nhớ chính trong vòng đời của Component. Điều này giúp đảm bảo rằng trạng thái của Component luôn được cập nhật một cách đồng bộ và chính xác.
Mở trang câu hỏi này →
148How do you handle 404 Not Found pages in React Router?4 lựa chọncó codeDễ80% trả lời đúng
Đề bài
<Routes> <Route path="/" element={
  <Home />
}
/> <Route path="/about" element={
  <About />
}
/> <Route path="*" element={
  <NotFound />
}
/> </Routes>
ABy using the <NotFound> component.
BBy adding a <Route path="*" element={<NotFound />} /> as the last route.
CBy using the notFound prop on the <Routes> component.
DBy using the useNotFound() hook.
Lời giải

Để xử lý trang 404 Not Found trong React Router, bạn cần thêm một route đặc biệt có path là ".*". Điều này cho phép React Router bắt gặp và chuyển hướng đến trang 404 khi người dùng truy cập vào một URL không tồn tại. Bạn có thể thêm route này vào cuối danh sách các route như sau: <Route path="*" element={ <NotFound /> } />. Điều này cho phép bạn định nghĩa một component riêng biệt để hiển thị khi người dùng truy cập vào một URL không tồn tại. Ngoài ra, bạn cũng có thể sử dụng component này để hiển thị thông tin về trang không tồn tại, chẳng hạn như một liên kết quay lại trang chủ hoặc một thông báo về trang không tồn tại.

Mở trang câu hỏi này →
ABy ignoring the error
BBy using.catch() on the Axios promise and accessing the error object
CBy using static HTML error messages
DBy redirecting to a different page without displaying an error
Lời giải
Khi làm việc với RESTful API trong ứng dụng ReactJS bằng Axios, việc xử lý lỗi là rất quan trọng. Để xử lý lỗi khi gửi yêu cầu, bạn có thể sử dụng phương thức .catch() trên promise của Axios. Phương thức này cho phép bạn truy cập vào đối tượng lỗi và thực hiện các hành động cần thiết để xử lý lỗi. Ví dụ, bạn có thể hiển thị thông báo lỗi cho người dùng, hoặc thực hiện các hành động khác để xử lý lỗi. Điều này giúp đảm bảo ứng dụng của bạn luôn hoạt động ổn định và không bị ảnh hưởng bởi lỗi.
Mở trang câu hỏi này →
150How do you typically handle asynchronous data fetching in a React component?4 lựa chọnDễ100% trả lời đúng
ABy directly modifying the DOM
BBy using lifecycle methods (Class Components) or useEffect Hook (Functional Components)
CBy using CSS selectors
DBy using global variables
Lời giải
Khi xử lý dữ liệu tải về bất đồng bộ trong một thành phần React, bạn cần sử dụng một trong hai phương pháp sau. Trước đây, khi sử dụng các thành phần lớp (Class Components), bạn có thể sử dụng các phương thức vòng đời (lifecycle methods) để thực hiện các hành động khi dữ liệu tải về. Tuy nhiên, hiện tại khi sử dụng các thành phần chức năng (Functional Components), bạn nên sử dụng Hook useEffect để thực hiện các hành động tương tự. Điều này giúp bạn có thể quản lý dữ liệu tải về một cách dễ dàng và hiệu quả hơn.
Mở trang câu hỏi này →
151What is Axios primarily used for in JavaScript applications?4 lựa chọnKhó29% trả lời đúng
ATo define CSS styles.
BTo make HTTP requests.
CTo manage database connections.
DTo handle client-side rendering exclusively.
Lời giải
Axios là một thư viện JavaScript phổ biến được sử dụng để thực hiện các yêu cầu HTTP trong các ứng dụng JavaScript. Nó cho phép bạn dễ dàng gửi và nhận dữ liệu từ máy chủ bằng cách sử dụng các phương thức HTTP khác nhau như GET, POST, PUT, DELETE, v.v. Axios cung cấp một cách đơn giản và dễ sử dụng để quản lý các yêu cầu HTTP, giúp giảm thiểu thời gian phát triển và tăng hiệu suất của ứng dụng. Ngoài ra, Axios cũng hỗ trợ các tính năng như hủy bỏ yêu cầu, quản lý trạng thái, và xử lý lỗi, giúp bạn có thể xây dựng các ứng dụng web mạnh mẽ và đáng tin cậy.
Mở trang câu hỏi này →
A@RequestMapping
B@Autowired
C@RestController
D@Entity
Lời giải

Để inject một Spring Data JPA repository vào một service hoặc controller, chúng ta sử dụng annotation @Autowired. Annotation này cho phép Spring tự động inject các bean vào các field hoặc setter của class. Điều này giúp giảm thiểu sự phức tạp khi viết mã và tăng cường tính tái sử dụng của code. Ví dụ, nếu chúng ta có một interface được tạo bởi Spring Data JPA, như sau:

Lời giải
public interface UserRepository extends JpaRepository<User, Long> {}

Thì chúng ta có thể inject nó vào một service như sau: @Service

Lời giải
public class UserService {

@Autowired

Lời giải
 private UserRepository userRepository;

}

Trong ví dụ trên, Spring sẽ tự động inject UserRepository vào UserService.

Mở trang câu hỏi này →
ALayered System
BCode on Demand
CStateless
DCacheable
Lời giải
Mô hình REST có nguyên tắc đảm bảo rằng mỗi yêu cầu từ client đến server phải chứa tất cả thông tin cần thiết để hiểu và xử lý yêu cầu. Nguyên tắc này được gọi là 'Stateless'. Điều này có nghĩa là server không lưu trữ trạng thái của client và không dựa vào trạng thái đó để xử lý yêu cầu. Thay vào đó, mỗi yêu cầu phải chứa thông tin cần thiết để server có thể xử lý nó một cách độc lập. Điều này giúp tăng tính linh hoạt và khả năng mở rộng của hệ thống.
Mở trang câu hỏi này →
154Which HTTP method is safe (does not modify resources)?4 lựa chọnDễ83% trả lời đúng
AGET
BPOST
CPUT
DDELETE
Lời giải
HTTP phương thức an toàn (không thay đổi tài nguyên) là phương thức GET. Phương thức GET được sử dụng để yêu cầu thông tin từ máy chủ mà không cần phải tạo, cập nhật hoặc xóa bất kỳ tài nguyên nào. Nó thường được sử dụng để tải xuống dữ liệu, hiển thị trang web hoặc tải xuống tệp. Ví dụ, khi bạn nhập địa chỉ URL của một trang web vào trình duyệt, trình duyệt sẽ gửi một yêu cầu GET đến máy chủ để tải xuống trang web đó. Phương thức GET không gửi bất kỳ dữ liệu nào đến máy chủ và không thay đổi trạng thái của tài nguyên. Do đó, nó được coi là phương thức an toàn.
Mở trang câu hỏi này →
155Which HTTP method is idempotent?4 lựa chọnDễ75% trả lời đúng
AGET
BPUT
CBoth GET and PUT
DPOST
Lời giải
HTTP phương thức idempotent là phương thức có thể thực hiện nhiều lần mà không gây ra tác động khác biệt. Trong các phương thức HTTP, phương thức GET và PUT được coi là idempotent. Phương thức GET được sử dụng để lấy dữ liệu từ server, trong khi phương thức PUT được sử dụng để cập nhật dữ liệu trên server. Vì cả hai phương thức này đều không gây ra tác động khác biệt khi thực hiện nhiều lần, nên chúng được coi là idempotent. Ví dụ, nếu bạn thực hiện GET nhiều lần để lấy dữ liệu, bạn sẽ nhận được dữ liệu giống nhau mỗi lần. Tương tự, nếu bạn thực hiện PUT nhiều lần để cập nhật dữ liệu, dữ liệu sẽ được cập nhật một lần duy nhất. Điều này giúp đảm bảo tính toàn vẹn và ổn định của dữ liệu trên server.
Mở trang câu hỏi này →
ASort
BPageable
CSlice
DList
Lời giải
Để xác định số trang và kích thước trang trong Spring Data JPA, bạn cần sử dụng đối tượng Pageable. Đối tượng này cho phép bạn sắp xếp và phân trang dữ liệu một cách linh hoạt. Bạn có thể sử dụng Pageable để chỉ định số trang và kích thước trang trong các phương thức tìm kiếm dữ liệu. Ví dụ, bạn có thể sử dụng Pageable để tìm kiếm 10 bản ghi trên trang thứ 2 của dữ liệu. Đối tượng Pageable cũng cho phép bạn sắp xếp dữ liệu theo các tiêu chí khác nhau, chẳng hạn như sắp xếp dữ liệu theo tên hoặc sắp xếp dữ liệu theo ngày tạo.
Mở trang câu hỏi này →
157What does the "Transient" state of an object in Hibernate indicate?4 lựa chọnDễ80% trả lời đúng
AThe object is associated with a Session and has a corresponding database record.
BThe object is not associated with any Session and does not have a database record.
CThe object was previously associated with a Session but is now detached.
DThe object is cached in the second-level cache.
Lời giải
Trạng thái 'Transient' trong Hibernate cho biết đối tượng hiện không được liên kết với bất kỳ phiên làm việc nào và không có bản ghi tương ứng trong cơ sở dữ liệu. Điều này có nghĩa là đối tượng đã được tạo hoặc cập nhật nhưng chưa được lưu trữ vào cơ sở dữ liệu. Khi đối tượng ở trạng thái này, Hibernate sẽ không tự động lưu trữ nó vào cơ sở dữ liệu khi phiên làm việc kết thúc. Thay vào đó, bạn phải sử dụng phương thức save() hoặc persist() để lưu trữ đối tượng vào cơ sở dữ liệu.
Mở trang câu hỏi này →
158In JPA, which annotation defines a many-to-many relationship?4 lựa chọnDễ100% trả lời đúng
A@OneToOne
B@OneToMany
C@ManyToMany
D@JoinColumn
Lời giải
Trong JPA, annotation nào định nghĩa mối quan hệ nhiều đến nhiều? Mối quan hệ nhiều đến nhiều là một loại mối quan hệ giữa hai bảng trong cơ sở dữ liệu, trong đó một bản ghi trong bảng này có thể liên kết với nhiều bản ghi trong bảng khác và ngược lại. Annotation @ManyToMany được sử dụng để định nghĩa mối quan hệ này. Nó cho phép bạn tạo một mối quan hệ giữa hai bảng thông qua một bảng trung gian. Ví dụ, một người có thể có nhiều bạn bè và một bạn bè cũng có thể có nhiều người. Annotation @ManyToMany giúp bạn quản lý mối quan hệ này một cách dễ dàng.
Mở trang câu hỏi này →
159Which Hibernate Cache property enables the second-level cache?4 lựa chọnDễ100% trả lời đúng
Ahibernate.cache.use_second_level_cache
Bhibernate.cache.provider_class
Chibernate.cache.region.factory_class
Dhibernate.cache.use_query_cache
Lời giải
Câu hỏi này yêu cầu bạn chọn thuộc tính của Hibernate Cache cho phép bật cache cấp hai. Cache cấp hai là một tính năng quan trọng của Hibernate giúp giảm thiểu số lượng truy vấn cơ sở dữ liệu bằng cách lưu trữ kết quả của các truy vấn trước đó trong bộ nhớ. Điều này giúp cải thiện hiệu suất ứng dụng và giảm thiểu tải trên cơ sở dữ liệu. Để bật cache cấp hai, bạn cần thiết lập thuộc tính `hibernate.cache.use_second_level_cache` thành `true`. Ngoài ra, bạn cũng cần thiết lập thuộc tính `hibernate.cache.provider_class` để chỉ định lớp cung cấp cache. Một số lớp cung cấp cache phổ biến bao gồm `org.hibernate.cache.EhCacheProvider`, `org.hibernate.cache.HashtableCacheProvider`, v.v. Bạn cần chọn lớp cung cấp cache phù hợp với nhu cầu của ứng dụng. Tóm lại, thuộc tính `hibernate.cache.use_second_level_cache` là thuộc tính quan trọng nhất cho phép bật cache cấp hai trong Hibernate.
Mở trang câu hỏi này →
160What is the purpose of the @GeneratedValue annotation?4 lựa chọnDễ100% trả lời đúng
ATo define a column name.
BTo specify the strategy for generating primary key values.
CTo create a new table.
DTo define a new entity.
Lời giải
Annotation @GeneratedValue được sử dụng để chỉ định chiến lược tạo giá trị khóa chính. Khi sử dụng @GeneratedValue, bạn có thể chọn một trong các chiến lược tạo khóa chính như AUTO, IDENTITY, SEQUENCE hoặc TABLE. Mục đích chính của @GeneratedValue là tự động tạo khóa chính cho mỗi bản ghi mới được thêm vào bảng dữ liệu. Điều này giúp giảm thiểu sự phức tạp khi phải tự tạo khóa chính cho mỗi bản ghi.
Mở trang câu hỏi này →
161Which method is used to create a Sort object for ascending order?4 lựa chọnDễ100% trả lời đúng
ASort.descending()
BSort.ascending()
CSort.unsorted()
DSort.by()
Lời giải
Để tạo một đối tượng Sort cho thứ tự tăng dần, bạn cần sử dụng phương thức Sort.ascending(). Phương thức này được sử dụng để sắp xếp dữ liệu theo thứ tự tăng dần. Ví dụ, nếu bạn có một danh sách các số từ nhỏ đến lớn, phương thức này sẽ giúp bạn sắp xếp chúng theo thứ tự tăng dần. Ngoài ra, phương thức Sort.ascending() cũng có thể được sử dụng để sắp xếp các chuỗi hoặc các đối tượng theo thứ tự tăng dần dựa trên giá trị của chúng. Tuy nhiên, cần lưu ý rằng phương thức này chỉ hoạt động khi dữ liệu được sắp xếp là một danh sách hoặc một mảng.
Mở trang câu hỏi này →
162Which method in MongoTemplate is used to insert a single document?4 lựa chọnTrung bình50% trả lời đúng
Asave()
Binsert()
Ccreate()
Dadd()
Lời giải
Để thêm một bản ghi đơn (single document) vào cơ sở dữ liệu MongoDB bằng cách sử dụng MongoTemplate, bạn cần sử dụng phương thức phù hợp. Trong các phương thức được đề cập, phương thức "insert()" là lựa chọn chính xác.
Mở trang câu hỏi này →
163Which MongoDB command is used to delete documents from a collection?4 lựa chọnDễ83% trả lời đúng
Aupdate()
Bfind()
CinsertOne()
DdeleteMany() or deleteOne()
Lời giải
Để xóa tài liệu từ một tập hợp trong MongoDB, bạn cần sử dụng lệnh thích hợp. Trong các lựa chọn đã cho, có hai lệnh có thể thực hiện được việc này: deleteMany() và deleteOne(). Lệnh deleteMany() được sử dụng để xóa nhiều tài liệu cùng một lúc, trong khi lệnh deleteOne() được sử dụng để xóa một tài liệu duy nhất. Để sử dụng các lệnh này, bạn cần biết ID hoặc các điều kiện lọc cụ thể của tài liệu bạn muốn xóa. Ví dụ, bạn có thể sử dụng lệnh deleteMany() để xóa tất cả tài liệu trong một tập hợp, hoặc sử dụng lệnh deleteOne() để xóa một tài liệu cụ thể dựa trên ID hoặc các điều kiện lọc khác. Tóm lại, lệnh deleteMany() và deleteOne() là hai lệnh quan trọng trong MongoDB giúp bạn quản lý và xóa tài liệu từ các tập hợp.
Mở trang câu hỏi này →
164What does the spring-boot-starter-data-mongodb dependency include?4 lựa chọnDễ100% trả lời đúng
AOnly the MongoDB Java driver.
BThe MongoDB Java driver and Spring Data MongoDB.
COnly Spring Data MongoDB.
DJDBC drivers and Spring Data JPA.
Lời giải
Tùy thuộc vào yêu cầu của dự án, bạn có thể chọn sử dụng MongoDB Java driver hoặc Spring Data MongoDB. Tuy nhiên, nếu bạn chọn sử dụng spring-boot-starter-data-mongodb, thì nó sẽ bao gồm cả hai phần này. MongoDB Java driver là một thư viện Java để kết nối với cơ sở dữ liệu MongoDB, trong khi Spring Data MongoDB là một phần mở rộng của Spring Framework để hỗ trợ giao tiếp với MongoDB. Với spring-boot-starter-data-mongodb, bạn có thể dễ dàng sử dụng các tính năng của MongoDB và Spring Data MongoDB trong dự án của mình.
Mở trang câu hỏi này →