[{"data":1,"prerenderedAt":3136},["ShallowReactive",2],{"navigation_docs":3,"-phong-van-ngan-hang-cau-hoi-design-pattern":420,"-phong-van-ngan-hang-cau-hoi-design-pattern-surround":3131},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":3124,"extension":3125,"links":3126,"meta":3127,"navigation":3128,"path":104,"seo":3129,"stem":105,"__hash__":3130},"docs\u002F1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern.md","Ngân hàng câu hỏi Design Pattern (.NET)",{"type":424,"value":425,"toc":3042},"minimark",[426,436,441,446,466,470,473,504,508,515,577,581,595,598,602,605,644,648,659,669,673,677,684,688,736,754,766,775,779,784,793,796,807,811,825,828,832,907,910,914,917,982,986,1007,1011,1014,1044,1058,1062,1075,1083,1093,1108,1111,1115,1119,1130,1134,1137,1162,1165,1169,1180,1210,1214,1217,1232,1235,1239,1242,1245,1265,1269,1284,1288,1303,1307,1311,1318,1381,1384,1388,1401,1404,1408,1415,1458,1469,1473,1491,1495,1498,1501,1515,1519,1526,1600,1604,1610,1635,1642,1646,1674,1698,1702,1709,1713,1718,1721,1809,1812,1816,1820,1827,1838,1842,1913,1917,1928,1932,1937,1947,1953,1957,1960,2030,2033,2037,2051,2059,2064,2075,2081,2085,2088,2127,2134,2138,2144,2164,2167,2171,2185,2189,2196,2277,2280,2300,2304,2311,2373,2385,2389,2392,2435,2438,2442,2456,2459,2463,2466,2477,2480,2484,2488,2491,2495,2513,2520,2524,2527,2531,2539,2543,2546,2550,2554,2560,2585,2592,2596,2599,2604,2618,2623,2634,2637,2641,2644,2679,2682,2686,2689,2700,2704,2743,2746,2757,2763,2767,2802,2805,2809,2812,2886,2890,2896,2900,2913,2917,2959,2962,2972,2975,2979,3038],[427,428,431,435],"callout",{"color":429,"icon":430},"primary","i-lucide-info",[432,433,434],"strong",{},"Design Pattern là câu hỏi cốt lõi của phỏng vấn .NET — fresher 1-2 pattern cơ bản, junior trở lên hỏi sâu cả pattern .NET-specific (Repository, MediatR, Options)."," File này tổng hợp 55+ câu hỏi thực tế từ ITviec, TopDev, Viblo, ScholarHat, codewithmukesh, Microsoft Learn.",[437,438,440],"h2",{"id":439},"a-tổng-quan","A. Tổng quan",[442,443,445],"h3",{"id":444},"_1-design-pattern-là-gì","1. Design Pattern là gì?",[447,448,449,450,453,454,457,458,461,462,465],"p",{},"Giải pháp ",[432,451,452],{},"tái sử dụng"," cho ",[432,455,456],{},"vấn đề lập trình lặp lại"," trong design. Không phải code copy-paste — là ",[432,459,460],{},"template (khuôn mẫu)"," để áp dụng. Khái niệm xuất phát từ kiến trúc (Christopher Alexander), được phổ cập trong lập trình bởi cuốn ",[432,463,464],{},"\"Design Patterns\" của Gang of Four (1994)",".",[442,467,469],{"id":468},"_2-vì-sao-phỏng-vấn-net-hay-hỏi-design-pattern","2. Vì sao phỏng vấn .NET hay hỏi Design Pattern?",[447,471,472],{},"Vì recruiter muốn biết:",[474,475,476,484,491,498],"ul",{},[477,478,479,480,483],"li",{},"Bạn có viết được ",[432,481,482],{},"code maintainable, scalable"," chưa.",[477,485,486,487,490],{},"Bạn có ",[432,488,489],{},"đọc hiểu framework code"," không (ASP.NET Core, EF Core đầy pattern).",[477,492,493,494,497],{},"Có ",[432,495,496],{},"trải nghiệm thực"," với codebase phức tạp chưa.",[477,499,493,500,503],{},[432,501,502],{},"language chuẩn"," để giao tiếp team không (gọi \"Strategy pattern\" hiệu quả hơn mô tả 5 câu).",[442,505,507],{"id":506},"_3-có-bao-nhiêu-design-pattern-3-nhóm-chính","3. Có bao nhiêu Design Pattern? 3 nhóm chính?",[447,509,510,511,514],{},"Gang of Four liệt kê ",[432,512,513],{},"23 pattern",", chia 3 nhóm:",[516,517,518,534],"table",{},[519,520,521],"thead",{},[522,523,524,528,531],"tr",{},[525,526,527],"th",{},"Nhóm",[525,529,530],{},"Tập trung",[525,532,533],{},"Pattern phổ biến",[535,536,537,551,564],"tbody",{},[522,538,539,545,548],{},[540,541,542],"td",{},[432,543,544],{},"Creational",[540,546,547],{},"Tạo object",[540,549,550],{},"Singleton, Factory, Builder, Prototype, Abstract Factory",[522,552,553,558,561],{},[540,554,555],{},[432,556,557],{},"Structural",[540,559,560],{},"Lắp ráp class\u002Fobject",[540,562,563],{},"Adapter, Decorator, Facade, Proxy, Composite, Bridge, Flyweight",[522,565,566,571,574],{},[540,567,568],{},[432,569,570],{},"Behavioral",[540,572,573],{},"Tương tác + thuật toán",[540,575,576],{},"Strategy, Observer, Command, Template Method, Chain of Responsibility, Iterator, State, Mediator",[442,578,580],{"id":579},"_4-design-pattern-khác-design-principle-ra-sao","4. Design Pattern khác Design Principle ra sao?",[474,582,583,589],{},[477,584,585,588],{},[432,586,587],{},"Principle"," (nguyên lý): rules \u002F guidelines như SOLID, DRY, KISS, YAGNI — abstract.",[477,590,591,594],{},[432,592,593],{},"Pattern",": giải pháp cụ thể cho vấn đề cụ thể — concrete template.",[447,596,597],{},"Pattern thực thi Principle. Ví dụ: Strategy pattern thực thi OCP + DIP.",[442,599,601],{"id":600},"_5-pattern-nào-fresher-net-phải-biết","5. Pattern nào fresher .NET phải biết?",[447,603,604],{},"Top 6:",[606,607,608,614,620,626,632,638],"ol",{},[477,609,610,613],{},[432,611,612],{},"Singleton"," — câu PV gần như chắc chắn.",[477,615,616,619],{},[432,617,618],{},"Factory (Method\u002FAbstract)"," — tạo object linh hoạt.",[477,621,622,625],{},[432,623,624],{},"Strategy"," — swap algorithm runtime, ví dụ rất hay.",[477,627,628,631],{},[432,629,630],{},"Repository"," — luôn xuất hiện trong .NET có DB.",[477,633,634,637],{},[432,635,636],{},"Dependency Injection (pattern)"," — ASP.NET Core built-in.",[477,639,640,643],{},[432,641,642],{},"Observer \u002F Event"," — .NET event built-in chính là Observer.",[442,645,647],{"id":646},"_6-khi-nào-không-nên-áp-dụng-design-pattern","6. Khi nào KHÔNG nên áp dụng Design Pattern?",[474,649,650,653,656],{},[477,651,652],{},"Script nhỏ, prototype, throwaway code.",[477,654,655],{},"Khi áp pattern làm code phức tạp hơn vấn đề thực tế.",[477,657,658],{},"\"Pattern fever\" — ép pattern lên mọi vấn đề → over-engineering.",[447,660,661,664,665,668],{},[432,662,663],{},"Quy tắc:"," áp pattern khi ",[432,666,667],{},"đau"," thật, không \"preemptive\".",[437,670,672],{"id":671},"b-creational-patterns","B. Creational Patterns",[442,674,676],{"id":675},"_7-singleton-định-nghĩa","7. Singleton — định nghĩa?",[447,678,679,680,683],{},"Đảm bảo class chỉ có ",[432,681,682],{},"1 instance"," suốt app lifetime, expose qua điểm truy cập toàn cục.",[442,685,687],{"id":686},"_8-implement-singleton-thread-safe-c","8. Implement Singleton thread-safe C#?",[689,690,695],"pre",{"className":691,"code":692,"language":693,"meta":694,"style":694},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","public sealed class Logger {\n    private static readonly Lazy\u003CLogger> _instance = new(() => new Logger());\n    public static Logger Instance => _instance.Value;\n    private Logger() {}\n    public void Log(string m) => Console.WriteLine(m);\n}\n","csharp","",[696,697,698,706,712,718,724,730],"code",{"__ignoreMap":694},[699,700,703],"span",{"class":701,"line":702},"line",1,[699,704,705],{},"public sealed class Logger {\n",[699,707,709],{"class":701,"line":708},2,[699,710,711],{},"    private static readonly Lazy\u003CLogger> _instance = new(() => new Logger());\n",[699,713,715],{"class":701,"line":714},3,[699,716,717],{},"    public static Logger Instance => _instance.Value;\n",[699,719,721],{"class":701,"line":720},4,[699,722,723],{},"    private Logger() {}\n",[699,725,727],{"class":701,"line":726},5,[699,728,729],{},"    public void Log(string m) => Console.WriteLine(m);\n",[699,731,733],{"class":701,"line":732},6,[699,734,735],{},"}\n",[447,737,738,741,742,745,746,749,750,753],{},[696,739,740],{},"Lazy\u003CT>"," lo thread-safety + lazy init. ",[696,743,744],{},"sealed"," chặn kế thừa. ",[696,747,748],{},"private"," constructor chặn ",[696,751,752],{},"new"," từ ngoài.",[442,755,757,758],{"id":756},"_9-vì-sao-lazy-tốt-hơn-lock-thủ-công","9. Vì sao Lazy",[759,760,761,762,765],"t",{}," tốt hơn ",[696,763,764],{},"lock"," thủ công?",[447,767,768,770,771,774],{},[696,769,740],{}," dùng ",[696,772,773],{},"LazyThreadSafetyMode.ExecutionAndPublication"," mặc định → thread-safe, không phải viết double-check locking dễ sai. Code ngắn, ý đồ rõ.",[442,776,778],{"id":777},"_10-trong-aspnet-core-dùng-di-singleton-hay-viết-singleton-thủ-công","10. Trong ASP.NET Core, dùng DI Singleton hay viết Singleton thủ công?",[447,780,781],{},[432,782,783],{},"DI container Singleton:",[689,785,787],{"className":691,"code":786,"language":693,"meta":694,"style":694},"services.AddSingleton\u003CILogger, Logger>();\n",[696,788,789],{"__ignoreMap":694},[699,790,791],{"class":701,"line":702},[699,792,786],{},[447,794,795],{},"DI Singleton tốt hơn vì:",[474,797,798,801,804],{},[477,799,800],{},"Không global state — dễ test (thay impl khi test).",[477,802,803],{},"Lifetime quản lý bởi container, dispose đúng lúc.",[477,805,806],{},"Có thể inject dependency vào.",[442,808,810],{"id":809},"_11-singleton-có-hại-gì","11. Singleton có hại gì?",[474,812,813,816,819,822],{},[477,814,815],{},"Global state → khó test (test này ảnh hưởng test kia).",[477,817,818],{},"Hidden coupling — class dùng Singleton không expose dependency.",[477,820,821],{},"Khó parallel test.",[477,823,824],{},"Vi phạm SRP nếu lạm dụng (Singleton ôm nhiều việc).",[447,826,827],{},"→ Dùng DI Scoped\u002FSingleton thay vì viết Singleton thủ công.",[442,829,831],{"id":830},"_12-static-class-vs-singleton-khác-gì","12. Static class vs Singleton — khác gì?",[516,833,834,845],{},[519,835,836],{},[522,837,838,840,843],{},[525,839],{},[525,841,842],{},"Static class",[525,844,612],{},[535,846,847,858,869,878,888,897],{},[522,848,849,852,855],{},[540,850,851],{},"Instance",[540,853,854],{},"Không có",[540,856,857],{},"1",[522,859,860,863,866],{},[540,861,862],{},"Implement interface",[540,864,865],{},"❌",[540,867,868],{},"✅",[522,870,871,874,876],{},[540,872,873],{},"Inject vào class khác",[540,875,865],{},[540,877,868],{},[522,879,880,883,886],{},[540,881,882],{},"Lazy init",[540,884,885],{},"Phần",[540,887,868],{},[522,889,890,893,895],{},[540,891,892],{},"Polymorphism",[540,894,865],{},[540,896,868],{},[522,898,899,902,905],{},[540,900,901],{},"Mock test",[540,903,904],{},"Khó",[540,906,868],{},[447,908,909],{},"→ Singleton linh hoạt hơn, dễ test hơn.",[442,911,913],{"id":912},"_13-factory-method-là-gì-ví-dụ","13. Factory Method là gì? Ví dụ?",[447,915,916],{},"Định nghĩa interface tạo object, để class con quyết concrete type.",[689,918,920],{"className":691,"code":919,"language":693,"meta":694,"style":694},"public interface IShape { void Draw(); }\npublic class Circle : IShape { public void Draw() {} }\npublic class Square : IShape { public void Draw() {} }\n\npublic class ShapeFactory {\n    public IShape Create(string type) => type switch {\n        \"circle\" => new Circle(),\n        \"square\" => new Square(),\n        _ => throw new ArgumentException()\n    };\n}\n",[696,921,922,927,932,937,943,948,953,959,965,971,977],{"__ignoreMap":694},[699,923,924],{"class":701,"line":702},[699,925,926],{},"public interface IShape { void Draw(); }\n",[699,928,929],{"class":701,"line":708},[699,930,931],{},"public class Circle : IShape { public void Draw() {} }\n",[699,933,934],{"class":701,"line":714},[699,935,936],{},"public class Square : IShape { public void Draw() {} }\n",[699,938,939],{"class":701,"line":720},[699,940,942],{"emptyLinePlaceholder":941},true,"\n",[699,944,945],{"class":701,"line":726},[699,946,947],{},"public class ShapeFactory {\n",[699,949,950],{"class":701,"line":732},[699,951,952],{},"    public IShape Create(string type) => type switch {\n",[699,954,956],{"class":701,"line":955},7,[699,957,958],{},"        \"circle\" => new Circle(),\n",[699,960,962],{"class":701,"line":961},8,[699,963,964],{},"        \"square\" => new Square(),\n",[699,966,968],{"class":701,"line":967},9,[699,969,970],{},"        _ => throw new ArgumentException()\n",[699,972,974],{"class":701,"line":973},10,[699,975,976],{},"    };\n",[699,978,980],{"class":701,"line":979},11,[699,981,735],{},[442,983,985],{"id":984},"_14-abstract-factory-khác-factory-method","14. Abstract Factory khác Factory Method?",[474,987,988,998],{},[477,989,990,993,994,997],{},[432,991,992],{},"Factory Method",": tạo ",[432,995,996],{},"1 loại object"," qua interface.",[477,999,1000,993,1003,1006],{},[432,1001,1002],{},"Abstract Factory",[432,1004,1005],{},"một họ object liên quan"," (UI WinForms vs UI WPF — mỗi factory tạo Button + TextBox + Window cùng style).",[442,1008,1010],{"id":1009},"_15-builder-pattern-khi-nào-dùng","15. Builder pattern — khi nào dùng?",[447,1012,1013],{},"Khi tạo object phức tạp, nhiều bước, nhiều optional parameter. Fluent API gọn hơn constructor 10 tham số:",[689,1015,1017],{"className":691,"code":1016,"language":693,"meta":694,"style":694},"var query = new QueryBuilder()\n    .Where(\"city\", \"HCM\")\n    .OrderBy(\"age\")\n    .Limit(10)\n    .Build();\n",[696,1018,1019,1024,1029,1034,1039],{"__ignoreMap":694},[699,1020,1021],{"class":701,"line":702},[699,1022,1023],{},"var query = new QueryBuilder()\n",[699,1025,1026],{"class":701,"line":708},[699,1027,1028],{},"    .Where(\"city\", \"HCM\")\n",[699,1030,1031],{"class":701,"line":714},[699,1032,1033],{},"    .OrderBy(\"age\")\n",[699,1035,1036],{"class":701,"line":720},[699,1037,1038],{},"    .Limit(10)\n",[699,1040,1041],{"class":701,"line":726},[699,1042,1043],{},"    .Build();\n",[447,1045,1046,1047,1050,1051,1050,1054,1057],{},"Trong .NET: ",[696,1048,1049],{},"StringBuilder",", ",[696,1052,1053],{},"HttpRequestMessageBuilder",[696,1055,1056],{},"ConfigurationBuilder"," (ASP.NET Core).",[442,1059,1061],{"id":1060},"_16-prototype-pattern","16. Prototype pattern?",[447,1063,1064,1065,1067,1068,1071,1072,465],{},"Clone object hiện có thay vì ",[696,1066,752],{}," từ đầu — khi tạo object đắt (load từ DB, copy deep tree). C# có ",[696,1069,1070],{},"ICloneable"," nhưng API yếu (Object trả về) — thường viết deep clone thủ công hoặc dùng AutoMapper \u002F ",[696,1073,1074],{},"record with",[442,1076,1078,1079,1082],{"id":1077},"_17-c-record-có-liên-quan-prototype-không","17. C# ",[696,1080,1081],{},"record"," có liên quan Prototype không?",[447,1084,1085,1086,1088,1089,1092],{},"Có. ",[696,1087,1081],{}," có ",[696,1090,1091],{},"with"," expression — clone-and-modify rất gọn:",[689,1094,1096],{"className":691,"code":1095,"language":693,"meta":694,"style":694},"var user1 = new User(\"Alice\", 25);\nvar user2 = user1 with { Age = 26 };  \u002F\u002F clone, đổi Age\n",[696,1097,1098,1103],{"__ignoreMap":694},[699,1099,1100],{"class":701,"line":702},[699,1101,1102],{},"var user1 = new User(\"Alice\", 25);\n",[699,1104,1105],{"class":701,"line":708},[699,1106,1107],{},"var user2 = user1 with { Age = 26 };  \u002F\u002F clone, đổi Age\n",[447,1109,1110],{},"Đây là implementation của Prototype ở mức language.",[437,1112,1114],{"id":1113},"c-structural-patterns","C. Structural Patterns",[442,1116,1118],{"id":1117},"_18-adapter-pattern-ví-dụ-thực-tế","18. Adapter pattern — ví dụ thực tế?",[447,1120,1121,1122,1125,1126,1129],{},"Wrap interface không tương thích thành interface app cần. Ví dụ legacy ",[696,1123,1124],{},"OldPaymentGateway.DoPayment(double)"," → wrap thành ",[696,1127,1128],{},"IPaymentService.ChargeAsync(decimal)",". Code app chỉ thấy interface mới, không động legacy.",[442,1131,1133],{"id":1132},"_19-decorator-ví-dụ-trong-net","19. Decorator — ví dụ trong .NET?",[447,1135,1136],{},"Stream chain kinh điển:",[689,1138,1140],{"className":691,"code":1139,"language":693,"meta":694,"style":694},"using var fs = new FileStream(\"data.bin\", FileMode.Open);\nusing var bs = new BufferedStream(fs);\nusing var cs = new CryptoStream(bs, decryptor, CryptoStreamMode.Read);\nusing var gs = new GZipStream(cs, CompressionMode.Decompress);\n",[696,1141,1142,1147,1152,1157],{"__ignoreMap":694},[699,1143,1144],{"class":701,"line":702},[699,1145,1146],{},"using var fs = new FileStream(\"data.bin\", FileMode.Open);\n",[699,1148,1149],{"class":701,"line":708},[699,1150,1151],{},"using var bs = new BufferedStream(fs);\n",[699,1153,1154],{"class":701,"line":714},[699,1155,1156],{},"using var cs = new CryptoStream(bs, decryptor, CryptoStreamMode.Read);\n",[699,1158,1159],{"class":701,"line":720},[699,1160,1161],{},"using var gs = new GZipStream(cs, CompressionMode.Decompress);\n",[447,1163,1164],{},"Mỗi cấp wrap thêm chức năng (buffer, decrypt, decompress) mà không sửa class gốc.",[442,1166,1168],{"id":1167},"_20-aspnet-core-middleware-có-phải-decorator-không","20. ASP.NET Core middleware có phải Decorator không?",[447,1170,1171,1172,1175,1176,1179],{},"Có thể coi là dạng Decorator\u002FChain of Responsibility lai. Mỗi middleware ",[432,1173,1174],{},"wrap"," ",[696,1177,1178],{},"RequestDelegate"," next, thêm logic trước\u002Fsau khi gọi next:",[689,1181,1183],{"className":691,"code":1182,"language":693,"meta":694,"style":694},"app.Use(async (ctx, next) => {\n    \u002F* before *\u002F\n    await next();\n    \u002F* after *\u002F\n});\n",[696,1184,1185,1190,1195,1200,1205],{"__ignoreMap":694},[699,1186,1187],{"class":701,"line":702},[699,1188,1189],{},"app.Use(async (ctx, next) => {\n",[699,1191,1192],{"class":701,"line":708},[699,1193,1194],{},"    \u002F* before *\u002F\n",[699,1196,1197],{"class":701,"line":714},[699,1198,1199],{},"    await next();\n",[699,1201,1202],{"class":701,"line":720},[699,1203,1204],{},"    \u002F* after *\u002F\n",[699,1206,1207],{"class":701,"line":726},[699,1208,1209],{},"});\n",[442,1211,1213],{"id":1212},"_21-facade-pattern-ví-dụ","21. Facade pattern — ví dụ?",[447,1215,1216],{},"Cung cấp interface đơn giản cho subsystem phức tạp. Trong ASP.NET Core:",[689,1218,1220],{"className":691,"code":1219,"language":693,"meta":694,"style":694},"services.AddDbContext\u003CAppDbContext>(opt => opt.UseSqlServer(...));\napp.MapControllers();\n",[696,1221,1222,1227],{"__ignoreMap":694},[699,1223,1224],{"class":701,"line":702},[699,1225,1226],{},"services.AddDbContext\u003CAppDbContext>(opt => opt.UseSqlServer(...));\n",[699,1228,1229],{"class":701,"line":708},[699,1230,1231],{},"app.MapControllers();\n",[447,1233,1234],{},"Mỗi dòng wrap nhiều bước setup phức tạp.",[442,1236,1238],{"id":1237},"_22-proxy-pattern-dùng-làm-gì","22. Proxy pattern — dùng làm gì?",[447,1240,1241],{},"Object đứng giữa client và target — kiểm soát truy cập, lazy load, caching, logging.",[447,1243,1244],{},"Trong .NET:",[474,1246,1247,1253,1259],{},[477,1248,1249,1252],{},[432,1250,1251],{},"EF Core lazy loading proxy"," — proxy class generate runtime, intercept property access để load related data.",[477,1254,1255,1258],{},[432,1256,1257],{},"Castle DynamicProxy"," — interceptor cho AOP (Aspect-Oriented Programming).",[477,1260,1261,1264],{},[432,1262,1263],{},"WCF \u002F gRPC client"," — proxy gọi remote service.",[442,1266,1268],{"id":1267},"_23-composite-pattern","23. Composite pattern?",[447,1270,1271,1272,1275,1276,1279,1280,1283],{},"Cho phép xử lý object đơn lẻ và group object ",[432,1273,1274],{},"theo cùng cách",". Ví dụ tree file\u002Ffolder: cả File và Folder implement ",[696,1277,1278],{},"IFileSystemItem"," với method ",[696,1281,1282],{},"GetSize()",". Folder tính tổng size con đệ quy.",[442,1285,1287],{"id":1286},"_24-bridge-pattern","24. Bridge pattern?",[447,1289,1290,1291,1294,1295,1298,1299,1302],{},"Tách abstraction khỏi implementation để ",[432,1292,1293],{},"2 chiều thay đổi độc lập",". Ví dụ ",[696,1296,1297],{},"Shape"," × ",[696,1300,1301],{},"Renderer"," (OpenGL\u002FVulkan\u002FSoftware) — thêm Shape mới không động Renderer, thêm Renderer không động Shape.",[437,1304,1306],{"id":1305},"d-behavioral-patterns","D. Behavioral Patterns",[442,1308,1310],{"id":1309},"_25-strategy-pattern-ví-dụ-phổ-biến","25. Strategy pattern — ví dụ phổ biến?",[447,1312,1313,1314,1317],{},"Định nghĩa ",[432,1315,1316],{},"họ algorithm",", mỗi cái 1 class, swap được runtime:",[689,1319,1321],{"className":691,"code":1320,"language":693,"meta":694,"style":694},"public interface IDiscountStrategy {\n    decimal Apply(decimal total);\n}\npublic class NoDiscount : IDiscountStrategy { ... }\npublic class TenPercent : IDiscountStrategy { ... }\npublic class VipDiscount : IDiscountStrategy { ... }\n\npublic class Cart {\n    private readonly IDiscountStrategy _strategy;\n    public Cart(IDiscountStrategy strategy) => _strategy = strategy;\n    public decimal Checkout(decimal total) => _strategy.Apply(total);\n}\n",[696,1322,1323,1328,1333,1337,1342,1347,1352,1356,1361,1366,1371,1376],{"__ignoreMap":694},[699,1324,1325],{"class":701,"line":702},[699,1326,1327],{},"public interface IDiscountStrategy {\n",[699,1329,1330],{"class":701,"line":708},[699,1331,1332],{},"    decimal Apply(decimal total);\n",[699,1334,1335],{"class":701,"line":714},[699,1336,735],{},[699,1338,1339],{"class":701,"line":720},[699,1340,1341],{},"public class NoDiscount : IDiscountStrategy { ... }\n",[699,1343,1344],{"class":701,"line":726},[699,1345,1346],{},"public class TenPercent : IDiscountStrategy { ... }\n",[699,1348,1349],{"class":701,"line":732},[699,1350,1351],{},"public class VipDiscount : IDiscountStrategy { ... }\n",[699,1353,1354],{"class":701,"line":955},[699,1355,942],{"emptyLinePlaceholder":941},[699,1357,1358],{"class":701,"line":961},[699,1359,1360],{},"public class Cart {\n",[699,1362,1363],{"class":701,"line":967},[699,1364,1365],{},"    private readonly IDiscountStrategy _strategy;\n",[699,1367,1368],{"class":701,"line":973},[699,1369,1370],{},"    public Cart(IDiscountStrategy strategy) => _strategy = strategy;\n",[699,1372,1373],{"class":701,"line":979},[699,1374,1375],{},"    public decimal Checkout(decimal total) => _strategy.Apply(total);\n",[699,1377,1379],{"class":701,"line":1378},12,[699,1380,735],{},[447,1382,1383],{},"Strategy + DI trong ASP.NET Core = combo cực phổ biến.",[442,1385,1387],{"id":1386},"_26-strategy-vs-state-pattern","26. Strategy vs State pattern?",[474,1389,1390,1395],{},[477,1391,1392,1394],{},[432,1393,624],{},": client chọn algorithm; algorithm độc lập với nhau.",[477,1396,1397,1400],{},[432,1398,1399],{},"State",": object tự đổi state nội bộ; behavior thay đổi theo state hiện tại.",[447,1402,1403],{},"Cấu trúc class giống nhau, ý đồ khác.",[442,1405,1407],{"id":1406},"_27-observer-pattern-net-implement-ra-sao","27. Observer pattern — .NET implement ra sao?",[447,1409,1410,1411,1414],{},"Built-in qua ",[432,1412,1413],{},"event + delegate",":",[689,1416,1418],{"className":691,"code":1417,"language":693,"meta":694,"style":694},"public class StockTicker {\n    public event EventHandler\u003CPriceChangedEventArgs>? PriceChanged;\n    public void Update(decimal newPrice) {\n        PriceChanged?.Invoke(this, new PriceChangedEventArgs(newPrice));\n    }\n}\n\nticker.PriceChanged += (s, e) => Console.WriteLine(e.NewPrice);\n",[696,1419,1420,1425,1430,1435,1440,1445,1449,1453],{"__ignoreMap":694},[699,1421,1422],{"class":701,"line":702},[699,1423,1424],{},"public class StockTicker {\n",[699,1426,1427],{"class":701,"line":708},[699,1428,1429],{},"    public event EventHandler\u003CPriceChangedEventArgs>? PriceChanged;\n",[699,1431,1432],{"class":701,"line":714},[699,1433,1434],{},"    public void Update(decimal newPrice) {\n",[699,1436,1437],{"class":701,"line":720},[699,1438,1439],{},"        PriceChanged?.Invoke(this, new PriceChangedEventArgs(newPrice));\n",[699,1441,1442],{"class":701,"line":726},[699,1443,1444],{},"    }\n",[699,1446,1447],{"class":701,"line":732},[699,1448,735],{},[699,1450,1451],{"class":701,"line":955},[699,1452,942],{"emptyLinePlaceholder":941},[699,1454,1455],{"class":701,"line":961},[699,1456,1457],{},"ticker.PriceChanged += (s, e) => Console.WriteLine(e.NewPrice);\n",[447,1459,1460,1461,1464,1465,1468],{},"Hoặc ",[696,1462,1463],{},"IObservable\u003CT>"," \u002F ",[696,1466,1467],{},"IObserver\u003CT>"," (Reactive Extensions \u002F Rx.NET).",[442,1470,1472],{"id":1471},"_28-observer-vs-pubsub","28. Observer vs Pub\u002FSub?",[474,1474,1475,1481],{},[477,1476,1477,1480],{},[432,1478,1479],{},"Observer",": subject biết observer cụ thể (in-process, direct reference).",[477,1482,1483,1486,1487,1490],{},[432,1484,1485],{},"Pub\u002FSub",": publisher và subscriber ",[432,1488,1489],{},"không biết nhau",", qua broker (Redis Pub\u002FSub, RabbitMQ, Kafka).",[442,1492,1494],{"id":1493},"_29-command-pattern-ứng-dụng","29. Command pattern — ứng dụng?",[447,1496,1497],{},"Đóng gói request thành object → queue, log, undo được.",[447,1499,1500],{},"Ứng dụng:",[474,1502,1503,1506,1509],{},[477,1504,1505],{},"Undo\u002Fredo trong editor.",[477,1507,1508],{},"Job queue (Hangfire, MassTransit).",[477,1510,1511,1514],{},[432,1512,1513],{},"MediatR"," library — mỗi command\u002Fquery là 1 object, có handler riêng.",[442,1516,1518],{"id":1517},"_30-template-method-pattern-ví-dụ","30. Template Method pattern — ví dụ?",[447,1520,1521,1522,1525],{},"Cha định nghĩa ",[432,1523,1524],{},"skeleton thuật toán",", con override các bước:",[689,1527,1529],{"className":691,"code":1528,"language":693,"meta":694,"style":694},"public abstract class DataExporter {\n    public void Export(string file) {           \u002F\u002F template method — fixed\n        var data = LoadData();\n        var transformed = Transform(data);\n        var formatted = Format(transformed);\n        File.WriteAllText(file, formatted);\n    }\n    protected abstract List\u003CRecord> LoadData();\n    protected abstract List\u003CRecord> Transform(List\u003CRecord> d);\n    protected abstract string Format(List\u003CRecord> d);\n}\n\npublic class CsvExporter : DataExporter { \u002F* implement 3 step *\u002F }\npublic class JsonExporter : DataExporter { \u002F* implement 3 step *\u002F }\n",[696,1530,1531,1536,1541,1546,1551,1556,1561,1565,1570,1575,1580,1584,1588,1594],{"__ignoreMap":694},[699,1532,1533],{"class":701,"line":702},[699,1534,1535],{},"public abstract class DataExporter {\n",[699,1537,1538],{"class":701,"line":708},[699,1539,1540],{},"    public void Export(string file) {           \u002F\u002F template method — fixed\n",[699,1542,1543],{"class":701,"line":714},[699,1544,1545],{},"        var data = LoadData();\n",[699,1547,1548],{"class":701,"line":720},[699,1549,1550],{},"        var transformed = Transform(data);\n",[699,1552,1553],{"class":701,"line":726},[699,1554,1555],{},"        var formatted = Format(transformed);\n",[699,1557,1558],{"class":701,"line":732},[699,1559,1560],{},"        File.WriteAllText(file, formatted);\n",[699,1562,1563],{"class":701,"line":955},[699,1564,1444],{},[699,1566,1567],{"class":701,"line":961},[699,1568,1569],{},"    protected abstract List\u003CRecord> LoadData();\n",[699,1571,1572],{"class":701,"line":967},[699,1573,1574],{},"    protected abstract List\u003CRecord> Transform(List\u003CRecord> d);\n",[699,1576,1577],{"class":701,"line":973},[699,1578,1579],{},"    protected abstract string Format(List\u003CRecord> d);\n",[699,1581,1582],{"class":701,"line":979},[699,1583,735],{},[699,1585,1586],{"class":701,"line":1378},[699,1587,942],{"emptyLinePlaceholder":941},[699,1589,1591],{"class":701,"line":1590},13,[699,1592,1593],{},"public class CsvExporter : DataExporter { \u002F* implement 3 step *\u002F }\n",[699,1595,1597],{"class":701,"line":1596},14,[699,1598,1599],{},"public class JsonExporter : DataExporter { \u002F* implement 3 step *\u002F }\n",[442,1601,1603],{"id":1602},"_31-chain-of-responsibility-ví-dụ-net","31. Chain of Responsibility — ví dụ .NET?",[447,1605,1606,1609],{},[432,1607,1608],{},"ASP.NET Core middleware pipeline"," chính là Chain of Responsibility. Mỗi middleware quyết handle hoặc pass tiếp:",[689,1611,1613],{"className":691,"code":1612,"language":693,"meta":694,"style":694},"app.UseAuthentication();\napp.UseAuthorization();\napp.UseRouting();\napp.UseEndpoints(...);\n",[696,1614,1615,1620,1625,1630],{"__ignoreMap":694},[699,1616,1617],{"class":701,"line":702},[699,1618,1619],{},"app.UseAuthentication();\n",[699,1621,1622],{"class":701,"line":708},[699,1623,1624],{},"app.UseAuthorization();\n",[699,1626,1627],{"class":701,"line":714},[699,1628,1629],{},"app.UseRouting();\n",[699,1631,1632],{"class":701,"line":720},[699,1633,1634],{},"app.UseEndpoints(...);\n",[447,1636,1637,1638,1641],{},"Mỗi cái có thể short-circuit (không gọi ",[696,1639,1640],{},"next()",").",[442,1643,1645],{"id":1644},"_32-iterator-pattern-c-implement-sao","32. Iterator pattern — C# implement sao?",[447,1647,1410,1648,1651,1652,1655,1656,1659,1660,1663,1664,1651,1667,1655,1670,1673],{},[696,1649,1650],{},"IEnumerable\u003CT>"," + ",[696,1653,1654],{},"IEnumerator\u003CT>",". ",[696,1657,1658],{},"foreach"," thực chất gọi ",[696,1661,1662],{},"GetEnumerator()"," rồi loop ",[696,1665,1666],{},"MoveNext()",[696,1668,1669],{},"Current",[696,1671,1672],{},"yield return"," là sugar để tạo iterator dễ:",[689,1675,1677],{"className":691,"code":1676,"language":693,"meta":694,"style":694},"public IEnumerable\u003Cint> EvenNumbers(int max) {\n    for (int i = 0; i \u003C= max; i += 2)\n        yield return i;\n}\n",[696,1678,1679,1684,1689,1694],{"__ignoreMap":694},[699,1680,1681],{"class":701,"line":702},[699,1682,1683],{},"public IEnumerable\u003Cint> EvenNumbers(int max) {\n",[699,1685,1686],{"class":701,"line":708},[699,1687,1688],{},"    for (int i = 0; i \u003C= max; i += 2)\n",[699,1690,1691],{"class":701,"line":714},[699,1692,1693],{},"        yield return i;\n",[699,1695,1696],{"class":701,"line":720},[699,1697,735],{},[442,1699,1701],{"id":1700},"_33-mediator-pattern-là-gì","33. Mediator pattern là gì?",[447,1703,1704,1705,1708],{},"Đóng gói cách object tương tác với nhau qua ",[432,1706,1707],{},"1 trung gian",". Object không reference nhau trực tiếp — chỉ biết mediator. Giảm coupling N×N thành N×1.",[442,1710,1712],{"id":1711},"_34-mediatr-là-gì-liên-hệ-mediator-pattern","34. MediatR là gì? Liên hệ Mediator pattern?",[447,1714,1715,1717],{},[432,1716,1513],{}," là thư viện .NET implement Mediator pattern + Command pattern + Notification pattern.",[447,1719,1720],{},"Trong ASP.NET Core:",[689,1722,1724],{"className":691,"code":1723,"language":693,"meta":694,"style":694},"\u002F\u002F Command\npublic record CreateOrderCommand(int UserId, decimal Total) : IRequest\u003Cint>;\n\n\u002F\u002F Handler\npublic class CreateOrderHandler : IRequestHandler\u003CCreateOrderCommand, int> {\n    public async Task\u003Cint> Handle(CreateOrderCommand cmd, CancellationToken ct) {\n        \u002F\u002F logic\n        return orderId;\n    }\n}\n\n\u002F\u002F Controller\n[HttpPost]\npublic async Task\u003CIActionResult> Create(CreateOrderDto dto) {\n    var id = await _mediator.Send(new CreateOrderCommand(dto.UserId, dto.Total));\n    return Ok(id);\n}\n",[696,1725,1726,1731,1736,1740,1745,1750,1755,1760,1765,1769,1773,1777,1782,1787,1792,1798,1804],{"__ignoreMap":694},[699,1727,1728],{"class":701,"line":702},[699,1729,1730],{},"\u002F\u002F Command\n",[699,1732,1733],{"class":701,"line":708},[699,1734,1735],{},"public record CreateOrderCommand(int UserId, decimal Total) : IRequest\u003Cint>;\n",[699,1737,1738],{"class":701,"line":714},[699,1739,942],{"emptyLinePlaceholder":941},[699,1741,1742],{"class":701,"line":720},[699,1743,1744],{},"\u002F\u002F Handler\n",[699,1746,1747],{"class":701,"line":726},[699,1748,1749],{},"public class CreateOrderHandler : IRequestHandler\u003CCreateOrderCommand, int> {\n",[699,1751,1752],{"class":701,"line":732},[699,1753,1754],{},"    public async Task\u003Cint> Handle(CreateOrderCommand cmd, CancellationToken ct) {\n",[699,1756,1757],{"class":701,"line":955},[699,1758,1759],{},"        \u002F\u002F logic\n",[699,1761,1762],{"class":701,"line":961},[699,1763,1764],{},"        return orderId;\n",[699,1766,1767],{"class":701,"line":967},[699,1768,1444],{},[699,1770,1771],{"class":701,"line":973},[699,1772,735],{},[699,1774,1775],{"class":701,"line":979},[699,1776,942],{"emptyLinePlaceholder":941},[699,1778,1779],{"class":701,"line":1378},[699,1780,1781],{},"\u002F\u002F Controller\n",[699,1783,1784],{"class":701,"line":1590},[699,1785,1786],{},"[HttpPost]\n",[699,1788,1789],{"class":701,"line":1596},[699,1790,1791],{},"public async Task\u003CIActionResult> Create(CreateOrderDto dto) {\n",[699,1793,1795],{"class":701,"line":1794},15,[699,1796,1797],{},"    var id = await _mediator.Send(new CreateOrderCommand(dto.UserId, dto.Total));\n",[699,1799,1801],{"class":701,"line":1800},16,[699,1802,1803],{},"    return Ok(id);\n",[699,1805,1807],{"class":701,"line":1806},17,[699,1808,735],{},[447,1810,1811],{},"Controller không biết handler — chỉ biết mediator. Loose coupling, dễ test.",[437,1813,1815],{"id":1814},"e-net-specific-patterns","E. .NET-Specific Patterns",[442,1817,1819],{"id":1818},"_35-repository-pattern-vì-sao-dùng","35. Repository pattern — vì sao dùng?",[447,1821,1822,1823,1826],{},"Tách data access khỏi business logic. Service không biết DB là SQL hay Mongo, chỉ thấy ",[696,1824,1825],{},"IUserRepository",". Lợi ích:",[474,1828,1829,1832,1835],{},[477,1830,1831],{},"Test dễ (mock interface).",[477,1833,1834],{},"Swap DB dễ.",[477,1836,1837],{},"Centralize query phức tạp tái sử dụng.",[442,1839,1841],{"id":1840},"_36-repository-với-ef-core-có-thừa-không","36. Repository với EF Core — có thừa không?",[427,1843,1846,1849,1854,1885,1890,1904],{"color":1844,"icon":1845},"warning","i-lucide-star",[447,1847,1848],{},"⭐ Câu PV tranh cãi — phải biết để trả lời cân bằng.",[447,1850,1851],{},[432,1852,1853],{},"Lập luận \"thừa\":",[474,1855,1856,1862,1868,1875],{},[477,1857,1858,1861],{},[696,1859,1860],{},"DbSet\u003CT>"," đã là Repository.",[477,1863,1864,1867],{},[696,1865,1866],{},"DbContext"," đã là Unit of Work (track change, SaveChanges atomic).",[477,1869,1870,1871,1874],{},"Nếu chỉ wrap ",[696,1872,1873],{},"_ctx.Users.Where(...)"," → noise.",[477,1876,1877,1880,1881,1884],{},[696,1878,1879],{},"IQueryable"," mất khi qua Repository abstraction (",[696,1882,1883],{},"Task\u003CList\u003CT>>",") → mất composability.",[447,1886,1887],{},[432,1888,1889],{},"Lập luận \"vẫn cần\":",[474,1891,1892,1898,1901],{},[477,1893,1894,1895,1641],{},"Centralize query phức tạp (",[696,1896,1897],{},"GetActiveUsersInCity",[477,1899,1900],{},"Hide EF Core khỏi business layer (test, swap ORM dễ hơn).",[477,1902,1903],{},"Áp Specification pattern bên trên.",[447,1905,1906,1909,1910,1912],{},[432,1907,1908],{},"Câu trả lời thực dụng:"," \"Phụ thuộc complexity. Project nhỏ-vừa dùng ",[696,1911,1866],{}," trực tiếp đủ. Project lớn có domain phức tạp + nhiều dev → Repository giúp giới hạn EF Core knowledge.\"",[442,1914,1916],{"id":1915},"_37-unit-of-work-định-nghĩa","37. Unit of Work — định nghĩa?",[447,1918,1919,1920,1923,1924,1927],{},"Nhóm nhiều thao tác DB thành ",[432,1921,1922],{},"1 transaction",". Track changes của entity, commit hết bằng 1 ",[696,1925,1926],{},"SaveChanges()",". Đảm bảo atomic — hoặc tất cả thành công, hoặc rollback.",[442,1929,1931],{"id":1930},"_38-ef-core-dbcontext-unit-of-work","38. EF Core DbContext = Unit of Work?",[447,1933,1934,1935,1414],{},"Đúng. ",[696,1936,1866],{},[474,1938,1939,1942],{},[477,1940,1941],{},"Track entity state (Added\u002FModified\u002FDeleted\u002FUnchanged).",[477,1943,1944,1946],{},[696,1945,1926],{}," = commit 1 transaction.",[447,1948,1949,1950,465],{},"Đó là vì sao nhiều người argue không cần wrap thêm ",[696,1951,1952],{},"IUnitOfWork",[442,1954,1956],{"id":1955},"_39-specification-pattern","39. Specification pattern?",[447,1958,1959],{},"Đóng gói query criteria thành object reusable + composable:",[689,1961,1963],{"className":691,"code":1962,"language":693,"meta":694,"style":694},"public interface ISpecification\u003CT> {\n    Expression\u003CFunc\u003CT, bool>> Criteria { get; }\n    List\u003CExpression\u003CFunc\u003CT, object>>> Includes { get; }\n}\n\npublic class ActiveUsersInCitySpec : ISpecification\u003CUser> {\n    public Expression\u003CFunc\u003CUser, bool>> Criteria { get; }\n    public ActiveUsersInCitySpec(string city) {\n        Criteria = u => u.IsActive && u.City == city;\n    }\n}\n\n\u002F\u002F Repository\npublic Task\u003CList\u003CT>> ListAsync\u003CT>(ISpecification\u003CT> spec) { ... }\n",[696,1964,1965,1970,1975,1980,1984,1988,1993,1998,2003,2008,2012,2016,2020,2025],{"__ignoreMap":694},[699,1966,1967],{"class":701,"line":702},[699,1968,1969],{},"public interface ISpecification\u003CT> {\n",[699,1971,1972],{"class":701,"line":708},[699,1973,1974],{},"    Expression\u003CFunc\u003CT, bool>> Criteria { get; }\n",[699,1976,1977],{"class":701,"line":714},[699,1978,1979],{},"    List\u003CExpression\u003CFunc\u003CT, object>>> Includes { get; }\n",[699,1981,1982],{"class":701,"line":720},[699,1983,735],{},[699,1985,1986],{"class":701,"line":726},[699,1987,942],{"emptyLinePlaceholder":941},[699,1989,1990],{"class":701,"line":732},[699,1991,1992],{},"public class ActiveUsersInCitySpec : ISpecification\u003CUser> {\n",[699,1994,1995],{"class":701,"line":955},[699,1996,1997],{},"    public Expression\u003CFunc\u003CUser, bool>> Criteria { get; }\n",[699,1999,2000],{"class":701,"line":961},[699,2001,2002],{},"    public ActiveUsersInCitySpec(string city) {\n",[699,2004,2005],{"class":701,"line":967},[699,2006,2007],{},"        Criteria = u => u.IsActive && u.City == city;\n",[699,2009,2010],{"class":701,"line":973},[699,2011,1444],{},[699,2013,2014],{"class":701,"line":979},[699,2015,735],{},[699,2017,2018],{"class":701,"line":1378},[699,2019,942],{"emptyLinePlaceholder":941},[699,2021,2022],{"class":701,"line":1590},[699,2023,2024],{},"\u002F\u002F Repository\n",[699,2026,2027],{"class":701,"line":1596},[699,2028,2029],{},"public Task\u003CList\u003CT>> ListAsync\u003CT>(ISpecification\u003CT> spec) { ... }\n",[447,2031,2032],{},"Composable — combine spec bằng And\u002FOr.",[442,2034,2036],{"id":2035},"_40-cqrs-là-gì-khi-nào-dùng","40. CQRS là gì? Khi nào dùng?",[447,2038,2039,2042,2043,2046,2047,2050],{},[432,2040,2041],{},"Command Query Responsibility Segregation"," — tách model ",[432,2044,2045],{},"write"," (command) khỏi ",[432,2048,2049],{},"read"," (query).",[474,2052,2053,2056],{},[477,2054,2055],{},"Command: thay đổi state, không return data (hoặc chỉ ID).",[477,2057,2058],{},"Query: đọc data, không thay đổi.",[447,2060,2061],{},[432,2062,2063],{},"Khi nào dùng:",[474,2065,2066,2069,2072],{},[477,2067,2068],{},"Read pattern khác hẳn write (analytics, dashboard).",[477,2070,2071],{},"Cần scale read và write độc lập (write DB master, read replica\u002Fcache).",[477,2073,2074],{},"Domain phức tạp với business logic write nhiều validation.",[447,2076,2077,2080],{},[432,2078,2079],{},"Khi nào KHÔNG:"," CRUD đơn giản. CQRS thêm complexity không đáng.",[442,2082,2084],{"id":2083},"_41-cqrs-mediatr-pattern-combo","41. CQRS + MediatR — pattern combo?",[447,2086,2087],{},"Cực phổ biến trong ASP.NET Core clean architecture:",[689,2089,2091],{"className":691,"code":2090,"language":693,"meta":694,"style":694},"\u002F\u002F Command (write)\npublic record CreateOrderCommand(...) : IRequest\u003Cint>;\npublic class CreateOrderHandler : IRequestHandler\u003CCreateOrderCommand, int> { ... }\n\n\u002F\u002F Query (read)\npublic record GetOrderByIdQuery(int Id) : IRequest\u003COrderDto>;\npublic class GetOrderByIdHandler : IRequestHandler\u003CGetOrderByIdQuery, OrderDto> { ... }\n",[696,2092,2093,2098,2103,2108,2112,2117,2122],{"__ignoreMap":694},[699,2094,2095],{"class":701,"line":702},[699,2096,2097],{},"\u002F\u002F Command (write)\n",[699,2099,2100],{"class":701,"line":708},[699,2101,2102],{},"public record CreateOrderCommand(...) : IRequest\u003Cint>;\n",[699,2104,2105],{"class":701,"line":714},[699,2106,2107],{},"public class CreateOrderHandler : IRequestHandler\u003CCreateOrderCommand, int> { ... }\n",[699,2109,2110],{"class":701,"line":720},[699,2111,942],{"emptyLinePlaceholder":941},[699,2113,2114],{"class":701,"line":726},[699,2115,2116],{},"\u002F\u002F Query (read)\n",[699,2118,2119],{"class":701,"line":732},[699,2120,2121],{},"public record GetOrderByIdQuery(int Id) : IRequest\u003COrderDto>;\n",[699,2123,2124],{"class":701,"line":955},[699,2125,2126],{},"public class GetOrderByIdHandler : IRequestHandler\u003CGetOrderByIdQuery, OrderDto> { ... }\n",[447,2128,2129,2130,2133],{},"Controller ",[696,2131,2132],{},"Send"," mediator, không trực tiếp gọi service. Mỗi action là 1 file → dễ navigate.",[442,2135,2137],{"id":2136},"_42-cqrs-có-bắt-buộc-2-db-không","42. CQRS có bắt buộc 2 DB không?",[447,2139,2140,2143],{},[432,2141,2142],{},"Không."," CQRS có nhiều cấp:",[474,2145,2146,2152,2158],{},[477,2147,2148,2151],{},[432,2149,2150],{},"Cấp 1",": cùng DB, tách 2 model (Command\u002FQuery handler). Phổ biến nhất.",[477,2153,2154,2157],{},[432,2155,2156],{},"Cấp 2",": cùng DB, view riêng cho query (materialized view).",[477,2159,2160,2163],{},[432,2161,2162],{},"Cấp 3",": 2 DB tách hẳn — write DB normalized, read DB denormalized. Cần Event Sourcing hoặc CDC sync.",[447,2165,2166],{},"Fresher hay nhầm CQRS = 2 DB. Sai.",[442,2168,2170],{"id":2169},"_43-dependency-injection-là-pattern-hay-framework-feature","43. Dependency Injection — là pattern hay framework feature?",[447,2172,2173,2176,2177,2180,2181,2184],{},[432,2174,2175],{},"Cả 2."," DI là ",[432,2178,2179],{},"pattern"," thực thi DIP. ASP.NET Core, NestJS, Spring biến nó thành ",[432,2182,2183],{},"framework feature"," qua DI container — bạn chỉ khai báo, container build dependency graph.",[442,2186,2188],{"id":2187},"_44-options-pattern-trong-aspnet-core","44. Options pattern trong ASP.NET Core?",[447,2190,2191,2192,2195],{},"Pattern để bind config từ ",[696,2193,2194],{},"appsettings.json"," thành strong-typed class:",[689,2197,2199],{"className":691,"code":2198,"language":693,"meta":694,"style":694},"\u002F\u002F config class\npublic class JwtSettings {\n    public string Issuer { get; set; } = \"\";\n    public string Key { get; set; } = \"\";\n    public int ExpiryMinutes { get; set; } = 60;\n}\n\n\u002F\u002F Đăng ký\nbuilder.Services.Configure\u003CJwtSettings>(\n    builder.Configuration.GetSection(\"Jwt\"));\n\n\u002F\u002F Inject\npublic class AuthService {\n    private readonly JwtSettings _settings;\n    public AuthService(IOptions\u003CJwtSettings> opt) => _settings = opt.Value;\n}\n",[696,2200,2201,2206,2211,2216,2221,2226,2230,2234,2239,2244,2249,2253,2258,2263,2268,2273],{"__ignoreMap":694},[699,2202,2203],{"class":701,"line":702},[699,2204,2205],{},"\u002F\u002F config class\n",[699,2207,2208],{"class":701,"line":708},[699,2209,2210],{},"public class JwtSettings {\n",[699,2212,2213],{"class":701,"line":714},[699,2214,2215],{},"    public string Issuer { get; set; } = \"\";\n",[699,2217,2218],{"class":701,"line":720},[699,2219,2220],{},"    public string Key { get; set; } = \"\";\n",[699,2222,2223],{"class":701,"line":726},[699,2224,2225],{},"    public int ExpiryMinutes { get; set; } = 60;\n",[699,2227,2228],{"class":701,"line":732},[699,2229,735],{},[699,2231,2232],{"class":701,"line":955},[699,2233,942],{"emptyLinePlaceholder":941},[699,2235,2236],{"class":701,"line":961},[699,2237,2238],{},"\u002F\u002F Đăng ký\n",[699,2240,2241],{"class":701,"line":967},[699,2242,2243],{},"builder.Services.Configure\u003CJwtSettings>(\n",[699,2245,2246],{"class":701,"line":973},[699,2247,2248],{},"    builder.Configuration.GetSection(\"Jwt\"));\n",[699,2250,2251],{"class":701,"line":979},[699,2252,942],{"emptyLinePlaceholder":941},[699,2254,2255],{"class":701,"line":1378},[699,2256,2257],{},"\u002F\u002F Inject\n",[699,2259,2260],{"class":701,"line":1590},[699,2261,2262],{},"public class AuthService {\n",[699,2264,2265],{"class":701,"line":1596},[699,2266,2267],{},"    private readonly JwtSettings _settings;\n",[699,2269,2270],{"class":701,"line":1794},[699,2271,2272],{},"    public AuthService(IOptions\u003CJwtSettings> opt) => _settings = opt.Value;\n",[699,2274,2275],{"class":701,"line":1800},[699,2276,735],{},[447,2278,2279],{},"3 flavor:",[474,2281,2282,2288,2294],{},[477,2283,2284,2287],{},[696,2285,2286],{},"IOptions\u003CT>",": load 1 lần, không refresh.",[477,2289,2290,2293],{},[696,2291,2292],{},"IOptionsSnapshot\u003CT>",": refresh mỗi request (Scoped).",[477,2295,2296,2299],{},[696,2297,2298],{},"IOptionsMonitor\u003CT>",": refresh real-time + event change.",[442,2301,2303],{"id":2302},"_45-result-pattern-vì-sao-trend-gần-đây","45. Result pattern — Vì sao trend gần đây?",[447,2305,2306,2307,2310],{},"Thay vì throw exception cho business error, return ",[696,2308,2309],{},"Result\u003CT>"," chứa success\u002Ffailure + value\u002Ferror:",[689,2312,2314],{"className":691,"code":2313,"language":693,"meta":694,"style":694},"public class Result\u003CT> {\n    public bool IsSuccess { get; }\n    public T? Value { get; }\n    public string? Error { get; }\n}\n\npublic Result\u003CUser> Register(string email, string pwd) {\n    if (await _db.Users.AnyAsync(u => u.Email == email))\n        return Result\u003CUser>.Fail(\"Email already exists\");\n    \u002F\u002F ...\n    return Result\u003CUser>.Ok(user);\n}\n",[696,2315,2316,2321,2326,2331,2336,2340,2344,2349,2354,2359,2364,2369],{"__ignoreMap":694},[699,2317,2318],{"class":701,"line":702},[699,2319,2320],{},"public class Result\u003CT> {\n",[699,2322,2323],{"class":701,"line":708},[699,2324,2325],{},"    public bool IsSuccess { get; }\n",[699,2327,2328],{"class":701,"line":714},[699,2329,2330],{},"    public T? Value { get; }\n",[699,2332,2333],{"class":701,"line":720},[699,2334,2335],{},"    public string? Error { get; }\n",[699,2337,2338],{"class":701,"line":726},[699,2339,735],{},[699,2341,2342],{"class":701,"line":732},[699,2343,942],{"emptyLinePlaceholder":941},[699,2345,2346],{"class":701,"line":955},[699,2347,2348],{},"public Result\u003CUser> Register(string email, string pwd) {\n",[699,2350,2351],{"class":701,"line":961},[699,2352,2353],{},"    if (await _db.Users.AnyAsync(u => u.Email == email))\n",[699,2355,2356],{"class":701,"line":967},[699,2357,2358],{},"        return Result\u003CUser>.Fail(\"Email already exists\");\n",[699,2360,2361],{"class":701,"line":973},[699,2362,2363],{},"    \u002F\u002F ...\n",[699,2365,2366],{"class":701,"line":979},[699,2367,2368],{},"    return Result\u003CUser>.Ok(user);\n",[699,2370,2371],{"class":701,"line":1378},[699,2372,735],{},[447,2374,2375,2376,1050,2379,1050,2382,465],{},"Lợi ích: exception đắt, signature rõ ràng hơn, FP-style. Lib: ",[696,2377,2378],{},"FluentResults",[696,2380,2381],{},"LanguageExt",[696,2383,2384],{},"ErrorOr",[442,2386,2388],{"id":2387},"_46-pipeline-pattern-behavior-trong-mediatr","46. Pipeline pattern (Behavior trong MediatR)?",[447,2390,2391],{},"Wrap mỗi request qua chuỗi behavior — logging, validation, transaction, caching:",[689,2393,2395],{"className":691,"code":2394,"language":693,"meta":694,"style":694},"public class LoggingBehavior\u003CTReq, TRes> : IPipelineBehavior\u003CTReq, TRes> {\n    public async Task\u003CTRes> Handle(TReq req, RequestHandlerDelegate\u003CTRes> next, CancellationToken ct) {\n        _logger.LogInformation(\"Handling {Name}\", typeof(TReq).Name);\n        var response = await next();\n        _logger.LogInformation(\"Handled {Name}\", typeof(TReq).Name);\n        return response;\n    }\n}\n",[696,2396,2397,2402,2407,2412,2417,2422,2427,2431],{"__ignoreMap":694},[699,2398,2399],{"class":701,"line":702},[699,2400,2401],{},"public class LoggingBehavior\u003CTReq, TRes> : IPipelineBehavior\u003CTReq, TRes> {\n",[699,2403,2404],{"class":701,"line":708},[699,2405,2406],{},"    public async Task\u003CTRes> Handle(TReq req, RequestHandlerDelegate\u003CTRes> next, CancellationToken ct) {\n",[699,2408,2409],{"class":701,"line":714},[699,2410,2411],{},"        _logger.LogInformation(\"Handling {Name}\", typeof(TReq).Name);\n",[699,2413,2414],{"class":701,"line":720},[699,2415,2416],{},"        var response = await next();\n",[699,2418,2419],{"class":701,"line":726},[699,2420,2421],{},"        _logger.LogInformation(\"Handled {Name}\", typeof(TReq).Name);\n",[699,2423,2424],{"class":701,"line":732},[699,2425,2426],{},"        return response;\n",[699,2428,2429],{"class":701,"line":955},[699,2430,1444],{},[699,2432,2433],{"class":701,"line":961},[699,2434,735],{},[447,2436,2437],{},"Đăng ký 1 lần, áp dụng mọi command\u002Fquery. Tương tự middleware nhưng cho app layer.",[442,2439,2441],{"id":2440},"_47-result-vs-exception-bao-giờ-dùng-cái-nào","47. Result vs Exception — bao giờ dùng cái nào?",[474,2443,2444,2450],{},[477,2445,2446,2449],{},[432,2447,2448],{},"Exception",": lỗi thật sự bất ngờ (DB connection lost, OutOfMemory). Trường hợp ngoại lệ.",[477,2451,2452,2455],{},[432,2453,2454],{},"Result",": business validation expected (email trùng, balance không đủ). Flow control bình thường.",[447,2457,2458],{},"Throw exception cho mọi business rule = chậm + signature mờ. Result cho luồng business, exception cho infra error.",[442,2460,2462],{"id":2461},"_48-anemic-domain-model-có-phải-anti-pattern","48. Anemic Domain Model có phải anti-pattern?",[447,2464,2465],{},"Tranh cãi.",[474,2467,2468,2471,2474],{},[477,2469,2470],{},"Martin Fowler gọi là anti-pattern: entity chỉ get\u002Fset, logic ở service → mất OOP encapsulation.",[477,2472,2473],{},"Phe DDD agree: Rich Domain Model tốt hơn — invariant trong entity.",[477,2475,2476],{},"Phe pragmatic không phản đối: với CRUD app, Anemic + service đơn giản hơn, không có gì sai.",[447,2478,2479],{},"→ Hiểu context. Domain phức tạp → Rich. CRUD đơn giản → Anemic OK.",[437,2481,2483],{"id":2482},"f-anti-patterns","F. Anti-patterns",[442,2485,2487],{"id":2486},"_49-god-class-god-object","49. God Class \u002F God Object?",[447,2489,2490],{},"Class 2000+ dòng làm mọi thứ. Vi phạm SRP. Fix: tách theo trách nhiệm (entity, service, repository, formatter...).",[442,2492,2494],{"id":2493},"_50-service-locator-vs-di","50. Service Locator vs DI?",[474,2496,2497,2507],{},[477,2498,2499,2502,2503,2506],{},[432,2500,2501],{},"Service Locator",": code tự ",[696,2504,2505],{},"Locator.Get\u003CIFoo>()"," — hide dependency, khó test.",[477,2508,2509,2512],{},[432,2510,2511],{},"DI",": inject qua constructor — dependency rõ ràng, là phần API.",[447,2514,2515,2516,2519],{},"DI tốt hơn nhiều. ASP.NET Core có ",[696,2517,2518],{},"IServiceProvider"," — đừng inject nó trừ trường hợp đặc biệt (factory).",[442,2521,2523],{"id":2522},"_51-singleton-lạm-dụng-vấn-đề-gì","51. Singleton lạm dụng — vấn đề gì?",[447,2525,2526],{},"Global state → khó test, hidden coupling, khó parallel. Thay bằng DI Singleton lifetime — vẫn 1 instance, nhưng test thay được.",[442,2528,2530],{"id":2529},"_52-premature-optimization","52. Premature optimization?",[447,2532,2533,2534,2538],{},"Optimize trước khi có evidence chậm. Quote Knuth: ",[2535,2536,2537],"em",{},"\"Premature optimization is the root of all evil\"",". Code clear trước, đo bottleneck, mới tối ưu chỗ đó.",[442,2540,2542],{"id":2541},"_53-reinventing-the-wheel","53. Reinventing the wheel?",[447,2544,2545],{},"Tự code feature framework đã có (cache, validation, retry). Tốn thời gian, bug-prone. ASP.NET Core \u002F NestJS có sẵn rất nhiều — dùng built-in.",[437,2547,2549],{"id":2548},"g-câu-scenario-thực-tế","G. Câu scenario thực tế",[442,2551,2553],{"id":2552},"_54-project-bạn-từng-làm-dùng-pattern-nào-nổi-bật","54. Project bạn từng làm dùng pattern nào nổi bật?",[447,2555,2556,2559],{},[432,2557,2558],{},"Câu open-ended cực hot."," Kể project thật:",[474,2561,2562,2569,2576],{},[477,2563,2564,2565,2568],{},"\"Em dùng ",[432,2566,2567],{},"Repository + Unit of Work"," trong project E-commerce dù EF Core đã là Repository, vì team có 4 dev cần restrict query reusable.\"",[477,2570,2571,2572,2575],{},"\"Em apply ",[432,2573,2574],{},"CQRS + MediatR"," trong project Order System — write có nhiều validation, read là dashboard cần JOIN nhiều. MediatR pipeline cho logging + validation chung.\"",[477,2577,2564,2578,2580,2581,2584],{},[432,2579,624],{}," cho payment gateway — 3 provider (Stripe, VnPay, MoMo) implement ",[696,2582,2583],{},"IPaymentGateway",", inject qua DI.\"",[447,2586,2587,2588,2591],{},"Tránh kể chung chung — phải có ",[432,2589,2590],{},"context cụ thể"," (project gì, vì sao chọn pattern đó, kết quả).",[442,2593,2595],{"id":2594},"_55-bạn-có-dùng-mediatr-không-vì-sao","55. Bạn có dùng MediatR không? Vì sao?",[447,2597,2598],{},"Hai phía:",[447,2600,2601],{},[432,2602,2603],{},"Pro:",[474,2605,2606,2609,2612,2615],{},[477,2607,2608],{},"Decouple controller khỏi service.",[477,2610,2611],{},"Cross-cutting concerns (logging, validation, transaction) qua pipeline behavior.",[477,2613,2614],{},"Dễ navigate — mỗi command\u002Fquery 1 file.",[477,2616,2617],{},"Test handler dễ — input + output rõ.",[447,2619,2620],{},[432,2621,2622],{},"Con:",[474,2624,2625,2628,2631],{},[477,2626,2627],{},"Thêm layer indirection — tracing khó hơn.",[477,2629,2630],{},"Boilerplate cho action đơn giản.",[477,2632,2633],{},"\"Magic\" — newcomer khó hiểu flow.",[447,2635,2636],{},"Recent: tác giả MediatR (Jimmy Bogard) đã monetize lib → community chia rẽ, nhiều người chuyển sang manual handler hoặc lib khác (Mediator.SourceGenerator). Biết tin này là điểm cộng.",[442,2638,2640],{"id":2639},"_56-khi-gặp-legacy-code-spaghetti-refactor-pattern-nào-trước","56. Khi gặp legacy code spaghetti — refactor pattern nào trước?",[447,2642,2643],{},"Bước thực tế:",[606,2645,2646,2652,2657,2663,2676],{},[477,2647,2648,2651],{},[432,2649,2650],{},"Extract Method"," — tách function nhỏ.",[477,2653,2654,2656],{},[432,2655,630],{}," — tách data access.",[477,2658,2659,2662],{},[432,2660,2661],{},"Service"," — tách business logic.",[477,2664,2665,2667,2668,2671,2672,2675],{},[432,2666,2511],{}," — thay ",[696,2669,2670],{},"new ServiceA()"," bằng ",[696,2673,2674],{},"IServiceA"," inject.",[477,2677,2678],{},"Sau đó mới đến pattern lớn (CQRS, Event Sourcing).",[447,2680,2681],{},"Đừng làm cách mạng — refactor từng bước, test mỗi bước.",[442,2683,2685],{"id":2684},"_57-pattern-bạn-từng-áp-sai-và-phải-gỡ","57. Pattern bạn từng áp sai và phải gỡ?",[447,2687,2688],{},"Câu trick — admit mistake là điểm cộng. Ví dụ thật:",[474,2690,2691,2697],{},[477,2692,2693,2694,2696],{},"\"Em áp Repository + UoW cho project nhỏ → 5 layer cho 1 endpoint CRUD. Sau gỡ về dùng ",[696,2695,1866],{}," trực tiếp, code gọn hơn 60%.\"",[477,2698,2699],{},"\"Em làm Singleton cho service có state, sau phát hiện thread-safety issue → đổi sang Scoped.\"",[442,2701,2703],{"id":2702},"_58-nhìn-code-có-strategy-hard-code-3-case-sao-biết-dùng-pattern","58. Nhìn code có Strategy hard-code 3 case — sao biết dùng pattern?",[689,2705,2707],{"className":691,"code":2706,"language":693,"meta":694,"style":694},"\u002F\u002F Mùi smell — if\u002Felse dài, sẽ grow\npublic decimal CalcShipping(Order o) {\n    if (o.ShipMethod == \"express\") return o.Weight * 50000;\n    if (o.ShipMethod == \"standard\") return o.Weight * 30000;\n    if (o.ShipMethod == \"economy\") return o.Weight * 15000;\n    throw new ArgumentException();\n}\n",[696,2708,2709,2714,2719,2724,2729,2734,2739],{"__ignoreMap":694},[699,2710,2711],{"class":701,"line":702},[699,2712,2713],{},"\u002F\u002F Mùi smell — if\u002Felse dài, sẽ grow\n",[699,2715,2716],{"class":701,"line":708},[699,2717,2718],{},"public decimal CalcShipping(Order o) {\n",[699,2720,2721],{"class":701,"line":714},[699,2722,2723],{},"    if (o.ShipMethod == \"express\") return o.Weight * 50000;\n",[699,2725,2726],{"class":701,"line":720},[699,2727,2728],{},"    if (o.ShipMethod == \"standard\") return o.Weight * 30000;\n",[699,2730,2731],{"class":701,"line":726},[699,2732,2733],{},"    if (o.ShipMethod == \"economy\") return o.Weight * 15000;\n",[699,2735,2736],{"class":701,"line":732},[699,2737,2738],{},"    throw new ArgumentException();\n",[699,2740,2741],{"class":701,"line":955},[699,2742,735],{},[447,2744,2745],{},"Khi:",[474,2747,2748,2751,2754],{},[477,2749,2750],{},"if\u002Felse 3+ branch trên cùng type.",[477,2752,2753],{},"Mỗi case có algorithm riêng độc lập.",[477,2755,2756],{},"Sẽ thêm case nữa.",[447,2758,2759,2760,465],{},"→ Apply Strategy. Mỗi case 1 class implement ",[696,2761,2762],{},"IShippingStrategy",[442,2764,2766],{"id":2765},"_59-pattern-nào-hay-bị-over-engineering","59. Pattern nào hay bị \"over-engineering\"?",[474,2768,2769,2782,2790,2796],{},[477,2770,2771,2774,2775,453,2778,2781],{},[432,2772,2773],{},"Factory"," cho mọi class — ",[696,2776,2777],{},"UserFactory.Create()",[696,2779,2780],{},"new User()"," thuần.",[477,2783,2784,2786,2787,2789],{},[432,2785,630],{}," wrap ",[696,2788,1860],{}," 1-1.",[477,2791,2792,2795],{},[432,2793,2794],{},"CQRS"," cho CRUD đơn giản.",[477,2797,2798,2801],{},[432,2799,2800],{},"Microservice"," + Event Sourcing cho startup MVP.",[447,2803,2804],{},"→ Bắt đầu đơn giản, refactor khi đau.",[442,2806,2808],{"id":2807},"_60-decorator-vs-adapter-vs-proxy-phân-biệt","60. Decorator vs Adapter vs Proxy — phân biệt?",[447,2810,2811],{},"Cấu trúc gần giống (cùng wrap object) nhưng ý đồ khác:",[516,2813,2814,2829],{},[519,2815,2816],{},[522,2817,2818,2820,2823,2826],{},[525,2819],{},[525,2821,2822],{},"Adapter",[525,2824,2825],{},"Decorator",[525,2827,2828],{},"Proxy",[535,2830,2831,2845,2858,2872],{},[522,2832,2833,2836,2839,2842],{},[540,2834,2835],{},"Mục đích",[540,2837,2838],{},"Đổi interface",[540,2840,2841],{},"Thêm behavior",[540,2843,2844],{},"Kiểm soát truy cập",[522,2846,2847,2850,2853,2856],{},[540,2848,2849],{},"Interface output",[540,2851,2852],{},"Khác input",[540,2854,2855],{},"Giống input",[540,2857,2855],{},[522,2859,2860,2863,2866,2869],{},[540,2861,2862],{},"Wrap nhiều cấp",[540,2864,2865],{},"Hiếm",[540,2867,2868],{},"Thường",[540,2870,2871],{},"1 cấp",[522,2873,2874,2877,2880,2883],{},[540,2875,2876],{},"Ví dụ",[540,2878,2879],{},"Legacy → New API",[540,2881,2882],{},"Stream chain",[540,2884,2885],{},"Lazy load, caching",[442,2887,2889],{"id":2888},"_61-solid-nguyên-lý-nào-liên-hệ-trực-tiếp-với-di","61. SOLID nguyên lý nào liên hệ trực tiếp với DI?",[447,2891,2892,2895],{},[432,2893,2894],{},"Dependency Inversion Principle (D)",". DI là kỹ thuật thực thi DIP — high-level module depend abstraction, low-level cũng depend abstraction, DI container wire chúng lại runtime.",[442,2897,2899],{"id":2898},"_62-ef-core-lazy-loading-proxy-thuộc-pattern-nào","62. EF Core lazy loading proxy thuộc pattern nào?",[447,2901,2902,2905,2906,1651,2909,2912],{},[432,2903,2904],{},"Proxy pattern",". EF Core generate class derived runtime, override navigation property để load related data khi truy cập. Bật bằng ",[696,2907,2908],{},"UseLazyLoadingProxies()",[696,2910,2911],{},"virtual"," keyword.",[442,2914,2916],{"id":2915},"_63-aspnet-core-có-những-pattern-nào-built-in","63. ASP.NET Core có những pattern nào built-in?",[474,2918,2919,2925,2931,2937,2943,2949],{},[477,2920,2921,2924],{},[432,2922,2923],{},"DI \u002F IoC",": built-in container.",[477,2926,2927,2930],{},[432,2928,2929],{},"Options",": bind config.",[477,2932,2933,2936],{},[432,2934,2935],{},"Middleware",": Chain of Responsibility.",[477,2938,2939,2942],{},[432,2940,2941],{},"Filter"," (action\u002Fexception filter): Decorator-like.",[477,2944,2945,2948],{},[432,2946,2947],{},"Mediator"," (qua MediatR — không built-in, nhưng cực phổ biến).",[477,2950,2951,2954,2955,2958],{},[432,2952,2953],{},"Background Service",": ",[696,2956,2957],{},"IHostedService"," — Template Method.",[447,2960,2961],{},"Hiểu được những điều này = đọc source code framework dễ hơn nhiều.",[427,2963,2965,2966,2969,2970,465],{"color":429,"icon":2964},"i-lucide-arrow-right","Quay lại ",[2967,2968,67],"a",{"href":74}," hoặc xem ",[2967,2971,119],{"href":120},[2973,2974],"hr",{},[437,2976,2978],{"id":2977},"tham-khảo","Tham khảo",[474,2980,2981,2989,2996,3003,3010,3017,3024,3031],{},[477,2982,2983],{},[2967,2984,2988],{"href":2985,"rel":2986},"https:\u002F\u002Fwww.scholarhat.com\u002Ftutorial\u002Fdesignpatterns\u002Fdotnet-design-patterns-interview-questions-and-answers",[2987],"nofollow","ScholarHat — .Net Design Patterns Interview Questions",[477,2990,2991],{},[2967,2992,2995],{"href":2993,"rel":2994},"https:\u002F\u002Fbool.dev\u002Fblog\u002Fdetail\u002Fpart5-design-patterns-csharp-interview-questions",[2987],"bool.dev — C# Design Patterns Interview 2026",[477,2997,2998],{},[2967,2999,3002],{"href":3000,"rel":3001},"https:\u002F\u002Fwww.interviewbit.com\u002Fdesign-patterns-interview-questions\u002F",[2987],"InterviewBit — Top Design Patterns Interview Questions",[477,3004,3005],{},[2967,3006,3009],{"href":3007,"rel":3008},"https:\u002F\u002Fcodewithmukesh.com\u002Fblog\u002Fcqrs-and-mediatr-in-aspnet-core\u002F",[2987],"codewithmukesh — CQRS with MediatR in ASP.NET Core",[477,3011,3012],{},[2967,3013,3016],{"href":3014,"rel":3015},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fdotnet\u002Farchitecture\u002Fmicroservices\u002Fmicroservice-ddd-cqrs-patterns\u002Fmicroservice-application-layer-implementation-web-api",[2987],"Microsoft Learn — Microservice CQRS DDD Patterns",[477,3018,3019],{},[2967,3020,3023],{"href":3021,"rel":3022},"https:\u002F\u002Fkungfutech.edu.vn\u002Fphong-van-pro\u002Ffull-stack-web-and-mobile\u002Fdesign-pattern",[2987],"Kungfutech VN — Design Pattern interview",[477,3025,3026],{},[2967,3027,3030],{"href":3028,"rel":3029},"https:\u002F\u002Fvntalking.com\u002F5-loai-design-pattern-ma-developer-can-phai-biet.html",[2987],"VNTalking — 5 Design Pattern dev cần biết",[477,3032,3033],{},[2967,3034,3037],{"href":3035,"rel":3036},"https:\u002F\u002Fgrowupwork.com\u002Fblog\u002Fky-nang-phong-van\u002Fcau-hoi-phong-van-net-developer-787",[2987],"GrowUpWork — Câu hỏi phỏng vấn .NET Developer",[3039,3040,3041],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":694,"searchDepth":708,"depth":708,"links":3043},[3044,3052,3067,3076,3088,3104,3111,3123],{"id":439,"depth":708,"text":440,"children":3045},[3046,3047,3048,3049,3050,3051],{"id":444,"depth":714,"text":445},{"id":468,"depth":714,"text":469},{"id":506,"depth":714,"text":507},{"id":579,"depth":714,"text":580},{"id":600,"depth":714,"text":601},{"id":646,"depth":714,"text":647},{"id":671,"depth":708,"text":672,"children":3053},[3054,3055,3056,3058,3059,3060,3061,3062,3063,3064,3065],{"id":675,"depth":714,"text":676},{"id":686,"depth":714,"text":687},{"id":756,"depth":714,"text":3057},"9. Vì sao Lazy tốt hơn lock thủ công?",{"id":777,"depth":714,"text":778},{"id":809,"depth":714,"text":810},{"id":830,"depth":714,"text":831},{"id":912,"depth":714,"text":913},{"id":984,"depth":714,"text":985},{"id":1009,"depth":714,"text":1010},{"id":1060,"depth":714,"text":1061},{"id":1077,"depth":714,"text":3066},"17. C# record có liên quan Prototype không?",{"id":1113,"depth":708,"text":1114,"children":3068},[3069,3070,3071,3072,3073,3074,3075],{"id":1117,"depth":714,"text":1118},{"id":1132,"depth":714,"text":1133},{"id":1167,"depth":714,"text":1168},{"id":1212,"depth":714,"text":1213},{"id":1237,"depth":714,"text":1238},{"id":1267,"depth":714,"text":1268},{"id":1286,"depth":714,"text":1287},{"id":1305,"depth":708,"text":1306,"children":3077},[3078,3079,3080,3081,3082,3083,3084,3085,3086,3087],{"id":1309,"depth":714,"text":1310},{"id":1386,"depth":714,"text":1387},{"id":1406,"depth":714,"text":1407},{"id":1471,"depth":714,"text":1472},{"id":1493,"depth":714,"text":1494},{"id":1517,"depth":714,"text":1518},{"id":1602,"depth":714,"text":1603},{"id":1644,"depth":714,"text":1645},{"id":1700,"depth":714,"text":1701},{"id":1711,"depth":714,"text":1712},{"id":1814,"depth":708,"text":1815,"children":3089},[3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103],{"id":1818,"depth":714,"text":1819},{"id":1840,"depth":714,"text":1841},{"id":1915,"depth":714,"text":1916},{"id":1930,"depth":714,"text":1931},{"id":1955,"depth":714,"text":1956},{"id":2035,"depth":714,"text":2036},{"id":2083,"depth":714,"text":2084},{"id":2136,"depth":714,"text":2137},{"id":2169,"depth":714,"text":2170},{"id":2187,"depth":714,"text":2188},{"id":2302,"depth":714,"text":2303},{"id":2387,"depth":714,"text":2388},{"id":2440,"depth":714,"text":2441},{"id":2461,"depth":714,"text":2462},{"id":2482,"depth":708,"text":2483,"children":3105},[3106,3107,3108,3109,3110],{"id":2486,"depth":714,"text":2487},{"id":2493,"depth":714,"text":2494},{"id":2522,"depth":714,"text":2523},{"id":2529,"depth":714,"text":2530},{"id":2541,"depth":714,"text":2542},{"id":2548,"depth":708,"text":2549,"children":3112},[3113,3114,3115,3116,3117,3118,3119,3120,3121,3122],{"id":2552,"depth":714,"text":2553},{"id":2594,"depth":714,"text":2595},{"id":2639,"depth":714,"text":2640},{"id":2684,"depth":714,"text":2685},{"id":2702,"depth":714,"text":2703},{"id":2765,"depth":714,"text":2766},{"id":2807,"depth":714,"text":2808},{"id":2888,"depth":714,"text":2889},{"id":2898,"depth":714,"text":2899},{"id":2915,"depth":714,"text":2916},{"id":2977,"depth":708,"text":2978},"55+ câu hỏi Design Pattern hay hỏi nhất trong phỏng vấn .NET — GoF, .NET-specific patterns (Repository, UoW, Options, MediatR, CQRS), anti-pattern.","md",null,{},{"title":103,"icon":106},{"title":422,"description":3124},"JVKbYil7UvBvGRshG7QyjUqoYGEuP9q8dhYBBgKBarw",[3132,3134],{"title":98,"path":99,"stem":100,"description":3133,"icon":101,"children":-1},"25+ câu hỏi HR\u002Fbehavioral hay gặp khi phỏng vấn fresher .NET — kèm gợi ý cách trả lời.",{"title":108,"path":109,"stem":110,"description":3135,"icon":91,"children":-1},"80+ câu hỏi ASP.NET MVC 5 tới ASP.NET Core 8\u002F9\u002F10, Minimal API, versioning, rate limiting, output caching. Phỏng vấn fresher tới senior.",1783490355584]