A.@Bean và @Component tạo ra bean với scope khác nhau: @Bean luôn là prototype còn @Component luôn là singleton
B.Chỉ @Bean tạo ra Spring bean thật; class gắn @Component chỉ là POJO thường, không được container quản lý
C.@Component chỉ dùng được cho class có sẵn của framework, còn @Bean mới dùng cho class trong ứng dụng của bạn
D.@Component để Spring tự new qua component scan; @Bean trả về object bạn tự tạo
Đáp án: D
@Component đặt trên class của bạn — Spring phát hiện qua component scan rồi tự khởi tạo bằng default constructor. @Bean đặt trên method trong @Configuration và trả về object do bạn tự tạo, hợp cho class thư viện ngoài (RestTemplate, ObjectMapper) hoặc init cần logic tuỳ ý. Cả hai mặc định là singleton scope.
Phát biểu nào đúng về singleton scope — scope mặc định của bean trong Spring?
A.Singleton scope tự động làm bean thread-safe: Spring bọc mỗi method trong khối đồng bộ hoá nên có thể giữ state chung thoải mái
B.Singleton nghĩa là mỗi HTTP request nhận một instance riêng của bean
C.Đúng một instance dùng chung; nên giữ stateless vì Spring KHÔNG tự lo thread-safe
D.Spring tạo sẵn tất cả bean singleton nhưng mỗi lần inject lại tạo một bản sao mới của instance
Đáp án: C
Singleton là scope mặc định: container tạo đúng một instance và dùng chung ở mọi điểm inject trong ứng dụng. Vì được chia sẻ giữa nhiều thread, bean singleton nên stateless — Spring KHÔNG tự đồng bộ hoá hay làm nó thread-safe. Giữ mutable state trong singleton là nguồn race condition; state theo request thì dùng request scope hoặc biến cục bộ.
@SpringBootApplication gộp ba annotation: @Configuration (class là nguồn định nghĩa bean), @EnableAutoConfiguration (bật auto-configuration theo classpath), và @ComponentScan (quét component từ package hiện tại trở xuống). Vì vậy nên đặt class main ở package gốc để @ComponentScan quét được toàn bộ sub-package.
Client gọi GET /api/users/1 tới controller dưới đây. Response body trả về là gì?
java
@RestController@RequestMapping("/api/users")classUserController {
@GetMapping("/{id}")
User getUser(@PathVariable Long id) {
returnnewUser(id, "Ann");
}
}
A.Spring coi "Ann" là tên view và đi tìm template user rồi render HTML
B.JSON của object User — @RestController = @Controller + @ResponseBody
C.Lỗi biên dịch — controller method không được trả về kiểu object tuỳ ý, phải là String hoặc ResponseEntity
D.Response rỗng với status 200 — method trả object nhưng thiếu @ResponseBody nên body không được ghi
Đáp án: B
Trả về JSON của object User, ví dụ {"id":1,"name":"Ann"}. @RestController = @Controller + @ResponseBody, nên mọi method mặc định ghi giá trị trả về thẳng vào response body qua message converter (Jackson) thay vì hiểu nó là tên view. Đây là điểm khác cốt lõi với @Controller — vốn dùng cho web MVC trả về template HTML.
App chạy với spring.profiles.active=prod. Spring nạp các file cấu hình nào và ưu tiên ra sao?
A.Chỉ nạp application-prod.yml; application.yml bị bỏ hoàn toàn khi có profile active
B.application.yml ghi đè application-prod.yml vì file base luôn có ưu tiên cao nhất
C.Phải build một artifact riêng cho prod vì Spring không thể chọn cấu hình theo môi trường lúc runtime
D.Nạp application.yml rồi application-prod.yml ghi đè lên cho cùng key
Đáp án: D
Spring nạp application.yml (base) rồi merge application-prod.yml lên trên; với cùng key, giá trị ở file profile active ghi đè base. Kích hoạt qua spring.profiles.active=prod (hoặc biến môi trường SPRING_PROFILES_ACTIVE). Nhờ vậy chỉ cần deploy MỘT JAR cho mọi môi trường và chọn cấu hình lúc chạy. Bean cũng có thể gắn @Profile("prod") để chỉ tồn tại ở env tương ứng.
A.@RestController = @Controller + @ResponseBody, trả về vào response body
B.@RestController tự động thêm CORS cho mọi endpoint, @Controller thì không
C.@RestController chỉ nhận request GET, còn @Controller nhận mọi HTTP method
D.@Controller đã bị loại bỏ từ Spring Boot 3, chỉ còn @RestController
Đáp án: A
@RestController = @Controller + @ResponseBody. Giá trị trả về được ghi thẳng vào response body qua HttpMessageConverter (mặc định Jackson → JSON). @Controller không có @ResponseBody thì chuỗi trả về bị hiểu là tên view để template engine render.
Khi nào nên trả về ResponseEntity<T> thay vì trả thẳng object T từ controller?
A.Khi cần kiểm soát status code và header của response
B.Bắt buộc luôn dùng ResponseEntity, trả thẳng object đã bị loại bỏ từ Spring Boot 3
C.Khi muốn trả về JSON — trả thẳng object thì Spring luôn trả XML
D.Khi controller cần chạy bất đồng bộ; trả object thường thì luôn chặn luồng
Đáp án: A
Dùng ResponseEntity khi cần tự quyết định status hoặc thêm header. Trả thẳng object thì Spring luôn dùng 200 OK (trừ khi có @ResponseStatus). Ví dụ điển hình cần ResponseEntity: 201 Created kèm header Location, hoặc phân nhánh 200/404 ngay trong method.
A.Spring tự sửa email về chuỗi rỗng rồi tiếp tục xử lý
B.Spring ném MethodArgumentNotValidException, trả 400 trước khi vào method
C.Method vẫn chạy bình thường; muốn biết có lỗi phải tự gọi validator trong thân method
D.Trả về 500 Internal Server Error vì exception chưa được bắt
Đáp án: B
Trả 400 Bad Request, service.create không được gọi. @Valid kích hoạt Bean Validation ngay khi bind @RequestBody; vi phạm ràng buộc sinh MethodArgumentNotValidException và Spring Boot ánh xạ sẵn thành 400. Cần thư viện spring-boot-starter-validation trên classpath.
A.Nó gọi một stored procedure cùng tên trong database
B.Spring Data phân tích tên method theo quy ước và sinh truy vấn lúc chạy
C.JpaRepository đã có sẵn method này trong interface cha
D.Một annotation processor sinh file .java lúc build, xem được trong thư mục generated-sources
Đáp án: B
Spring Data đọc tên method và sinh truy vấn tương ứng lúc chạy, rồi tạo một proxy làm implementation. findByEmailAndActiveTrue được phân tích thành where email = ?1 and active = true. Sai chính tả tên field sẽ làm ứng dụng lỗi ngay lúc khởi động, không phải lúc gọi.
Thêm spring-boot-starter-actuator vào dự án thì được gì?
A.Toàn bộ endpoint được expose công khai theo mặc định, gồm cả /actuator/env và /actuator/heapdump
B.Bộ endpoint vận hành sẵn: /actuator/health, /metrics, /info
C.Tự động thêm cache và load balancing cho mọi endpoint của ứng dụng
D.Một giao diện web quản trị đầy đủ để chỉnh sửa cấu hình lúc chạy
Đáp án: B
Actuator thêm các endpoint vận hành: health cho liveness/readiness probe, metrics cho Prometheus/Micrometer, info, env, loggers, httpexchanges. Mặc định chỉ health được expose qua HTTP; các endpoint khác phải bật rõ ràng bằng management.endpoints.web.exposure.include.
@Component, @Service, @Repository khác nhau thế nào?
A.Cùng đăng ký bean; @Repository thêm việc dịch exception của tầng dữ liệu
B.Chỉ @Component mới được quét tự động, hai cái kia phải khai báo tay
C.Mỗi annotation tạo bean với scope mặc định khác nhau
D.Chúng quyết định thứ tự khởi tạo bean khi ứng dụng khởi động
Đáp án: A
Cả ba đều đăng ký bean và đều được quét tự động — hai cái sau là meta-annotation của cái đầu. Khác biệt kỹ thuật duy nhất: annotation cho tầng dữ liệu kích hoạt việc dịch ngoại lệ của nhà cung cấp sang hệ ngoại lệ chung của Spring.
Ứng dụng Spring Boot chạy được bằng java -jar nhờ đâu?
A.Spring Boot cài một máy chủ ứng dụng vào hệ điều hành khi khởi động
B.JVM tự tìm và tải các dependency từ kho trung tâm khi chạy
C.Tệp cấu hình khai báo cổng nên jar tự mở cổng lắng nghe
D.Fat jar chứa cả dependency và một web server nhúng
Đáp án: D
Gói jar chứa cả các thư viện phụ thuộc lẫn một máy chủ web nhúng. Trước đây phải đóng gói dạng WAR rồi triển khai vào một máy chủ ứng dụng cài sẵn bên ngoài — nay ứng dụng tự chứa mọi thứ nó cần.
application.properties và application.yml khác nhau ở điểm nào?
A.Một dùng cho môi trường phát triển, một cho production
B.Một được nạp lúc build, một được đọc lúc chạy
C.Chỉ khác định dạng, cùng đọc ra một tập cấu hình
D.Một hỗ trợ biến môi trường, một thì không
Đáp án: C
Chỉ khác định dạng, cả hai đọc ra cùng một tập cấu hình. Dạng phân cấp gọn hơn khi có nhiều khoá lồng nhau; dạng khoá bằng giá trị thì đơn giản và không có bẫy thụt lề.
Ứng dụng Spring Boot chạy ở cổng 8080. Đổi sang 9000 bằng cách nào?
A.Truyền cổng vào hàm khởi động trong lớp chính
B.Đặt thuộc tính cổng của máy chủ trong cấu hình
C.Sửa cấu hình của máy chủ Tomcat cài trên hệ thống
D.Khai báo cổng trong tệp mô tả triển khai của ứng dụng
Đáp án: B
Đặt thuộc tính cổng của máy chủ trong cấu hình. Giá trị này đọc được từ file cấu hình, biến môi trường hoặc tham số dòng lệnh — nên đổi được ở từng môi trường mà không sửa mã hay dựng lại.
Thêm spring-boot-starter-web vào dự án mang lại những gì?
A.Chỉ các annotation dùng cho controller và routing
B.Bộ công cụ sinh mã cho các endpoint REST
C.Máy chủ nhúng, tầng MVC và thư viện xử lý JSON
D.Một máy chủ web cần cài đặt riêng trên hệ thống
Đáp án: C
Nó mang máy chủ nhúng, tầng MVC và thư viện xử lý JSON cùng các phụ thuộc đi kèm. Nhờ đó ứng dụng chạy được bằng một lệnh duy nhất mà không cần cài máy chủ web riêng.
@GetMapping("/users") khác @RequestMapping(value="/users", method=GET) thế nào?
A.Dạng viết tắt chỉ dùng được trong lớp trả về dữ liệu
B.Dạng tổng quát hỗ trợ nhiều đường dẫn, dạng kia thì không
C.Chỉ là dạng viết tắt, hành vi hoàn toàn giống nhau
D.Dạng viết tắt có hiệu năng tốt hơn khi định tuyến
Đáp án: C
Chỉ là dạng viết tắt, hành vi hoàn toàn giống nhau. Các annotation chuyên cho từng phương thức HTTP được định nghĩa dựa trên annotation tổng quát, nên chúng ngắn hơn và đọc rõ ý định hơn.
Khai báo phụ thuộc Spring Boot thường không ghi số phiên bản. Vì sao?
A.Các thư viện của Spring không đánh số phiên bản riêng
B.Công cụ dựng luôn tự lấy phiên bản mới nhất khi build
C.Phiên bản do phần quản lý phụ thuộc của Spring Boot quyết định
D.Phiên bản được lấy từ môi trường chạy lúc khởi động
Đáp án: C
Vì phần quản lý phụ thuộc của Spring Boot đã khai báo sẵn phiên bản cho hàng trăm thư viện phổ biến, và chúng đã được kiểm chứng tương thích với nhau. Nâng phiên bản Spring Boot là nâng cả tập đó cùng lúc.
A.Tự khởi động lại khi mã đổi và tắt bộ nhớ đệm mẫu
B.Trình sinh mã cho controller và repository
C.Bộ công cụ gỡ lỗi từ xa cho môi trường production
D.Bộ giám sát hiệu năng và thu thập số liệu ứng dụng
Đáp án: A
Nó tự khởi động lại ứng dụng khi mã đổi, tắt bộ nhớ đệm của các mẫu hiển thị, và bật một số thiết lập tiện cho phát triển. Nó tự vô hiệu hoá khi ứng dụng chạy dạng đóng gói ở môi trường thật.
Một @Service nằm ngoài package của lớp chính không được Spring nhận ra. Vì sao?
A.Annotation đó chỉ dùng được trong package gốc của dự án
B.Việc quét component bắt đầu từ package của lớp chính
C.Các package khác cần được biên dịch riêng trước đó
D.Lớp cần được khai báo thêm trong file cấu hình
Đáp án: B
Vì việc quét component bắt đầu từ package chứa lớp khởi động và chỉ đi xuống các package con. Lớp nằm ngoài phạm vi đó không được phát hiện, và ứng dụng báo lỗi thiếu bean khi có nơi cần tới nó.
A.Một phương thức so sánh bằng do người dùng tự viết
B.Một interface repository tương ứng được khai báo sẵn
C.Các phương thức đọc ghi cho mọi trường của lớp
D.Một khoá chính và một constructor không tham số
Đáp án: D
Một khoá chính và một constructor không tham số. Thư viện ánh xạ tạo đối tượng bằng phản chiếu rồi mới gán các trường, nên nó cần constructor rỗng — đây là lý do lớp entity không dùng được kiểu bản ghi bất biến.
Phát biểu nào sau đây SAI về dependency injection và @Autowired trong Spring?
A.@Autowired mặc định bắt buộc phải tìm được bean, thiếu bean thì app không khởi động
B.Field injection dễ viết unit test hơn vì không phải khai constructor
C.Setter injection phù hợp cho dependency optional (có thể không cần)
D.Với class chỉ có đúng một constructor, từ Spring 4.3+ không cần ghi @Autowired trên constructor đó
E.Constructor injection cho phép field khai báo final (immutable) và làm dependency bắt buộc trở nên rõ ràng
Đáp án: B
Constructor injection cho phép field final và làm dependency bắt buộc rõ ràng; class có đúng một constructor thì Spring 4.3+ khỏi cần @Autowired; setter injection hợp cho dependency optional. Ngược lại, field injection khó test hơn (cần reflection), và @Autowired mặc định required=true nên thiếu bean sẽ khiến app không khởi động.
A.Có — vì Task là prototype nên Spring tạo Task mới mỗi lần Worker truy cập tới nó
B.Lỗi khởi động — không được inject bean prototype vào bean singleton
C.Không — Worker là singleton nên Task chỉ được inject đúng một lần lúc khởi tạo
D.Có — Spring tự nhận diện prototype và inject một provider, nên mỗi handle() nhận Task mới mà không cần thêm gì
Đáp án: C
Không. Worker là singleton nên Spring chỉ inject Task một lần — lúc khởi tạo Worker. Dù Task khai báo prototype, mọi lần handle() sau đó đều dùng lại chính instance đã inject đó. Prototype chỉ tạo mới tại thời điểm inject/getBean, không phải mỗi lần truy cập. Muốn Task mới mỗi lần, dùng ObjectProvider<Task>, method @Lookup, hoặc gọi getBean().
A.Cả ba đều lấy từ query string vì mọi tham số của controller method đều đến từ query parameter
B.id và page đều từ path; body được đọc từ query string dưới dạng chuỗi JSON đã encode
C.id từ path {id}, page từ query string, body từ nội dung request body
D.id từ query string, page từ path, body từ header — thứ tự khai báo tham số quyết định nguồn dữ liệu
Đáp án: C
@PathVariable Long id lấy từ đoạn path {id} của URL (/users/42/notes → 42). @RequestParam int page lấy từ query string (?page=2), có defaultValue nên optional. @RequestBody NoteDto body lấy từ nội dung request body — Jackson deserialize JSON thành object. Nguồn dữ liệu do annotation quyết định, không phụ thuộc thứ tự khai báo tham số.
A.Lỗi khởi động — không được đặt @Transactional trên method được gọi nội bộ trong cùng class
B.Có — Spring viết lại bytecode của method lúc biên dịch để chèn logic transaction, nên self-invocation vẫn được bao
C.Không — gọi this.processOne() không qua AOP proxy nên @Transactional bị bỏ qua
D.Có — @Transactional gắn trực tiếp vào method nên luôn có hiệu lực bất kể được gọi từ đâu
Đáp án: C
Không. Spring thực thi @Transactional qua một AOP proxy bọc bean: chỉ lời gọi đi từ NGOÀI vào proxy mới được begin/commit. Gọi this.processOne() là self-invocation — đi thẳng vào object, bỏ qua proxy — nên @Transactional vô hiệu và processOne chạy không transaction. Cách sửa: tách processOne sang service khác rồi inject, hoặc self-inject proxy.
Khi nào nên dùng @ConfigurationProperties thay vì @Value để đọc cấu hình?
A.@ConfigurationProperties là bắt buộc cho mọi property; @Value đã bị loại bỏ (deprecated) trong Spring Boot 3
B.@ConfigurationProperties nhanh hơn lúc runtime vì đọc property trực tiếp từ file mỗi lần truy cập, bỏ qua Environment
C.Khi cần bind một NHÓM property vào class/record type-safe, có validation
D.Chỉ @Value mới đọc được từ application.yml; @ConfigurationProperties chỉ đọc từ biến môi trường
Đáp án: C
Dùng @ConfigurationProperties khi cần bind một NHÓM property liên quan (thường ≥3 key) vào một class/record: type-safe, chuyển kiểu đầy đủ, validate được bằng @Validated + Bean Validation, và IDE autocomplete/navigation. Dùng @Value cho một property đơn lẻ hoặc khi cần biểu thức SpEL. Cả hai đọc từ cùng nguồn Environment; khác biệt nằm ở phạm vi bind và type-safety.
Trong Spring AOP, vai trò của Pointcut và advice @Around là gì?
A.Pointcut là đoạn logic cross-cutting thực thi; @Around là nơi khai báo pattern chọn method
B.@Around chỉ chạy được SAU khi method kết thúc và không thể can thiệp giá trị trả về
C.Pointcut chọn method bị intercept; @Around bao quanh và phải gọi proceed()
D.Pointcut và @Around chỉ dùng được cho method static và phải khai trong file XML riêng
Đáp án: C
Pointcut là biểu thức chọn những join point (method) sẽ bị intercept, ví dụ execution(* com.example.service.*.*(..)). @Around là advice bao quanh method: nhận ProceedingJoinPoint, chạy logic trước, gọi proceed() để thực thi method thật, rồi chạy logic sau — kiểm soát được cả giá trị trả về và exception. AOP dùng để tách cross-cutting concern (logging, security, transaction) khỏi business logic.
Trong Spring Security, authentication và authorization khác nhau thế nào?
A.Authorization xảy ra trước để lọc quyền, sau đó authentication mới xác minh danh tính người dùng
B.Authentication kiểm tra role và scope; authorization kiểm tra mật khẩu và token đăng nhập
C.Authentication là "bạn là ai", authorization là "được làm gì"; xác thực trước
D.Hai từ chỉ cùng một việc — kiểm tra username/password — chỉ khác cách gọi
Đáp án: C
Authentication ("Bạn là ai?") xác minh danh tính — login mật khẩu, JWT, OAuth. Authorization ("Bạn được phép làm gì?") kiểm tra quyền — role, scope. Authentication luôn xảy ra trước. Trong Spring Security: xác thực dựng Authentication rồi lưu vào SecurityContextHolder; phân quyền đọc từ đó, áp rule theo URL (authorizeHttpRequests) hoặc theo method (@PreAuthorize).
A.500, vì mọi exception chưa được xử lý đều thành Internal Server Error
B.404 nhưng body rỗng, vì @ResponseStatus luôn loại bỏ body
C.200, vì handler trả về object thành công nên coi như request đã xử lý xong
D.404 kèm body JSON của ApiError — @ResponseStatus quyết định status
Đáp án: D
404 kèm body JSON của ApiError. @RestControllerAdvice = @ControllerAdvice + @ResponseBody, gom xử lý exception cho toàn bộ controller. @ExceptionHandler chọn loại exception, @ResponseStatus đặt status, giá trị trả về thành response body.
A.Không được gọi save — nó sẽ tạo thêm một bản ghi mới trùng dữ liệu
B.Bắt buộc — không gọi save thì thay đổi chỉ nằm trong bộ nhớ và bị mất
C.Không bắt buộc — entity managed tự được dirty checking khi commit
D.Bắt buộc, vì findById luôn trả về bản sao detached
Đáp án: C
Không bắt buộc. Trong transaction, entity từ findById là managed — persistence context so sánh trạng thái lúc commit và tự phát UPDATE cho phần thay đổi. Gọi save chỉ thừa. Ngoài transaction thì entity là detached, lúc đó save mới thực sự cần.
Vì sao constructor injection được khuyến nghị hơn field injection (@Autowired đặt thẳng lên field)?
A.Field injection đã bị loại bỏ từ Spring Boot 3 nên không còn dùng được
B.Khai được final, test không cần Spring, lộ phụ thuộc vòng lúc khởi động
C.Chỉ constructor injection mới inject được bean scope prototype
D.Constructor injection nhanh hơn lúc chạy vì Spring không phải dùng reflection
Đáp án: B
Ba lý do: dependency để final được nên bất biến và object luôn hợp lệ ngay sau khi tạo; unit test new thẳng service với mock, không cần dựng Spring context; và phụ thuộc vòng lộ ra ngay lúc khởi động thay vì bị field injection che đi.
A.Sau constructor và sau khi mọi dependency đã inject xong
B.Chạy song song với constructor trên một thread khác
C.Trước constructor, để chuẩn bị dữ liệu cho constructor dùng
D.Chỉ chạy khi có request đầu tiên tới ứng dụng
Đáp án: A
Thứ tự: constructor → inject các dependency còn lại → @PostConstruct → bean sẵn sàng dùng. Vì vậy @PostConstruct là chỗ đúng cho việc khởi tạo cần tới dependency. @PreDestroy chạy đối xứng lúc context đóng, hợp cho việc dọn tài nguyên.
application.yml đặt app.timeout=30, đồng thời container có biến môi trường APP_TIMEOUT=60. Ứng dụng đọc ra giá trị nào?
A.30 — file cấu hình của ứng dụng luôn thắng vì nó cụ thể hơn
B.60 — biến môi trường ưu tiên cao hơn file, và relaxed binding khớp tên
C.Ứng dụng lỗi lúc khởi động vì hai nguồn cấu hình xung đột
D.30, vì tên biến môi trường viết hoa có gạch dưới không khớp với khóa viết thường có dấu chấm
Đáp án: B
60. Spring Boot xếp các nguồn cấu hình theo thứ tự ưu tiên, biến môi trường đứng trên application.yml đóng gói trong jar. Relaxed binding ánh xạ APP_TIMEOUT sang app.timeout. Đây chính là nền tảng để cùng một image chạy được ở nhiều môi trường.
Phát biểu nào đúng về các annotation test của Spring Boot?
A.@DataJpaTest giữ lại dữ liệu sau mỗi test
B.@WebMvcTest chỉ nạp tầng web, còn service/repository phải mock
C.Cả ba annotation đều khởi động web server thật trên một port ngẫu nhiên
D.@SpringBootTest chỉ nạp tầng web nên chạy nhanh nhất trong ba loại
Đáp án: B
@SpringBootTest nạp cả context (chậm, đầy đủ). @WebMvcTest chỉ nạp tầng web và mock phần còn lại. @DataJpaTest chỉ nạp tầng JPA, mỗi test chạy trong transaction rồi rollback. Slice test nhanh hơn nhiều nên nên là mặc định; @SpringBootTest để dành cho luồng cần kiểm tra xuyên tầng.
Trong Spring Security, vì sao dùng BCryptPasswordEncoder để lưu mật khẩu thay vì băm bằng SHA-256?
A.BCrypt chậm có chủ đích, có cost điều chỉnh được và tự sinh salt
B.BCrypt mã hóa hai chiều nên có thể giải ra mật khẩu gốc khi người dùng quên
C.SHA-256 đã bị chứng minh là có va chạm nên không dùng được nữa
D.BCrypt tạo ra chuỗi băm ngắn hơn nên tiết kiệm dung lượng database
Đáp án: A
Vì mật khẩu cần hàm băm CHẬM. BCrypt có tham số cost để chỉnh độ chậm và tự nhúng salt ngẫu nhiên vào mỗi chuỗi băm, nên hai người dùng cùng mật khẩu vẫn ra hai giá trị khác nhau và không dùng được rainbow table. SHA-256 nhanh nên GPU dò được hàng tỷ lần mỗi giây.
Có hai bean cùng implement một interface. Inject interface đó gây lỗi gì và sửa thế nào?
A.Không lỗi; Spring chọn bean được khai báo trước trong quá trình quét
B.Lỗi bean mơ hồ; sửa bằng @Primary hoặc @Qualifier
C.Lỗi khi chạy request đầu tiên chứ không phải lúc khởi động
D.Không lỗi; cả hai bean được inject dưới dạng danh sách
Đáp án: B
Lỗi bean mơ hồ ngay khi khởi động. Sửa bằng cách đánh dấu một bean là ưu tiên, hoặc dùng annotation chỉ định tên bean cụ thể ở nơi inject. Container không đoán — nó từ chối khởi động.
Khi nào phải dùng @Bean trong @Configuration thay vì @Component?
A.Khi bean phải được khởi tạo trước các bean khác
B.Khi bean cần được inject bằng constructor thay vì field
C.Khi lớp cần tạo bean thuộc thư viện ngoài, không sửa được mã
D.Khi bean cần scope singleton thay vì prototype
Đáp án: C
Khi lớp cần tạo bean thuộc thư viện ngoài mà bạn không sửa được mã nguồn — không thể thêm annotation vào lớp của người khác. Cũng dùng khi việc tạo bean cần logic: đọc cấu hình, gọi một người dựng, hoặc chọn cài đặt theo điều kiện.
A.Một lớp chạy khi ứng dụng khởi động để khởi tạo tài nguyên
B.Một tệp cấu hình khai báo các bean mặc định của ứng dụng
C.Một plugin của công cụ build để đóng gói ứng dụng
D.Một dependency gom sẵn nhóm thư viện cần cho một tính năng
Đáp án: D
Một phụ thuộc gom sẵn nhóm thư viện cần cho một tính năng, với các phiên bản đã được kiểm tra tương thích. Bản thân nó thường không chứa mã — giá trị nằm ở việc bạn khai một dòng thay vì mười dòng và không phải tự dò phiên bản.
A.Một thuộc tính nhận nhiều cách viết tên: gạch nối, camelCase, chữ hoa gạch dưới
B.Kiểu dữ liệu của thuộc tính được kiểm tra lỏng lẻo hơn bình thường
C.Thuộc tính thay đổi được lúc chạy mà không cần khởi động lại
D.Thuộc tính thiếu giá trị sẽ nhận giá trị mặc định thay vì báo lỗi
Đáp án: A
Một thuộc tính nhận nhiều cách viết tên: dấu gạch nối, kiểu lạc đà, hay chữ hoa kèm gạch dưới đều trỏ về cùng một thuộc tính. Nhờ đó đặt được bằng tệp YAML lẫn bằng biến môi trường, vốn có quy ước đặt tên khác hẳn.
Bean chỉ được tạo khi profile đó đang được kích hoạt. Đây là cách thay cài đặt theo môi trường — dịch vụ gửi email thật ở môi trường sản xuất và một cài đặt chỉ ghi log ở máy cá nhân.
Chuỗi bộ lọc ở tầng servlet chạy trước, rồi bộ điều phối trung tâm nhận request, tra bảng ánh xạ để tìm phương thức xử lý, chạy các interceptor, rồi mới tới phương thức của bạn. Phản hồi đi ngược lại qua các tầng đó.
Nên đặt logic xác thực token ở Filter, Interceptor hay AOP?
A.Đặt trực tiếp trong từng controller để kiểm soát chi tiết
B.Interceptor — nó biết được phương thức xử lý nào sắp chạy
C.Filter — nó thấy mọi request trước khi vào tầng MVC
D.AOP — nó tách hoàn toàn khỏi tầng web nên tái dùng được
Đáp án: C
Ở bộ lọc, vì nó thấy mọi request trước khi vào tầng MVC. Đặt ở tầng sau thì các request không khớp lớp xử lý nào — đường dẫn sai, tài nguyên tĩnh — sẽ lọt qua mà không được kiểm tra.
Không xử lý gì thì một exception chưa bắt trong controller trả về status nào?
A.400, vì Spring suy ra rằng dữ liệu đầu vào có vấn đề
B.500, kể cả khi nguyên nhân thật là dữ liệu client gửi sai
C.404, vì không tìm được cách xử lý cho request đó
D.503, để client biết dịch vụ tạm thời không sẵn sàng
Đáp án: B
Mã 500 — kể cả khi nguyên nhân thật là dữ liệu client gửi sai. Đây là vấn đề vì client không phân biệt được lỗi của mình với lỗi máy chủ, nên nó có thể thử lại một request không bao giờ thành công.
D.Cơ chế thử lại khi request thất bại vì lỗi tạm thời
Đáp án: C
Định dạng của thân phản hồi lỗi, theo một chuẩn có sẵn với các trường quy ước: kiểu lỗi, tiêu đề, mã trạng thái, mô tả chi tiết, và đường dẫn xảy ra lỗi. Mở rộng thêm trường riêng được.
Vì sao không nên trả thẳng JPA entity làm response body?
A.Response body bắt buộc phải là kiểu do Spring định nghĩa
B.Entity không có constructor rỗng nên không tạo lại được
C.Lộ cấu trúc bảng, dễ rò rỉ trường nhạy cảm và gây lỗi lazy loading
D.Jackson không serialize được các lớp có annotation của JPA
Đáp án: C
Ba lý do: nó lộ cấu trúc bảng ra ngoài, dễ vô tình trả về trường nhạy cảm như mật khẩu băm, và các quan hệ lazy load gây lỗi khi serialize ngoài phạm vi giao dịch. Thêm một cột vào bảng cũng đổi luôn hợp đồng API.
Cấu hình CORS trong Spring Boot nên làm ở đâu khi đã có Spring Security?
A.Ở phía client, bằng cách khai báo các nguồn được phép gọi
B.Khai một nguồn cấu hình CORS và bật nó trong chuỗi filter của Security
C.Chỉ cần annotation cho phép nguồn trên từng controller
D.Trong tệp cấu hình bằng một thuộc tính có sẵn của Spring Boot
Đáp án: B
Khai một nguồn cấu hình CORS rồi bật nó trong chuỗi bộ lọc của Security. Chuỗi đó chạy trước tầng MVC, nên cấu hình chỉ đặt ở tầng MVC không kịp áp cho request kiểm tra trước và trình duyệt báo lỗi.
Spring 6 giới thiệu RestClient. Nó khác RestTemplate và WebClient thế nào?
A.API dạng chuỗi như WebClient nhưng đồng bộ, không cần phụ thuộc reactive
B.Nó là bản đổi tên của API cũ, hành vi hoàn toàn giống
C.Nó chỉ dùng được trong ứng dụng reactive dựa trên WebFlux
D.Nó thay thế cả hai và hai API kia đã bị gỡ khỏi framework
Đáp án: A
Nó có API dạng chuỗi giống API bất đồng bộ nhưng chạy đồng bộ và không kéo theo phụ thuộc reactive. Nó lấp khoảng trống giữa một API cũ đã ngừng phát triển và một API bất đồng bộ vốn quá nặng cho nhu cầu gọi HTTP thông thường.
@Valid trên tham số controller và @Validated trên class service khác nhau thế nào?
A.Cái đầu do MVC xử lý, cái sau qua AOP nên áp được cho mọi bean
B.Cái sau chỉ dùng được với các annotation ràng buộc tự định nghĩa
C.Cái đầu kiểm tra sâu vào object lồng nhau, cái sau thì không
D.Cái đầu ném exception còn cái sau chỉ ghi log cảnh báo
Đáp án: A
Cái đầu do Spring MVC xử lý ở tầng web và ném một ngoại lệ riêng mà lớp xử lý lỗi bắt được. Cái sau kích hoạt kiểm tra qua proxy, nên áp được cho mọi bean chứ không riêng controller — nhưng chỉ khi phương thức được gọi từ bên ngoài.
Viết một annotation ràng buộc tự định nghĩa cần những gì?
A.Một lớp kế thừa từ lớp ràng buộc cơ sở của framework
B.Chỉ cần một annotation với biểu thức chính quy mô tả quy tắc
C.Một bean được đăng ký vào danh sách validator toàn cục
D.Một annotation đánh dấu @Constraint và một lớp validator đi kèm
Đáp án: D
Hai phần: một annotation mang annotation đánh dấu ràng buộc và trỏ tới lớp kiểm tra, cùng một lớp kiểm tra hiện thực interface chuẩn với phương thức trả về hợp lệ hay không.
A.Proxy kiểm tra cache theo khoá; có thì trả luôn, không thì gọi method rồi lưu
B.Kết quả được chia sẻ giữa mọi instance của ứng dụng
C.Method được chạy nền định kỳ để làm mới giá trị trong cache
D.Kết quả được lưu vào bộ nhớ của JVM và tồn tại tới khi hết bộ nhớ
Đáp án: A
Proxy chặn lời gọi, tính khoá từ tham số, và tra cache. Có thì trả luôn không chạy phương thức; không thì chạy rồi lưu kết quả. Vì đi qua proxy nên gọi từ trong cùng bean sẽ bỏ qua cache hoàn toàn.
A.Spring tự chia các lần chạy luân phiên giữa các instance
B.Chỉ instance được bầu làm leader chạy job
C.Job chỉ chạy ở instance khởi động đầu tiên
D.Cả 3 instance đều chạy job đó, gây trùng lặp
Đáp án: D
Cả ba đều chạy — mỗi tiến trình có bộ lập lịch riêng và không biết gì về nhau. Với tác vụ gửi email hay tính công nợ, đó là ba lần thực hiện trùng lặp. Cần khoá phân tán hoặc một bộ lập lịch bên ngoài.
A.Hoãn khởi tạo tới lần đầu bean được dùng thay vì lúc khởi động
B.Bean được tạo mới mỗi lần được inject vào nơi khác
C.Bean chỉ được tạo khi profile tương ứng đang active
D.Bean được giải phóng khỏi bộ nhớ khi không còn ai dùng
Đáp án: A
Hoãn việc khởi tạo tới lần đầu bean được dùng, thay vì tạo ngay lúc khởi động. Đổi lại, lỗi cấu hình của bean đó không lộ ra lúc khởi động mà xuất hiện khi có request thật — nên dùng có chọn lọc.
Ứng dụng cần chạy một đoạn code ngay sau khi khởi động xong. Dùng gì?
A.Một tác vụ theo lịch đặt chạy sau vài giây kể từ khi khởi động
B.Một phương thức đánh dấu chạy sau khi bean được tạo
C.Một khối static trong lớp chứa phương thức main
D.ApplicationRunner hoặc CommandLineRunner
Đáp án: D
Một trong hai interface chạy sau khởi động. Chúng chạy khi container đã sẵn sàng hoàn toàn nên mọi bean đều dùng được — khác với phương thức khởi tạo của một bean, vốn chạy khi chỉ riêng bean đó sẵn sàng.
Sửa một trường của entity đang được quản lý trong method @Transactional mà không gọi save(). Chuyện gì xảy ra?
A.Thay đổi vẫn được ghi xuống DB nhờ dirty checking
B.Ứng dụng ném exception vì entity bị sửa ngoài repository
C.Thay đổi chỉ có hiệu lực sau khi gọi lại phương thức tìm entity
D.Thay đổi bị mất vì chưa được ghi vào persistence context
Đáp án: A
Thay đổi vẫn được ghi xuống cơ sở dữ liệu. Ngữ cảnh lưu trữ giữ một bản chụp trạng thái lúc nạp entity, và khi giao dịch kết thúc nó so lại — trường nào khác thì sinh câu lệnh cập nhật tương ứng.
Đổi tất cả quan hệ sang FetchType.EAGER để tránh lỗi lazy loading là giải pháp thế nào?
A.Trung tính — hiệu năng như nhau vì dữ liệu sớm muộn cũng phải đọc
B.Tốt — nó loại bỏ hoàn toàn một lớp lỗi lúc chạy
C.Xấu — nó gây N+1 và kéo cả cây dữ liệu ở mọi truy vấn
D.Tốt nếu bật thêm cache cấp hai của JPA
Đáp án: C
Xấu. Nó chữa triệu chứng nhưng khiến mọi truy vấn kéo theo cả cây dữ liệu, và với quan hệ một-nhiều thì sinh ra vấn đề N+1. Cách đúng là giữ lazy load và nạp tường minh các quan hệ cần cho từng truy vấn.
Trong quan hệ hai chiều @OneToMany / @ManyToOne, phía nào là owning side?
A.Phía @OneToMany — phía chứa danh sách các phần tử con
B.Phía @ManyToOne — phía giữ cột khoá ngoại
C.Cả hai phía đều sở hữu và cùng cập nhật quan hệ
D.Phía được khai báo trước trong mã nguồn của entity
Đáp án: B
Phía nhiều-một, vì đó là phía giữ cột khoá ngoại trong bảng. Phía một-nhiều là phía nghịch đảo, khai bằng thuộc tính trỏ về tên trường bên kia. Chỉ thay đổi ở phía sở hữu mới được ghi xuống.
Thêm tham số Pageable vào method của repository cho kết quả gì?
A.Kết quả được nạp toàn bộ rồi cắt trang trong bộ nhớ
B.Kết quả được lưu vào cache theo từng trang
C.Spring tự thêm LIMIT/OFFSET và sắp xếp vào câu truy vấn
D.Repository trả về một stream đọc dần từ cơ sở dữ liệu
Đáp án: C
Spring tự thêm mệnh đề giới hạn, bỏ qua và sắp xếp vào câu truy vấn. Kiểu trả về dạng trang còn chạy thêm một truy vấn đếm để biết tổng số bản ghi và tổng số trang.
@Query với JPQL và với nativeQuery = true khác nhau thế nào?
A.JPQL chỉ dùng được cho truy vấn đọc, native dùng được cho cả ghi
B.JPQL được kiểm tra cú pháp lúc chạy còn native lúc biên dịch
C.Native nhanh hơn vì bỏ qua tầng ánh xạ của JPA
D.JPQL viết theo tên entity và độc lập DB; native viết SQL thẳng cho một DB
Đáp án: D
JPQL viết theo tên entity và tên trường Java, độc lập với hệ quản trị, và được kiểm tra cú pháp khi khởi động. Câu SQL thuần viết thẳng theo tên bảng và cột, dùng được tính năng riêng của hệ quản trị nhưng khoá ứng dụng vào hệ đó.
A.Đánh dấu phiên bản lược đồ để phục vụ việc di trú
B.Lưu lịch sử các phiên bản của bản ghi để xem lại sau
C.Optimistic locking — ghi đè đồng thời bị phát hiện và ném exception
D.Khoá dòng ở cơ sở dữ liệu khi entity được nạp lên
Đáp án: C
Khoá lạc quan. JPA thêm điều kiện phiên bản vào câu lệnh cập nhật và tăng giá trị đó lên; nếu không dòng nào bị tác động — nghĩa là ai đó đã ghi trước — nó ném ngoại lệ thay vì lặng lẽ ghi đè.
@Transactional(readOnly = true) mang lại lợi ích gì?
A.Transaction chạy ở mức isolation thấp nhất để nhanh hơn
B.Cơ sở dữ liệu từ chối mọi câu lệnh ghi trong transaction đó
C.Kết quả truy vấn được tự động lưu vào cache
D.Hibernate bỏ dirty checking, và driver có thể định tuyến sang replica đọc
Đáp án: D
Hibernate bỏ việc giữ bản chụp trạng thái để kiểm tra bẩn, giảm bộ nhớ và thời gian khi truy vấn trả về nhiều entity. Và với hạ tầng có bản sao đọc, thuộc tính này là tín hiệu để định tuyến sang đó.
Mặc định @Transactional rollback khi gặp loại exception nào?
A.Chỉ khi gọi tường minh phương thức đánh dấu rollback
B.Chỉ unchecked exception; checked exception thì vẫn commit
C.Chỉ các exception do tầng cơ sở dữ liệu ném ra
D.Mọi exception, cả checked lẫn unchecked
Đáp án: B
Chỉ ngoại lệ không kiểm tra. Ngoại lệ kiểm tra thì giao dịch vẫn xác nhận — nên một phương thức ném ngoại lệ kiểm tra giữa chừng sẽ ghi luôn các thay đổi dở dang. Muốn đổi thì khai báo thuộc tính chỉ định loại ngoại lệ.
Vì sao không nên dùng spring.jpa.hibernate.ddl-auto=update ở production?
A.Nó chỉ hoạt động với một số hệ quản trị nhất định
B.Nó suy ra thay đổi lược đồ tự động, không kiểm soát và không rollback được
C.Nó yêu cầu tài khoản cơ sở dữ liệu có quyền quản trị cao nhất
D.Nó làm chậm quá trình khởi động ứng dụng đáng kể
Đáp án: B
Nó suy ra thay đổi lược đồ từ entity một cách tự động — không rà soát được trước, không quay lui được, và không xử lý được việc đổi tên hay chuyển đổi dữ liệu. Công cụ di trú với các tệp có phiên bản là cách đúng.
A.Nó không cần khai báo lớp controller cần kiểm thử
B.Nó chỉ nạp tầng web, các bean khác phải được giả lập
C.Nó chỉ kiểm tra được các endpoint trả về JSON
D.Nó chạy trên một server thật ở cổng ngẫu nhiên
Đáp án: B
Nó chỉ nạp tầng web — controller, bộ chuyển đổi thông điệp, cấu hình xác thực dữ liệu — còn các bean khác phải được giả lập. Kiểm thử khởi động nhanh hơn nhiều và tập trung đúng vào tầng đang kiểm.
@MockBean (nay là @MockitoBean) khác @Mock của Mockito thế nào?
A.Nó tạo mock có hành vi mặc định thay vì trả về null
B.Nó chỉ dùng được với các bean có interface
C.Nó tự động ghi lại mọi lời gọi để so sánh với lần chạy trước
D.Nó thay bean trong application context, không chỉ tạo object giả
Đáp án: D
Nó thay bean trong container chứ không chỉ tạo một đối tượng giả. Nhờ vậy mọi bean khác đang tiêm phụ thuộc đó sẽ nhận được bản giả — điều mà annotation của thư viện giả lập thuần tuý không làm được.
A.Công cụ truy vết phân tán theo dõi request qua nhiều dịch vụ
B.Lớp trừu tượng thu thập metric, xuất được sang nhiều hệ giám sát
C.Thư viện ghi log có cấu trúc thay cho log truyền thống
D.Bộ đo hiệu năng chạy benchmark cho các method của ứng dụng
Đáp án: B
Nó là lớp trừu tượng cho việc thu thập số liệu đo — tương tự vai trò của một mặt tiền ghi log. Bạn viết mã đo đạc một lần, rồi xuất sang hệ giám sát nào là do phụ thuộc trên đường dẫn lớp quyết định.
Graceful shutdown trong Spring Boot cần cấu hình gì?
A.Bật thuộc tính shutdown graceful và đặt thời hạn chờ tắt
B.Chuyển sang mô hình reactive vì mô hình servlet không hỗ trợ
C.Đăng ký một hook tự viết để đóng các tài nguyên khi nhận tín hiệu
D.Không cần gì; Spring Boot luôn chờ request hoàn tất trước khi tắt
Đáp án: A
Bật thuộc tính tương ứng và đặt thời hạn chờ. Khi nhận tín hiệu dừng, máy chủ nhúng ngừng nhận kết nối mới và chờ các request đang xử lý hoàn tất trong khoảng thời hạn đó rồi mới tắt.
Các endpoint lộ cấu hình, biến môi trường, ảnh heap, danh sách bean và bản đồ đường dẫn. Chúng tiết lộ chuỗi kết nối, khoá bí mật và cấu trúc nội bộ. Mặc định Spring Boot chỉ phơi ra endpoint sức khoẻ, và mở thêm là quyết định có chủ đích.
Nâng từ Spring Boot 2 lên 3 gặp thay đổi phá vỡ lớn nhất nào?
A.Đổi định dạng tệp cấu hình từ YAML sang một định dạng mới
B.Đổi namespace từ javax.* sang jakarta.* và yêu cầu Java 17
C.Bỏ hoàn toàn mô hình servlet, chỉ còn WebFlux
D.Bỏ cơ chế auto-configuration, phải khai báo bean thủ công
Đáp án: B
Đổi không gian tên từ tiền tố cũ sang tiền tố mới cho toàn bộ API của servlet, JPA và xác thực dữ liệu, cùng với yêu cầu Java 17 trở lên. Các thư viện chưa hỗ trợ không gian tên mới sẽ không chạy được.
Đổi log level của một package lúc ứng dụng đang chạy làm thế nào?
A.Gọi endpoint loggers của actuator bằng một request POST
B.Gửi một tín hiệu hệ điều hành tới tiến trình Java
C.Sửa tệp cấu hình rồi chờ ứng dụng tự nạp lại
D.Không đổi được lúc chạy; phải khởi động lại ứng dụng
Đáp án: A
Gọi endpoint quản lý bộ ghi log của actuator bằng một request ghi, kèm mức log mong muốn. Nhờ đó bật log chi tiết cho đúng một gói khi đang có sự cố, rồi tắt lại — không phải khởi động lại và không ảnh hưởng phần còn lại.
spring.jpa.open-in-view bật mặc định gây vấn đề gì?
A.Giữ kết nối database suốt vòng đời của request
B.Làm mọi quan hệ lazy trở thành eager khi truy vấn
C.Gây lỗi khi truy cập quan hệ lazy ngoài transaction
D.Buộc mọi truy vấn phải chạy trong một transaction riêng
Đáp án: A
Nó giữ kết nối database suốt vòng đời của request, kể cả trong lúc dựng phản hồi hoặc gọi dịch vụ ngoài. Nhóm kết nối cạn sớm hơn nhiều so với dự kiến, và triệu chứng là lỗi chờ kết nối dưới tải cao.
Probe liveness và readiness của actuator khác nhau ở mục đích nào?
A.Một trả về trạng thái chi tiết, một chỉ trả về mã trạng thái
B.Một chạy lúc khởi động, một chạy định kỳ khi đang phục vụ
C.Một quyết định khởi động lại, một quyết định nhận lưu lượng
D.Một kiểm tra ứng dụng, một kiểm tra các phụ thuộc bên ngoài
Đáp án: C
Một probe quyết định có khởi động lại ứng dụng hay không, probe kia quyết định có gửi lưu lượng tới hay không. Ứng dụng đang khởi động hoặc mất kết nối tạm thời chưa sẵn sàng phục vụ nhưng vẫn khoẻ, nên khởi động lại nó là phản ứng sai.
Muốn trả về danh sách lỗi theo từng trường thay vì thông báo chung. Làm thế nào?
A.Khai báo thông báo lỗi riêng cho từng annotation ràng buộc
B.Bật chế độ hiển thị lỗi chi tiết trong cấu hình ứng dụng
C.Tự kiểm tra từng trường trong controller trước khi xử lý
D.Bắt ngoại lệ kiểm tra dữ liệu trong lớp xử lý lỗi chung
Đáp án: D
Bắt ngoại lệ kiểm tra dữ liệu trong lớp xử lý lỗi chung. Ngoại lệ đó mang theo danh sách lỗi của từng trường, nên chỉ cần duyệt qua và chuyển thành cấu trúc phản hồi mà giao diện cần.
Cần lần theo toàn bộ log của một request qua nhiều lớp. Cách nào phù hợp?
A.Gắn mã theo dõi vào ngữ cảnh chẩn đoán của luồng
B.Truyền mã theo dõi làm tham số cho mọi phương thức
C.Ghi log kèm mốc thời gian rồi lọc theo khoảng thời gian
D.Bật mức log chi tiết nhất cho toàn bộ ứng dụng
Đáp án: A
Gắn mã theo dõi vào ngữ cảnh chẩn đoán của luồng ở một bộ lọc đầu vào. Mọi dòng log của luồng đó tự mang theo mã, nên lọc theo mã là ra toàn bộ hành trình của một request.
Gọi API bên ngoài bằng client HTTP của Spring cần cấu hình gì trước tiên?
A.Bộ chuyển đổi JSON để đọc phản hồi trả về
B.Bộ ghi log để ghi lại nội dung mọi lời gọi ra ngoài
C.Kích thước tối đa của phản hồi được phép nhận
D.Thời gian chờ kết nối và thời gian chờ đọc dữ liệu
Đáp án: D
Thời gian chờ kết nối và thời gian chờ đọc dữ liệu. Mặc định của một số client là chờ vô hạn, nên một dịch vụ ngoài treo sẽ giữ luồng của ứng dụng mãi và làm cạn nhóm luồng — sự cố lan sang cả các chức năng không liên quan.
API trả về thời điểm dưới dạng mảng số thay vì chuỗi ngày giờ. Nguyên nhân?
A.Kiểu ngày giờ được dùng không phải kiểu chuẩn của ngôn ngữ
B.Thiếu module xử lý kiểu ngày giờ hoặc cấu hình tương ứng
C.Múi giờ của máy chủ chưa được cấu hình đúng
D.Trường đó chưa được khai báo annotation định dạng
Đáp án: B
Thiếu module xử lý kiểu ngày giờ hoặc cấu hình tương ứng. Thư viện JSON mặc định xem chúng như đối tượng thường và ghi ra từng thành phần. Spring Boot thường đã cấu hình sẵn, nên hiện tượng này hay gặp khi tự dựng bộ chuyển đổi.
Một bean giữ nhóm luồng riêng cần dọn dẹp khi ứng dụng tắt. Dùng gì?
A.Đăng ký một hook chạy khi máy ảo kết thúc
B.Annotation đánh dấu phương thức chạy trước khi bean bị huỷ
C.Không cần gì vì các luồng tự kết thúc khi tiến trình dừng
D.Dọn dẹp trong khối bảo đảm chạy của phương thức chính
Đáp án: B
Dùng annotation đánh dấu phương thức chạy trước khi bean bị huỷ. Spring gọi nó trong quá trình tắt ứng dụng, nên nhóm luồng được dừng có trật tự và các công việc đang chạy có cơ hội hoàn tất.