اختبار: تكوين قاعدة البيانات
اختبر معرفتك بـ PostgreSQL وHibernate وLombok.
30 سؤالًا - انقر على كل سؤال لكشف الإجابة.
الأسئلة 1-10: PostgreSQL
السؤال 1: كيف تضيف PostgreSQL إلى مشروع Spring Boot؟
الإجابة:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
السؤال 2: كيف تقوم بتكوين اتصال PostgreSQL؟
الإجابة:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
السؤال 3: كيف تقوم بتشغيل PostgreSQL باستخدام Docker؟
الإجابة:
docker run -d \
--name postgres \
-e POSTGRES_DB=mydb \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
postgres:15
السؤال 4: ما الفرق بين H2 وPostgreSQL؟
الإجابة:
| H2 | PostgreSQL |
|---|---|
| في الذاكرة (افتراضيًا) | دائم |
| تطوير/اختبارات | إنتاج |
| لا حاجة للتثبيت | يتطلب تثبيت |
| البيانات تُفقد عند إعادة التشغيل | البيانات دائمة |
| خفيف | كامل وقوي |
السؤال 5: كيف تقوم بتكوين تجمع الاتصالات؟
الإجابة: يستخدم Spring Boot HikariCP افتراضيًا:
spring:
datasource:
hikari:
maximum-pool-size: 10
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
السؤال 6: كيف تحدد مخططًا افتراضيًا؟
الإجابة:
spring:
jpa:
properties:
hibernate:
default_schema: my_schema
أو في عنوان URL:
url: jdbc:postgresql://localhost:5432/mydb?currentSchema=my_schema
السؤال 7: كيف تدير المناطق الزمنية مع PostgreSQL؟
الإجابة:
spring:
jpa:
properties:
hibernate:
jdbc:
time_zone: UTC
موصى به: التخزين في UTC، التحويل عند العرض.
السؤال 8: كيف تقوم بتكوين SSL لـ PostgreSQL؟
الإجابة:
spring:
datasource:
url: jdbc:postgresql://host:5432/db?ssl=true&sslmode=require
الأوضاع: disable, allow, prefer, require, verify-ca, verify-full
السؤال 9: كيف تنشئ قاعدة بيانات باستخدام Docker Compose؟
الإجابة:
# docker-compose.yml
services:
db:
image: postgres:15
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
volumes:
postgres-data:
السؤال 10: كيف تقوم بتخزين بيانات اعتماد قاعدة البيانات خارجيًا؟
الإجابة:
spring:
datasource:
url: ${DB_URL}
username: ${DB_USER}
password: ${DB_PASSWORD}
تحديد متغيرات البيئة:
export DB_URL=jdbc:postgresql://localhost/mydb
export DB_USER=postgres
export DB_PASSWORD=secret
الأسئلة 11-20: Hibernate DDL
السؤال 11: ما هو hibernate.ddl-auto؟
الإجابة: خاصية تتحكم في التوليد التلقائي للمخطط:
| القيمة | السلوك |
|---|---|
none | لا يوجد إجراء |
validate | التحقق من صحة المخطط |
update | تحديث المخطط |
create | إنشاء المخطط (حذف قبل) |
create-drop | إنشاء وحذف عند الإيقاف |
السؤال 12: ما القيمة التي يجب استخدامها في الإنتاج؟
الإجابة: none أو validate
spring:
jpa:
hibernate:
ddl-auto: validate
في الإنتاج، استخدم أدوات الترحيل (Flyway، Liquibase).
السؤال 13: كيف يقوم Hibernate بتوليد أسماء الجداول؟
الإجابة: الاستراتيجية الافتراضية: camelCase إلى snake_case
@Entity
public class UserProfile { }
// Table: user_profile
تخصيص:
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
السؤال 14: كيف تحدد اسم الجدول؟
الإجابة:
@Entity
@Table(name = "utilisateurs")
public class User {
// ...
}
السؤال 15: كيف تحدد اسم العمود؟
الإجابة:
@Entity
public class User {
@Column(name = "nom_complet")
private String fullName;
@Column(name = "courriel", unique = true, nullable = false)
private String email;
}
السؤال 16: كيف تحدد مفتاحًا أساسيًا يتم توليده تلقائيًا؟
الإجابة:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// استراتيجيات:
// IDENTITY: زيادة تلقائية في قاعدة البيانات
// SEQUENCE: تسلسل قاعدة البيانات
// TABLE: جدول التسلسل
// AUTO: اختيار تلقائي
السؤال 17: كيف تحدد قيدًا فريدًا؟
الإجابة:
// على عمود
@Column(unique = true)
private String email;
// على عدة أعمدة
@Table(uniqueConstraints = {
@UniqueConstraint(columnNames = {"firstName", "lastName"})
})
public class User { }
السؤال 18: كيف تحدد فهرسًا؟
الإجابة:
@Entity
@Table(indexes = {
@Index(name = "idx_email", columnList = "email"),
@Index(name = "idx_name", columnList = "lastName, firstName")
})
public class User { }
السؤال 19: كيف ترى SQL الذي يولده Hibernate؟
الإجابة:
spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
logging:
level:
org.hibernate.SQL: DEBUG
org.hibernate.orm.jdbc.bind: TRACE
السؤال 20: كيف تتحقق من صحة المخطط عند بدء التشغيل؟
الإجابة:
spring:
jpa:
hibernate:
ddl-auto: validate
تفشل التطبيق عند بدء التشغيل إذا لم يتطابق المخطط مع الكيانات.
الأسئلة 21-30: Lombok
السؤال 21: ما هو Lombok؟
الإجابة: مكتبة تولد الكود المتكرر عبر التعليقات التوضيحية:
- Getters/Setters
- المنشئون
- equals/hashCode
- toString
- Builder
تقلل بشكل كبير من الكود المتكرر.
السؤال 22: كيف تضيف Lombok؟
الإجابة:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
قم أيضًا بتثبيت إضافة IDE (IntelliJ، Eclipse).
السؤال 23: كيف تولد getters وsetters؟
الإجابة:
@Getter
@Setter
public class User {
private Long id;
private String name;
}
// يولد:
// getId(), setId()
// getName(), setName()
السؤال 24: ما هو @Data؟
الإجابة: يجمع بين عدة تعليقات توضيحية:
@Data // = @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor
public class User {
private Long id;
private String name;
}
السؤال 25: كيف تنشئ builder؟
الإجابة:
@Builder
public class User {
private Long id;
private String name;
private String email;
}
// الاستخدام:
User user = User.builder()
.name("John")
.email("john@example.com")
.build();
السؤال 26: كيف تولد المنشئين؟
الإجابة:
@NoArgsConstructor // منشئ فارغ
@AllArgsConstructor // جميع الحقول
@RequiredArgsConstructor // الحقول النهائية و@NonNull
public class User {
private final Long id;
@NonNull
private String name;
private String email;
}
السؤال 27: كيف تستخدم @Slf4j للتسجيل؟
الإجابة:
@Slf4j
@Service
public class UserService {
public void process() {
log.info("Processing...");
log.debug("Details: {}", data);
log.error("Error occurred", exception);
}
}
يولد: private static final Logger log = LoggerFactory.getLogger(UserService.class);
السؤال 28: كيف تستبعد حقلًا من toString؟
الإجابة:
@ToString(exclude = "password")
public class User {
private String email;
private String password; // مستبعد من toString
}
// أو
@ToString.Exclude
private String password;
السؤال 29: كيف تستبعد حقلًا من equals/hashCode؟
الإجابة:
@EqualsAndHashCode(exclude = "orders")
public class User {
private Long id;
private List<Order> orders; // مستبعد
}
// أو
@EqualsAndHashCode.Exclude
private List<Order> orders;
السؤال 30: ما هي أفضل الممارسات مع Lombok وJPA؟
الإجابة:
- تجنب
@Dataعلى الكيانات (مشاكل مع التحميل الكسول) - استبعاد العلاقات من equals/hashCode
- استخدام
@ToString.Excludeللعلاقات ثنائية الاتجاه - تفضيل
@Getterو@Setterبشكل منفصل - الانتباه إلى
@EqualsAndHashCodeمع الكيانات
@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString(exclude = "orders")
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {
@Id
@EqualsAndHashCode.Include
private Long id;
@OneToMany(mappedBy = "user")
private List<Order> orders;
}
النتيجة
| النتيجة | المستوى |
|---|---|
| 27-30 | ممتاز - تكوين متقن |
| 21-26 | جيد - بعض المراجعات |
| 15-20 | متوسط - أعد قراءة الفصول |
| أقل من 15 | بحاجة إلى مراجعة |