[{"data":1,"prerenderedAt":3976},["ShallowReactive",2],{"navigation_docs":3,"-phong-van-lo-trinh-ngay-1-csharp-co-ban":420,"-phong-van-lo-trinh-ngay-1-csharp-co-ban-surround":3971},[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":32,"body":422,"description":3964,"extension":3965,"links":3966,"meta":3967,"navigation":3968,"path":33,"seo":3969,"stem":34,"__hash__":3970},"docs\u002F1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban.md",{"type":423,"value":424,"toc":3895},"minimark",[425,430,439,487,528,531,535,540,548,559,576,586,590,605,610,677,682,716,729,827,831,842,847,899,904,924,965,969,1016,1023,1029,1032,1073,1131,1133,1137,1141,1173,1310,1314,1344,1347,1353,1357,1382,1384,1390,1393,1397,1410,1484,1497,1503,1510,1534,1541,1561,1586,1608,1628,1630,1634,1638,1652,1672,1674,1680,1684,1708,1713,1785,1789,1795,1851,1862,1870,1963,1965,1975,1979,1989,2014,2017,2023,2027,2051,2054,2065,2076,2080,2092,2120,2122,2128,2134,2147,2154,2212,2224,2261,2263,2275,2279,2341,2345,2403,2410,2426,2479,2522,2524,2534,2538,2635,2639,2696,2703,2744,2746,2750,2757,2800,2856,2860,2867,2880,2936,2940,3036,3083,3085,3089,3093,3199,3209,3245,3304,3312,3326,3380,3383,3412,3416,3451,3453,3457,3461,3467,3472,3483,3517,3523,3527,3532,3561,3566,3617,3623,3627,3670,3678,3712,3717,3721,3766,3772,3777,3779,3783,3873,3882,3884,3891],[426,427,429],"h2",{"id":428},"mục-tiêu-ngày-1","Mục tiêu ngày 1",[431,432,433,434,438],"p",{},"Sau ngày 1, bạn phải ",[435,436,437],"strong",{},"hiểu sâu"," (không chỉ đọc thuộc) các khái niệm sau, đến mức có thể vẽ hình giải thích cho người khác:",[440,441,442,449,456,459,466,480],"ul",{},[443,444,445,448],"li",{},[435,446,447],{},"Bộ nhớ trong .NET hoạt động ra sao"," — Stack vs Heap là gì.",[443,450,451,452,455],{},"Value type khác Reference type ở mức ",[435,453,454],{},"bộ nhớ thực",", không chỉ \"lưu giá trị vs lưu địa chỉ\".",[443,457,458],{},"Boxing\u002FUnboxing thực chất là gì, gây hại như thế nào.",[443,460,461,465],{},[462,463,464],"code",{},"string"," immutable nghĩa là gì ở mức bộ nhớ.",[443,467,468,469,472,473,472,476,479],{},"Khi nào dùng ",[462,470,471],{},"const",", ",[462,474,475],{},"readonly",[462,477,478],{},"static readonly",".",[443,481,482,483,486],{},"Tránh sai lầm ",[462,484,485],{},"throw ex"," — vì sao mất stack trace.",[488,489,492,498],"callout",{"color":490,"icon":491},"primary","i-lucide-info",[431,493,494,497],{},[435,495,496],{},"Quy ước level"," (áp dụng xuyên suốt tài liệu):",[440,499,500,507,514,521],{},[443,501,502,503,506],{},"🟢 ",[435,504,505],{},"Intern \u002F Fresher",": định nghĩa, ví dụ cơ bản.",[443,508,509,510,513],{},"🔵 ",[435,511,512],{},"Junior",": dùng được trong code thực, biết gotcha thường gặp.",[443,515,516,517,520],{},"🟡 ",[435,518,519],{},"Mid",": hiểu trade-off, internals đủ để debug.",[443,522,523,524,527],{},"🔴 ",[435,525,526],{},"Senior",": implementation chi tiết, performance, edge case sâu.",[529,530],"hr",{},[426,532,534],{"id":533},"_1-bộ-nhớ-trong-net-nền-tảng","1. Bộ nhớ trong .NET — nền tảng",[536,537,539],"h3",{"id":538},"_11-tại-sao-phải-hiểu-stack-và-heap","1.1. Tại sao phải hiểu Stack và Heap?",[488,541,502,544,547],{"color":542,"icon":543},"warning","i-lucide-star",[435,545,546],{},"Trước khi nói value\u002Freference type, bạn phải biết Stack và Heap là gì."," 90% fresher trả lời \"value type lưu trên stack\" mà không định nghĩa nổi stack là gì → interviewer biết bạn học vẹt.",[431,549,550,551,554,555,558],{},"Khi chương trình chạy, ",[435,552,553],{},"mỗi process"," được hệ điều hành cấp một vùng RAM. .NET chia vùng RAM này thành nhiều khu chức năng, trong đó ",[435,556,557],{},"2 khu quan trọng nhất"," là:",[440,560,561,567],{},[443,562,563,566],{},[435,564,565],{},"Stack"," — vùng nhớ dạng \"chồng đĩa\" (LIFO — last in, first out).",[443,568,569,572,573,479],{},[435,570,571],{},"Heap"," — vùng nhớ tự do, được quản lý bởi ",[435,574,575],{},"Garbage Collector (GC)",[577,578,583],"pre",{"className":579,"code":581,"language":582},[580],"language-text","┌─────────────────────────────────────┐\n│           PROCESS MEMORY            │\n├─────────────────────────────────────┤\n│  STACK (1MB mặc định \u002F thread)      │  ← grows downward\n│  ┌─────────────────────┐            │\n│  │ Frame of Main()     │            │\n│  ├─────────────────────┤            │\n│  │ Frame of CalcSum()  │            │\n│  ├─────────────────────┤            │\n│  │ Frame of GetUser()  │  ← active  │\n│  └─────────────────────┘            │\n│         ...                         │\n│                                     │\n│         (free space)                │\n│                                     │\n│                                     │\n│           HEAP                      │  ← grows upward\n│  ┌─────────────┐                    │\n│  │ User obj    │                    │\n│  └─────────────┘                    │\n│  ┌─────────────────────┐            │\n│  │ string \"hello\"      │            │\n│  └─────────────────────┘            │\n│  ┌──┐                               │\n│  │..│  Gen 0, Gen 1, Gen 2 (GC)     │\n│  └──┘                               │\n└─────────────────────────────────────┘\n","text",[462,584,581],{"__ignoreMap":585},"",[536,587,589],{"id":588},"_12-stack-vùng-nhớ-chồng-đĩa","1.2. Stack — vùng nhớ \"chồng đĩa\"",[488,591,592,593,596,597,600,601,604],{"color":490,"icon":491},"🟢 Hình dung Stack như ",[435,594,595],{},"chồng đĩa rửa chén",": đặt đĩa lên trên (",[435,598,599],{},"push","), lấy đĩa trên cùng xuống (",[435,602,603],{},"pop","). Bạn không lấy được đĩa giữa hay đáy chồng.",[431,606,607],{},[435,608,609],{},"Đặc điểm stack:",[611,612,613,626],"table",{},[614,615,616],"thead",{},[617,618,619,623],"tr",{},[620,621,622],"th",{},"Tính chất",[620,624,625],{},"Giải thích",[627,628,629,638,650,658,666],"tbody",{},[617,630,631,635],{},[632,633,634],"td",{},"Cấu trúc LIFO",[632,636,637],{},"Vào sau ra trước — như chồng đĩa",[617,639,640,643],{},[632,641,642],{},"Mỗi thread có 1 stack riêng",[632,644,645,646,649],{},"Stack default ",[435,647,648],{},"1 MB \u002F thread"," trên Windows, 8 MB trên Linux",[617,651,652,655],{},[632,653,654],{},"Cấp phát \u002F giải phóng cực nhanh",[632,656,657],{},"Chỉ là tăng\u002Fgiảm 1 con trỏ",[617,659,660,663],{},[632,661,662],{},"Không cần GC",[632,664,665],{},"Hết scope thì biến mất tự động",[617,667,668,671],{},[632,669,670],{},"Bị giới hạn kích thước",[632,672,673,674],{},"Đệ quy quá sâu → ",[435,675,676],{},"StackOverflowException",[431,678,679],{},[435,680,681],{},"Cái gì được lưu trên stack:",[440,683,684,694,700,710],{},[443,685,686,689,690,693],{},[435,687,688],{},"Local variable"," kiểu value type của method (",[462,691,692],{},"int x = 5;"," bên trong method).",[443,695,696,699],{},[435,697,698],{},"Method parameter"," kiểu value type.",[443,701,702,705,706,709],{},[435,703,704],{},"Reference"," (con trỏ) tới object trên heap. ⚠ Bản thân reference là 8 bytes (64-bit), nằm trên stack; ",[435,707,708],{},"object thực"," mới ở heap.",[443,711,712,715],{},[435,713,714],{},"Return address"," — địa chỉ instruction tiếp theo khi method return.",[431,717,718,719,721,722,725,726,728],{},"Mỗi lần gọi method, .NET ",[435,720,599],{}," một ",[435,723,724],{},"stack frame"," (khung) chứa các thông tin trên. Khi method return, frame bị ",[435,727,603],{}," — toàn bộ biến local biến mất.",[488,730,732,737,818,821],{"color":731,"icon":147},"info",[431,733,509,734],{},[435,735,736],{},"Ví dụ trực quan:",[577,738,742],{"className":739,"code":740,"language":741,"meta":585,"style":585},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","void Foo() {\n    int a = 10;          \u002F\u002F a lên stack\n    int b = 20;          \u002F\u002F b lên stack\n    Bar();               \u002F\u002F gọi Bar — push frame mới\n    \u002F\u002F sau Bar return, frame của Bar pop, a và b vẫn còn\n}\n\nvoid Bar() {\n    int c = 30;          \u002F\u002F c lên stack (frame của Bar)\n    int d = 40;          \u002F\u002F d lên stack\n    \u002F\u002F Bar return → c, d pop tự động, không cần GC\n}\n","csharp",[462,743,744,752,758,764,770,776,782,789,795,801,807,813],{"__ignoreMap":585},[745,746,749],"span",{"class":747,"line":748},"line",1,[745,750,751],{},"void Foo() {\n",[745,753,755],{"class":747,"line":754},2,[745,756,757],{},"    int a = 10;          \u002F\u002F a lên stack\n",[745,759,761],{"class":747,"line":760},3,[745,762,763],{},"    int b = 20;          \u002F\u002F b lên stack\n",[745,765,767],{"class":747,"line":766},4,[745,768,769],{},"    Bar();               \u002F\u002F gọi Bar — push frame mới\n",[745,771,773],{"class":747,"line":772},5,[745,774,775],{},"    \u002F\u002F sau Bar return, frame của Bar pop, a và b vẫn còn\n",[745,777,779],{"class":747,"line":778},6,[745,780,781],{},"}\n",[745,783,785],{"class":747,"line":784},7,[745,786,788],{"emptyLinePlaceholder":787},true,"\n",[745,790,792],{"class":747,"line":791},8,[745,793,794],{},"void Bar() {\n",[745,796,798],{"class":747,"line":797},9,[745,799,800],{},"    int c = 30;          \u002F\u002F c lên stack (frame của Bar)\n",[745,802,804],{"class":747,"line":803},10,[745,805,806],{},"    int d = 40;          \u002F\u002F d lên stack\n",[745,808,810],{"class":747,"line":809},11,[745,811,812],{},"    \u002F\u002F Bar return → c, d pop tự động, không cần GC\n",[745,814,816],{"class":747,"line":815},12,[745,817,781],{},[431,819,820],{},"Khi Foo gọi Bar, stack có dạng:",[577,822,825],{"className":823,"code":824,"language":582},[580],"┌──────────────┐\n│ Frame Bar    │ ← top\n│  c = 30      │\n│  d = 40      │\n│  return addr │\n├──────────────┤\n│ Frame Foo    │\n│  a = 10      │\n│  b = 20      │\n└──────────────┘\n",[462,826,824],{"__ignoreMap":585},[536,828,830],{"id":829},"_13-heap-vùng-nhớ-tự-do-được-gc-quản-lý","1.3. Heap — vùng nhớ tự do được GC quản lý",[488,832,833,834,837,838,841],{"color":490,"icon":491},"🟢 Hình dung Heap như ",[435,835,836],{},"bàn làm việc lớn",": đặt giấy tờ ở chỗ trống bất kỳ. Khi không cần nữa, có ",[435,839,840],{},"người dọn dẹp"," (Garbage Collector) đi qua nhặt giấy không ai dùng nữa.",[431,843,844],{},[435,845,846],{},"Đặc điểm heap:",[611,848,849,857],{},[614,850,851],{},[617,852,853,855],{},[620,854,622],{},[620,856,625],{},[627,858,859,867,875,883,891],{},[617,860,861,864],{},[632,862,863],{},"Cấu trúc tự do",[632,865,866],{},"Object có thể nằm ở vị trí bất kỳ",[617,868,869,872],{},[632,870,871],{},"Cả app dùng chung 1 (managed) heap",[632,873,874],{},"Mọi thread share heap, cần sync khi cấp phát parallel",[617,876,877,880],{},[632,878,879],{},"Cấp phát chậm hơn stack",[632,881,882],{},"Phải tìm chỗ trống, update bookkeeping",[617,884,885,888],{},[632,886,887],{},"Cần Garbage Collection",[632,889,890],{},"Object không còn reference → bị GC thu hồi",[617,892,893,896],{},[632,894,895],{},"Size lớn hơn nhiều",[632,897,898],{},"Có thể vài GB tuỳ RAM",[431,900,901],{},[435,902,903],{},"Cái gì được lưu trên heap:",[440,905,906,912,918],{},[443,907,908,911],{},[435,909,910],{},"Object kiểu reference type"," (class, array, string, delegate…).",[443,913,914,917],{},[435,915,916],{},"Boxed value type"," (sẽ giải thích).",[443,919,920,923],{},[435,921,922],{},"Field của object"," (tất cả field instance đều nằm cùng object trên heap, kể cả field kiểu value type).",[488,925,926,932,962],{"color":542,"icon":268},[431,927,516,928,931],{},[435,929,930],{},"Heap được chia thành \"generations\""," để GC tối ưu:",[440,933,934,944,950,956],{},[443,935,936,939,940,943],{},[435,937,938],{},"Gen 0",": object mới sinh — GC quét ",[435,941,942],{},"rất thường xuyên"," (mỗi vài ms).",[443,945,946,949],{},[435,947,948],{},"Gen 1",": object sống sót Gen 0 — quét ít hơn.",[443,951,952,955],{},[435,953,954],{},"Gen 2",": object sống sót Gen 1 — quét hiếm.",[443,957,958,961],{},[435,959,960],{},"Large Object Heap (LOH)",": object > 85 KB — quét cùng Gen 2.",[431,963,964],{},"Giả định: object sống lâu thì sẽ sống tiếp. Tối ưu hoá cho web app (request-scoped object chết nhanh ở Gen 0).",[536,966,968],{"id":967},"_14-vẽ-memory-cho-ví-dụ-thực","1.4. Vẽ memory cho ví dụ thực",[577,970,972],{"className":739,"code":971,"language":741,"meta":585,"style":585},"class User {\n    public int Id;\n    public string Name;\n}\n\nvoid Run() {\n    int x = 5;\n    User u = new User { Id = 1, Name = \"Alice\" };\n}\n",[462,973,974,979,984,989,993,997,1002,1007,1012],{"__ignoreMap":585},[745,975,976],{"class":747,"line":748},[745,977,978],{},"class User {\n",[745,980,981],{"class":747,"line":754},[745,982,983],{},"    public int Id;\n",[745,985,986],{"class":747,"line":760},[745,987,988],{},"    public string Name;\n",[745,990,991],{"class":747,"line":766},[745,992,781],{},[745,994,995],{"class":747,"line":772},[745,996,788],{"emptyLinePlaceholder":787},[745,998,999],{"class":747,"line":778},[745,1000,1001],{},"void Run() {\n",[745,1003,1004],{"class":747,"line":784},[745,1005,1006],{},"    int x = 5;\n",[745,1008,1009],{"class":747,"line":791},[745,1010,1011],{},"    User u = new User { Id = 1, Name = \"Alice\" };\n",[745,1013,1014],{"class":747,"line":797},[745,1015,781],{},[431,1017,1018,1019,1022],{},"Khi ",[462,1020,1021],{},"Run"," đang chạy, bộ nhớ trông như sau:",[577,1024,1027],{"className":1025,"code":1026,"language":582},[580],"STACK (frame của Run)             HEAP\n┌────────────────────┐           ┌─────────────────────────┐\n│ x = 5              │           │ User object             │\n│ u = 0x7f3a1c00 ────┼─────────► │   Id = 1                │\n│ (con trỏ heap)     │           │   Name = 0x7f3a2400 ────┼──┐\n└────────────────────┘           │   (con trỏ tới string)  │  │\n                                 └─────────────────────────┘  │\n                                 ┌─────────────────────────┐  │\n                                 │ string \"Alice\" ◄────────┼──┘\n                                 └─────────────────────────┘\n",[462,1028,1026],{"__ignoreMap":585},[431,1030,1031],{},"Quan sát:",[440,1033,1034,1044,1054,1064],{},[443,1035,1036,1039,1040,1043],{},[462,1037,1038],{},"x = 5"," (int, value type) → ",[435,1041,1042],{},"giá trị thực"," nằm trên stack.",[443,1045,1046,1049,1050,1053],{},[462,1047,1048],{},"u"," → ",[435,1051,1052],{},"con trỏ"," trên stack, trỏ tới object trên heap.",[443,1055,1056,1059,1060,1063],{},[462,1057,1058],{},"Id = 1"," → field này nằm ",[435,1061,1062],{},"bên trong"," User object (trên heap), không phải stack riêng.",[443,1065,1066,1069,1070,1072],{},[462,1067,1068],{},"Name = \"Alice\""," → field Name lưu ",[435,1071,1052],{}," trỏ tới chuỗi \"Alice\", chuỗi này nằm chỗ khác trên heap.",[488,1074,1075,1080,1099],{"color":542,"icon":543},[431,1076,516,1077],{},[435,1078,1079],{},"Hiểu lầm phổ biến — \"Value type luôn ở stack.\"",[431,1081,1082,1085,1086,1094,1095,1098],{},[435,1083,1084],{},"Sai."," Đúng hơn: ",[1087,1088,1089,1090,1093],"em",{},"\"Value type lưu ",[435,1091,1092],{},"giá trị trực tiếp"," chỗ nào nó được khai báo.\""," Nếu int là field của class → int đó nằm ",[435,1096,1097],{},"trong class trên heap",", không phải stack.",[577,1100,1102],{"className":739,"code":1101,"language":741,"meta":585,"style":585},"class Container { public int Value; }   \u002F\u002F Value nằm trên heap (cùng Container)\n\nvoid Foo() {\n    int x = 5;                          \u002F\u002F x trên stack\n    Container c = new Container();      \u002F\u002F c.Value trên heap\n}\n",[462,1103,1104,1109,1113,1117,1122,1127],{"__ignoreMap":585},[745,1105,1106],{"class":747,"line":748},[745,1107,1108],{},"class Container { public int Value; }   \u002F\u002F Value nằm trên heap (cùng Container)\n",[745,1110,1111],{"class":747,"line":754},[745,1112,788],{"emptyLinePlaceholder":787},[745,1114,1115],{"class":747,"line":760},[745,1116,751],{},[745,1118,1119],{"class":747,"line":766},[745,1120,1121],{},"    int x = 5;                          \u002F\u002F x trên stack\n",[745,1123,1124],{"class":747,"line":772},[745,1125,1126],{},"    Container c = new Container();      \u002F\u002F c.Value trên heap\n",[745,1128,1129],{"class":747,"line":778},[745,1130,781],{},[529,1132],{},[426,1134,1136],{"id":1135},"_2-value-type-vs-reference-type","2. Value Type vs Reference Type",[536,1138,1140],{"id":1139},"_21-định-nghĩa-kèm-ví-dụ","2.1. Định nghĩa kèm ví dụ",[488,1142,1143,1146],{"color":490,"icon":491},[431,1144,1145],{},"🟢",[440,1147,1148,1160],{},[443,1149,1150,1153,1154,1156,1157,479],{},[435,1151,1152],{},"Value type",": biến lưu ",[435,1155,1042],{},". Khi gán hoặc truyền, ",[435,1158,1159],{},"giá trị được copy",[443,1161,1162,1153,1165,1168,1169,1172],{},[435,1163,1164],{},"Reference type",[435,1166,1167],{},"địa chỉ"," của object trên heap. Khi gán hoặc truyền, ",[435,1170,1171],{},"địa chỉ được copy"," — 2 biến cùng trỏ tới 1 object.",[611,1174,1175,1186],{},[614,1176,1177],{},[617,1178,1179,1182,1184],{},[620,1180,1181],{},"Đặc điểm",[620,1183,1152],{},[620,1185,1164],{},[627,1187,1188,1232,1243,1253,1264,1279,1292],{},[617,1189,1190,1193,1216],{},[632,1191,1192],{},"Ví dụ",[632,1194,1195,472,1198,472,1201,472,1204,472,1207,472,1210,472,1213],{},[462,1196,1197],{},"int",[462,1199,1200],{},"double",[462,1202,1203],{},"bool",[462,1205,1206],{},"char",[462,1208,1209],{},"struct",[462,1211,1212],{},"enum",[462,1214,1215],{},"DateTime",[632,1217,1218,472,1221,472,1223,472,1226,472,1229],{},[462,1219,1220],{},"class",[462,1222,464],{},[462,1224,1225],{},"array",[462,1227,1228],{},"delegate",[462,1230,1231],{},"interface",[617,1233,1234,1237,1240],{},[632,1235,1236],{},"Lưu",[632,1238,1239],{},"Giá trị trực tiếp",[632,1241,1242],{},"Con trỏ → object trên heap",[617,1244,1245,1248,1251],{},[632,1246,1247],{},"Vị trí giá trị thực",[632,1249,1250],{},"Stack (local), inline trong object (field)",[632,1252,571],{},[617,1254,1255,1258,1261],{},[632,1256,1257],{},"Copy khi gán",[632,1259,1260],{},"Copy giá trị",[632,1262,1263],{},"Copy địa chỉ",[617,1265,1266,1273,1276],{},[632,1267,1268,1269,1272],{},"So sánh ",[462,1270,1271],{},"=="," mặc định",[632,1274,1275],{},"So sánh giá trị",[632,1277,1278],{},"So sánh địa chỉ (trừ string)",[617,1280,1281,1284,1287],{},[632,1282,1283],{},"Giá trị mặc định",[632,1285,1286],{},"0, false, '\\0'",[632,1288,1289],{},[462,1290,1291],{},"null",[617,1293,1294,1297,1307],{},[632,1295,1296],{},"Cho phép null",[632,1298,1299,1300,1303,1304],{},"Phải dùng ",[462,1301,1302],{},"int?"," (Nullable",[1197,1305,1306],{},")",[632,1308,1309],{},"Có sẵn (string?)",[536,1311,1313],{"id":1312},"_22-demo-bằng-code-copy-bằng-giá-trị","2.2. Demo bằng code — copy bằng giá trị",[577,1315,1317],{"className":739,"code":1316,"language":741,"meta":585,"style":585},"int a = 5;\nint b = a;       \u002F\u002F copy giá trị 5 vào b\nb = 10;          \u002F\u002F chỉ b đổi, a giữ nguyên\nConsole.WriteLine(a);    \u002F\u002F 5\nConsole.WriteLine(b);    \u002F\u002F 10\n",[462,1318,1319,1324,1329,1334,1339],{"__ignoreMap":585},[745,1320,1321],{"class":747,"line":748},[745,1322,1323],{},"int a = 5;\n",[745,1325,1326],{"class":747,"line":754},[745,1327,1328],{},"int b = a;       \u002F\u002F copy giá trị 5 vào b\n",[745,1330,1331],{"class":747,"line":760},[745,1332,1333],{},"b = 10;          \u002F\u002F chỉ b đổi, a giữ nguyên\n",[745,1335,1336],{"class":747,"line":766},[745,1337,1338],{},"Console.WriteLine(a);    \u002F\u002F 5\n",[745,1340,1341],{"class":747,"line":772},[745,1342,1343],{},"Console.WriteLine(b);    \u002F\u002F 10\n",[431,1345,1346],{},"Bộ nhớ:",[577,1348,1351],{"className":1349,"code":1350,"language":582},[580],"Trước b = 10:           Sau b = 10:\na = 5                   a = 5\nb = 5                   b = 10\n",[462,1352,1350],{"__ignoreMap":585},[536,1354,1356],{"id":1355},"_23-demo-bằng-code-copy-reference","2.3. Demo bằng code — copy reference",[577,1358,1360],{"className":739,"code":1359,"language":741,"meta":585,"style":585},"int[] arr1 = { 1, 2, 3 };\nint[] arr2 = arr1;       \u002F\u002F arr2 và arr1 trỏ CÙNG mảng\narr2[0] = 99;            \u002F\u002F sửa qua arr2\nConsole.WriteLine(arr1[0]);    \u002F\u002F 99 (cùng object!)\n",[462,1361,1362,1367,1372,1377],{"__ignoreMap":585},[745,1363,1364],{"class":747,"line":748},[745,1365,1366],{},"int[] arr1 = { 1, 2, 3 };\n",[745,1368,1369],{"class":747,"line":754},[745,1370,1371],{},"int[] arr2 = arr1;       \u002F\u002F arr2 và arr1 trỏ CÙNG mảng\n",[745,1373,1374],{"class":747,"line":760},[745,1375,1376],{},"arr2[0] = 99;            \u002F\u002F sửa qua arr2\n",[745,1378,1379],{"class":747,"line":766},[745,1380,1381],{},"Console.WriteLine(arr1[0]);    \u002F\u002F 99 (cùng object!)\n",[431,1383,1346],{},[577,1385,1388],{"className":1386,"code":1387,"language":582},[580],"STACK                    HEAP\narr1 ──┐                 ┌───────────────┐\n       ├──► [1, 2, 3] →  │ [99, 2, 3]    │\narr2 ──┘                 └───────────────┘\n",[462,1389,1387],{"__ignoreMap":585},[431,1391,1392],{},"Cả 2 biến cùng trỏ tới 1 array → sửa qua biến nào cũng thấy.",[536,1394,1396],{"id":1395},"_24-bẫy-truyền-tham-số","2.4. Bẫy: truyền tham số",[488,1398,1400,1405],{"color":542,"icon":1399},"i-lucide-alert-triangle",[431,1401,509,1402],{},[435,1403,1404],{},"Khi truyền value type vào method, một copy được tạo. Sửa parameter KHÔNG ảnh hưởng biến gốc.",[431,1406,1407],{},[435,1408,1409],{},"Khi truyền reference type, copy là copy của con trỏ — vẫn trỏ cùng object. Sửa field của object SẼ thấy bên ngoài. Nhưng gán parameter sang object khác thì không thấy.",[577,1411,1413],{"className":739,"code":1412,"language":741,"meta":585,"style":585},"void ModifyInt(int x) { x = 100; }\nvoid ModifyArr(int[] a) { a[0] = 100; }\nvoid ReplaceArr(int[] a) { a = new int[] { 99 }; }   \u002F\u002F gán parameter\n\nint n = 5;\nModifyInt(n);\nConsole.WriteLine(n);          \u002F\u002F 5 — không đổi (value type copy)\n\nint[] arr = { 1, 2, 3 };\nModifyArr(arr);\nConsole.WriteLine(arr[0]);     \u002F\u002F 100 — thay đổi (sửa qua reference cùng object)\n\nReplaceArr(arr);\nConsole.WriteLine(arr[0]);     \u002F\u002F 100 — không phải 99! ReplaceArr chỉ đổi con trỏ local\n",[462,1414,1415,1420,1425,1430,1434,1439,1444,1449,1453,1458,1463,1468,1472,1478],{"__ignoreMap":585},[745,1416,1417],{"class":747,"line":748},[745,1418,1419],{},"void ModifyInt(int x) { x = 100; }\n",[745,1421,1422],{"class":747,"line":754},[745,1423,1424],{},"void ModifyArr(int[] a) { a[0] = 100; }\n",[745,1426,1427],{"class":747,"line":760},[745,1428,1429],{},"void ReplaceArr(int[] a) { a = new int[] { 99 }; }   \u002F\u002F gán parameter\n",[745,1431,1432],{"class":747,"line":766},[745,1433,788],{"emptyLinePlaceholder":787},[745,1435,1436],{"class":747,"line":772},[745,1437,1438],{},"int n = 5;\n",[745,1440,1441],{"class":747,"line":778},[745,1442,1443],{},"ModifyInt(n);\n",[745,1445,1446],{"class":747,"line":784},[745,1447,1448],{},"Console.WriteLine(n);          \u002F\u002F 5 — không đổi (value type copy)\n",[745,1450,1451],{"class":747,"line":791},[745,1452,788],{"emptyLinePlaceholder":787},[745,1454,1455],{"class":747,"line":797},[745,1456,1457],{},"int[] arr = { 1, 2, 3 };\n",[745,1459,1460],{"class":747,"line":803},[745,1461,1462],{},"ModifyArr(arr);\n",[745,1464,1465],{"class":747,"line":809},[745,1466,1467],{},"Console.WriteLine(arr[0]);     \u002F\u002F 100 — thay đổi (sửa qua reference cùng object)\n",[745,1469,1470],{"class":747,"line":815},[745,1471,788],{"emptyLinePlaceholder":787},[745,1473,1475],{"class":747,"line":1474},13,[745,1476,1477],{},"ReplaceArr(arr);\n",[745,1479,1481],{"class":747,"line":1480},14,[745,1482,1483],{},"Console.WriteLine(arr[0]);     \u002F\u002F 100 — không phải 99! ReplaceArr chỉ đổi con trỏ local\n",[431,1485,1486],{},[435,1487,1488,1489,1492,1493,1496],{},"Vì sao ",[462,1490,1491],{},"ReplaceArr"," không đổi ",[462,1494,1495],{},"arr"," bên ngoài?",[577,1498,1501],{"className":1499,"code":1500,"language":582},[580],"Trước ReplaceArr:\ncaller: arr ──► [100, 2, 3]\n              ▲\nReplaceArr:   a ┘    (cùng object)\n\nSau `a = new int[]{99}` bên trong ReplaceArr:\ncaller: arr ──► [100, 2, 3]\nReplaceArr:   a ──► [99]   (a giờ trỏ object mới, không động arr)\n",[462,1502,1500],{"__ignoreMap":585},[431,1504,1505,1506,1509],{},"Để đổi được, dùng ",[462,1507,1508],{},"ref"," keyword:",[577,1511,1513],{"className":739,"code":1512,"language":741,"meta":585,"style":585},"void ReplaceArrRef(ref int[] a) { a = new int[] { 99 }; }\nint[] arr = { 1, 2, 3 };\nReplaceArrRef(ref arr);\nConsole.WriteLine(arr[0]);     \u002F\u002F 99 — vì ref truyền địa chỉ của con trỏ\n",[462,1514,1515,1520,1524,1529],{"__ignoreMap":585},[745,1516,1517],{"class":747,"line":748},[745,1518,1519],{},"void ReplaceArrRef(ref int[] a) { a = new int[] { 99 }; }\n",[745,1521,1522],{"class":747,"line":754},[745,1523,1457],{},[745,1525,1526],{"class":747,"line":760},[745,1527,1528],{},"ReplaceArrRef(ref arr);\n",[745,1530,1531],{"class":747,"line":766},[745,1532,1533],{},"Console.WriteLine(arr[0]);     \u002F\u002F 99 — vì ref truyền địa chỉ của con trỏ\n",[536,1535,1537,1538,1540],{"id":1536},"_25-string-reference-nhưng-hành-xử-như-value","2.5. ",[462,1539,464],{}," — reference nhưng hành xử như value",[488,1542,516,1543,1545,1546,1549,1550,1553,1554,1560],{"color":542,"icon":268},[462,1544,464],{}," là ",[435,1547,1548],{},"reference type"," nhưng ",[435,1551,1552],{},"immutable"," + ",[435,1555,1556,1557,1559],{},"operator ",[462,1558,1271],{}," được overload"," → hành xử như value type. Đây là bẫy hay được hỏi.",[577,1562,1564],{"className":739,"code":1563,"language":741,"meta":585,"style":585},"string a = \"hello\";\nstring b = \"hello\";\nConsole.WriteLine(a == b);              \u002F\u002F True — overloaded == so sánh nội dung\nConsole.WriteLine(ReferenceEquals(a, b)); \u002F\u002F True — string interning!\n",[462,1565,1566,1571,1576,1581],{"__ignoreMap":585},[745,1567,1568],{"class":747,"line":748},[745,1569,1570],{},"string a = \"hello\";\n",[745,1572,1573],{"class":747,"line":754},[745,1574,1575],{},"string b = \"hello\";\n",[745,1577,1578],{"class":747,"line":760},[745,1579,1580],{},"Console.WriteLine(a == b);              \u002F\u002F True — overloaded == so sánh nội dung\n",[745,1582,1583],{"class":747,"line":766},[745,1584,1585],{},"Console.WriteLine(ReferenceEquals(a, b)); \u002F\u002F True — string interning!\n",[431,1587,1588,1591,1592,1595,1596,1599,1600,1603,1604,1607],{},[435,1589,1590],{},"String interning:"," compiler nhận thấy ",[462,1593,1594],{},"\"hello\""," xuất hiện 2 lần → chỉ tạo ",[435,1597,1598],{},"1 chuỗi duy nhất"," trên heap, cả ",[462,1601,1602],{},"a"," và ",[462,1605,1606],{},"b"," cùng trỏ tới. Tiết kiệm RAM cho literal hay lặp lại.",[577,1609,1611],{"className":739,"code":1610,"language":741,"meta":585,"style":585},"string c = new string(\"hello\".ToCharArray());     \u002F\u002F ép tạo object mới\nConsole.WriteLine(a == c);                        \u002F\u002F True — nội dung giống\nConsole.WriteLine(ReferenceEquals(a, c));         \u002F\u002F False — 2 object khác nhau\n",[462,1612,1613,1618,1623],{"__ignoreMap":585},[745,1614,1615],{"class":747,"line":748},[745,1616,1617],{},"string c = new string(\"hello\".ToCharArray());     \u002F\u002F ép tạo object mới\n",[745,1619,1620],{"class":747,"line":754},[745,1621,1622],{},"Console.WriteLine(a == c);                        \u002F\u002F True — nội dung giống\n",[745,1624,1625],{"class":747,"line":760},[745,1626,1627],{},"Console.WriteLine(ReferenceEquals(a, c));         \u002F\u002F False — 2 object khác nhau\n",[529,1629],{},[426,1631,1633],{"id":1632},"_3-boxing-unboxing-chi-phí-ngầm","3. Boxing & Unboxing — chi phí ngầm",[536,1635,1637],{"id":1636},"_31-boxing-là-gì","3.1. Boxing là gì?",[488,1639,1640,1646],{"color":490,"icon":491},[431,1641,502,1642,1645],{},[435,1643,1644],{},"Boxing"," = đóng gói value type vào object trên heap.",[431,1647,1648,1651],{},[435,1649,1650],{},"Unboxing"," = lấy giá trị nguyên thuỷ ra khỏi object, ép kiểu về value type ban đầu.",[577,1653,1655],{"className":739,"code":1654,"language":741,"meta":585,"style":585},"int x = 42;          \u002F\u002F x là value type, trên stack\nobject o = x;        \u002F\u002F BOXING: tạo object trên heap chứa giá trị 42, o trỏ tới object đó\nint y = (int)o;      \u002F\u002F UNBOXING: ép o về int, copy giá trị ra\n",[462,1656,1657,1662,1667],{"__ignoreMap":585},[745,1658,1659],{"class":747,"line":748},[745,1660,1661],{},"int x = 42;          \u002F\u002F x là value type, trên stack\n",[745,1663,1664],{"class":747,"line":754},[745,1665,1666],{},"object o = x;        \u002F\u002F BOXING: tạo object trên heap chứa giá trị 42, o trỏ tới object đó\n",[745,1668,1669],{"class":747,"line":760},[745,1670,1671],{},"int y = (int)o;      \u002F\u002F UNBOXING: ép o về int, copy giá trị ra\n",[431,1673,1346],{},[577,1675,1678],{"className":1676,"code":1677,"language":582},[580],"STACK              HEAP\nx = 42             ┌──────────────┐\no ───────────────► │ box: int 42  │\ny = 42             └──────────────┘\n",[462,1679,1677],{"__ignoreMap":585},[536,1681,1683],{"id":1682},"_32-vì-sao-boxing-tốn","3.2. Vì sao boxing tốn?",[488,1685,1688,1693,1705],{"color":1686,"icon":1687},"error","i-lucide-alert-octagon",[431,1689,516,1690],{},[435,1691,1692],{},"Mỗi lần boxing:",[1694,1695,1696,1699,1702],"ol",{},[443,1697,1698],{},"Cấp phát object mới trên heap (~16 bytes overhead cho int).",[443,1700,1701],{},"Copy giá trị từ stack vào object.",[443,1703,1704],{},"Sau khi không dùng, object thành rác → GC phải dọn.",[431,1706,1707],{},"Trong vòng lặp lớn → tốn RAM + áp lực GC → chậm cả app.",[431,1709,1710],{},[435,1711,1712],{},"Khi nào boxing xảy ra (ngầm)?",[577,1714,1716],{"className":739,"code":1715,"language":741,"meta":585,"style":585},"\u002F\u002F 1. Gán value type vào object hoặc interface\nobject o = 42;\nIComparable c = 42;\n\n\u002F\u002F 2. Truyền vào method nhận object\nConsole.WriteLine(\"x = \" + 42);     \u002F\u002F 42 boxed thành object để + với string\n\n\u002F\u002F 3. Lưu vào collection non-generic (legacy)\nArrayList list = new ArrayList();\nlist.Add(42);                        \u002F\u002F boxing!\nlist.Add(true);                      \u002F\u002F boxing!\n\n\u002F\u002F 4. Format string nhiều khi\nstring s = string.Format(\"x = {0}\", 42);   \u002F\u002F 42 boxed (less so với interpolation modern)\n",[462,1717,1718,1723,1728,1733,1737,1742,1747,1751,1756,1761,1766,1771,1775,1780],{"__ignoreMap":585},[745,1719,1720],{"class":747,"line":748},[745,1721,1722],{},"\u002F\u002F 1. Gán value type vào object hoặc interface\n",[745,1724,1725],{"class":747,"line":754},[745,1726,1727],{},"object o = 42;\n",[745,1729,1730],{"class":747,"line":760},[745,1731,1732],{},"IComparable c = 42;\n",[745,1734,1735],{"class":747,"line":766},[745,1736,788],{"emptyLinePlaceholder":787},[745,1738,1739],{"class":747,"line":772},[745,1740,1741],{},"\u002F\u002F 2. Truyền vào method nhận object\n",[745,1743,1744],{"class":747,"line":778},[745,1745,1746],{},"Console.WriteLine(\"x = \" + 42);     \u002F\u002F 42 boxed thành object để + với string\n",[745,1748,1749],{"class":747,"line":784},[745,1750,788],{"emptyLinePlaceholder":787},[745,1752,1753],{"class":747,"line":791},[745,1754,1755],{},"\u002F\u002F 3. Lưu vào collection non-generic (legacy)\n",[745,1757,1758],{"class":747,"line":797},[745,1759,1760],{},"ArrayList list = new ArrayList();\n",[745,1762,1763],{"class":747,"line":803},[745,1764,1765],{},"list.Add(42);                        \u002F\u002F boxing!\n",[745,1767,1768],{"class":747,"line":809},[745,1769,1770],{},"list.Add(true);                      \u002F\u002F boxing!\n",[745,1772,1773],{"class":747,"line":815},[745,1774,788],{"emptyLinePlaceholder":787},[745,1776,1777],{"class":747,"line":1474},[745,1778,1779],{},"\u002F\u002F 4. Format string nhiều khi\n",[745,1781,1782],{"class":747,"line":1480},[745,1783,1784],{},"string s = string.Format(\"x = {0}\", 42);   \u002F\u002F 42 boxed (less so với interpolation modern)\n",[536,1786,1788],{"id":1787},"_33-tránh-boxing-dùng-generic","3.3. Tránh boxing — dùng Generic",[488,1790,509,1792,1794],{"color":1791,"icon":268},"success",[435,1793,334],{}," ra đời (C# 2.0) chính là để tránh boxing với value type.",[577,1796,1798],{"className":739,"code":1797,"language":741,"meta":585,"style":585},"\u002F\u002F ❌ Boxing mỗi lần Add\nArrayList legacy = new ArrayList();\nfor (int i = 0; i \u003C 1_000_000; i++) {\n    legacy.Add(i);          \u002F\u002F 1 triệu lần boxing!\n}\n\n\u002F\u002F ✅ Không boxing\nList\u003Cint> modern = new List\u003Cint>();\nfor (int i = 0; i \u003C 1_000_000; i++) {\n    modern.Add(i);          \u002F\u002F không boxing — int lưu thẳng trong array\n}\n",[462,1799,1800,1805,1810,1815,1820,1824,1828,1833,1838,1842,1847],{"__ignoreMap":585},[745,1801,1802],{"class":747,"line":748},[745,1803,1804],{},"\u002F\u002F ❌ Boxing mỗi lần Add\n",[745,1806,1807],{"class":747,"line":754},[745,1808,1809],{},"ArrayList legacy = new ArrayList();\n",[745,1811,1812],{"class":747,"line":760},[745,1813,1814],{},"for (int i = 0; i \u003C 1_000_000; i++) {\n",[745,1816,1817],{"class":747,"line":766},[745,1818,1819],{},"    legacy.Add(i);          \u002F\u002F 1 triệu lần boxing!\n",[745,1821,1822],{"class":747,"line":772},[745,1823,781],{},[745,1825,1826],{"class":747,"line":778},[745,1827,788],{"emptyLinePlaceholder":787},[745,1829,1830],{"class":747,"line":784},[745,1831,1832],{},"\u002F\u002F ✅ Không boxing\n",[745,1834,1835],{"class":747,"line":791},[745,1836,1837],{},"List\u003Cint> modern = new List\u003Cint>();\n",[745,1839,1840],{"class":747,"line":797},[745,1841,1814],{},[745,1843,1844],{"class":747,"line":803},[745,1845,1846],{},"    modern.Add(i);          \u002F\u002F không boxing — int lưu thẳng trong array\n",[745,1848,1849],{"class":747,"line":809},[745,1850,781],{},[431,1852,1853,1854,1857,1858,1861],{},"Benchmark thực tế: ",[462,1855,1856],{},"List\u003Cint>"," nhanh hơn ",[462,1859,1860],{},"ArrayList"," ~5–10× cho thao tác mass với int.",[536,1863,1865,1866,1869],{"id":1864},"_34-câu-trick-int-x-null-có-boxing-không","3.4. Câu trick — ",[462,1867,1868],{},"int? x = null;"," có boxing không?",[488,1871,1872,1891,1930,1937,1960],{"color":542,"icon":268},[431,1873,523,1874,1883,1884,1886,1887,1890],{},[435,1875,1876,1879,1880,1882],{},[462,1877,1878],{},"Nullable\u003Cint>"," (",[462,1881,1302],{},") là struct"," — không boxing khi gán cho biến ",[462,1885,1302],{}," khác. NHƯNG khi gán sang ",[462,1888,1889],{},"object"," thì có hành vi đặc biệt:",[577,1892,1894],{"className":739,"code":1893,"language":741,"meta":585,"style":585},"int? a = null;\nobject o = a;             \u002F\u002F o = NULL chứ không phải boxed Nullable\u003Cint>\nConsole.WriteLine(o == null);   \u002F\u002F True\n\nint? b = 42;\nobject o2 = b;            \u002F\u002F o2 = boxed int 42 (NOT boxed Nullable\u003Cint>)\nConsole.WriteLine(o2.GetType());  \u002F\u002F System.Int32\n",[462,1895,1896,1901,1906,1911,1915,1920,1925],{"__ignoreMap":585},[745,1897,1898],{"class":747,"line":748},[745,1899,1900],{},"int? a = null;\n",[745,1902,1903],{"class":747,"line":754},[745,1904,1905],{},"object o = a;             \u002F\u002F o = NULL chứ không phải boxed Nullable\u003Cint>\n",[745,1907,1908],{"class":747,"line":760},[745,1909,1910],{},"Console.WriteLine(o == null);   \u002F\u002F True\n",[745,1912,1913],{"class":747,"line":766},[745,1914,788],{"emptyLinePlaceholder":787},[745,1916,1917],{"class":747,"line":772},[745,1918,1919],{},"int? b = 42;\n",[745,1921,1922],{"class":747,"line":778},[745,1923,1924],{},"object o2 = b;            \u002F\u002F o2 = boxed int 42 (NOT boxed Nullable\u003Cint>)\n",[745,1926,1927],{"class":747,"line":784},[745,1928,1929],{},"Console.WriteLine(o2.GetType());  \u002F\u002F System.Int32\n",[431,1931,1932,1933,1936],{},"CLR có cơ chế đặc biệt — boxing ",[462,1934,1935],{},"Nullable\u003CT>",":",[440,1938,1939,1948],{},[443,1940,1941,1942,1945,1946,479],{},"Nếu ",[462,1943,1944],{},"HasValue == false"," → box thành ",[462,1947,1291],{},[443,1949,1941,1950,1945,1953,1956,1957,1959],{},[462,1951,1952],{},"HasValue == true",[462,1954,1955],{},"T"," (không phải ",[462,1958,1935],{},").",[431,1961,1962],{},"Đây là edge case senior hay hỏi để check depth.",[529,1964],{},[426,1966,1968,1969,1971,1972],{"id":1967},"_4-string-immutable-stringbuilder","4. ",[462,1970,464],{}," immutable & ",[462,1973,1974],{},"StringBuilder",[536,1976,1978],{"id":1977},"_41-immutable-nghĩa-là-gì","4.1. Immutable nghĩa là gì?",[488,1980,502,1981,1984,1985,1988],{"color":490,"icon":491},[435,1982,1983],{},"Immutable"," = không thể sửa sau khi tạo. Mọi thao tác \"sửa\" thực ra tạo ",[435,1986,1987],{},"chuỗi mới",", chuỗi cũ thành rác chờ GC.",[577,1990,1992],{"className":739,"code":1991,"language":741,"meta":585,"style":585},"string s = \"Hello\";\ns = s + \" World\";        \u002F\u002F KHÔNG sửa \"Hello\" — tạo chuỗi mới \"Hello World\"\n                         \u002F\u002F s giờ trỏ tới chuỗi mới\n                         \u002F\u002F \"Hello\" cũ thành rác\n",[462,1993,1994,1999,2004,2009],{"__ignoreMap":585},[745,1995,1996],{"class":747,"line":748},[745,1997,1998],{},"string s = \"Hello\";\n",[745,2000,2001],{"class":747,"line":754},[745,2002,2003],{},"s = s + \" World\";        \u002F\u002F KHÔNG sửa \"Hello\" — tạo chuỗi mới \"Hello World\"\n",[745,2005,2006],{"class":747,"line":760},[745,2007,2008],{},"                         \u002F\u002F s giờ trỏ tới chuỗi mới\n",[745,2010,2011],{"class":747,"line":766},[745,2012,2013],{},"                         \u002F\u002F \"Hello\" cũ thành rác\n",[431,2015,2016],{},"Bộ nhớ qua từng bước:",[577,2018,2021],{"className":2019,"code":2020,"language":582},[580],"Bước 1 — string s = \"Hello\":\nSTACK            HEAP\ns ─────────────► \"Hello\"\n\nBước 2 — s = s + \" World\":\nSTACK            HEAP\ns ─────────────► \"Hello World\"   (mới)\n                 \"Hello\"           (rác)\n                 \" World\"          (literal, có thể intern)\n",[462,2022,2020],{"__ignoreMap":585},[536,2024,2026],{"id":2025},"_42-vì-sao-đắt-trong-loop","4.2. Vì sao đắt trong loop?",[577,2028,2030],{"className":739,"code":2029,"language":741,"meta":585,"style":585},"string result = \"\";\nfor (int i = 0; i \u003C 10_000; i++) {\n    result += i.ToString();\n}\n",[462,2031,2032,2037,2042,2047],{"__ignoreMap":585},[745,2033,2034],{"class":747,"line":748},[745,2035,2036],{},"string result = \"\";\n",[745,2038,2039],{"class":747,"line":754},[745,2040,2041],{},"for (int i = 0; i \u003C 10_000; i++) {\n",[745,2043,2044],{"class":747,"line":760},[745,2045,2046],{},"    result += i.ToString();\n",[745,2048,2049],{"class":747,"line":766},[745,2050,781],{},[431,2052,2053],{},"Mỗi vòng:",[1694,2055,2056,2059,2062],{},[443,2057,2058],{},"Tạo chuỗi mới có độ dài tăng dần.",[443,2060,2061],{},"Copy nội dung cũ + nội dung mới sang chuỗi mới.",[443,2063,2064],{},"Chuỗi cũ thành rác.",[431,2066,2067,2068,2071,2072,2075],{},"Tổng: ",[435,2069,2070],{},"~10000 lần cấp phát + copy",". Độ phức tạp ",[435,2073,2074],{},"O(n²)"," về thời gian, áp lực GC khủng khiếp.",[536,2077,2079],{"id":2078},"_43-stringbuilder-buffer-mutable","4.3. StringBuilder — buffer mutable",[488,2081,509,2082,2084,2085,2088,2089,479],{"color":1791,"icon":268},[462,2083,1974],{}," dùng ",[462,2086,2087],{},"char[]"," mutable bên trong. Append mở rộng array (gấp đôi khi đầy) — chi phí amortized ",[435,2090,2091],{},"O(1) \u002F append",[577,2093,2095],{"className":739,"code":2094,"language":741,"meta":585,"style":585},"var sb = new StringBuilder();\nfor (int i = 0; i \u003C 10_000; i++) {\n    sb.Append(i);\n}\nstring result = sb.ToString();        \u002F\u002F 1 lần tạo chuỗi cuối\n",[462,2096,2097,2102,2106,2111,2115],{"__ignoreMap":585},[745,2098,2099],{"class":747,"line":748},[745,2100,2101],{},"var sb = new StringBuilder();\n",[745,2103,2104],{"class":747,"line":754},[745,2105,2041],{},[745,2107,2108],{"class":747,"line":760},[745,2109,2110],{},"    sb.Append(i);\n",[745,2112,2113],{"class":747,"line":766},[745,2114,781],{},[745,2116,2117],{"class":747,"line":772},[745,2118,2119],{},"string result = sb.ToString();        \u002F\u002F 1 lần tạo chuỗi cuối\n",[431,2121,1346],{},[577,2123,2126],{"className":2124,"code":2125,"language":582},[580],"STACK            HEAP\nsb ────────────► StringBuilder { char[] buffer = [...mutable...] }\n                 Khi đầy → cấp array mới gấp đôi, copy sang\n",[462,2127,2125],{"__ignoreMap":585},[431,2129,2130,2133],{},[435,2131,2132],{},"Benchmark thực tế"," (concat 10000 int):",[440,2135,2136,2142],{},[443,2137,2138,2141],{},[462,2139,2140],{},"string +=",": ~150 ms.",[443,2143,2144,2146],{},[462,2145,1974],{},": ~1 ms.",[536,2148,2150,2151,2153],{"id":2149},"_44-khi-nào-dùng-string-thường","4.4. Khi nào dùng ",[462,2152,464],{}," thường?",[488,2155,2156,2166,2195,2198],{"color":490,"icon":491},[431,2157,2158,2159,2162,2163,2165],{},"🔵 StringBuilder có overhead khởi tạo. Concat ",[435,2160,2161],{},"≤ 5 chuỗi cố định"," thì ",[462,2164,464],{}," + operator thường nhanh hơn:",[577,2167,2169],{"className":739,"code":2168,"language":741,"meta":585,"style":585},"\u002F\u002F ✅ OK — compiler tối ưu thành 1 string.Concat call\nstring greeting = \"Hello, \" + name + \"! Today is \" + day;\n\n\u002F\u002F ✅ Tốt nhất — interpolation gọn + JIT có thể tối ưu\nstring greeting = $\"Hello, {name}! Today is {day}\";\n",[462,2170,2171,2176,2181,2185,2190],{"__ignoreMap":585},[745,2172,2173],{"class":747,"line":748},[745,2174,2175],{},"\u002F\u002F ✅ OK — compiler tối ưu thành 1 string.Concat call\n",[745,2177,2178],{"class":747,"line":754},[745,2179,2180],{},"string greeting = \"Hello, \" + name + \"! Today is \" + day;\n",[745,2182,2183],{"class":747,"line":760},[745,2184,788],{"emptyLinePlaceholder":787},[745,2186,2187],{"class":747,"line":766},[745,2188,2189],{},"\u002F\u002F ✅ Tốt nhất — interpolation gọn + JIT có thể tối ưu\n",[745,2191,2192],{"class":747,"line":772},[745,2193,2194],{},"string greeting = $\"Hello, {name}! Today is {day}\";\n",[431,2196,2197],{},"Quy tắc:",[440,2199,2200,2206],{},[443,2201,2202,2205],{},[435,2203,2204],{},"Loop hoặc số phần > 10"," → StringBuilder.",[443,2207,2208,2211],{},[435,2209,2210],{},"Cố định \u003C 10"," → string + hoặc interpolation.",[536,2213,2215,2216,2219,2220,2223],{"id":2214},"_45-stringbuildercapacity-vs-length-câu-hỏi-sâu","4.5. ",[462,2217,2218],{},"StringBuilder.Capacity"," vs ",[462,2221,2222],{},"Length"," — câu hỏi sâu",[488,2225,2226,2229,2249,2252],{"color":542,"icon":268},[431,2227,2228],{},"🟡",[440,2230,2231,2239],{},[443,2232,2233,2235,2236,479],{},[462,2234,2222],{},": số ký tự ",[435,2237,2238],{},"đang chứa",[443,2240,2241,2244,2245,2248],{},[462,2242,2243],{},"Capacity",": dung lượng ",[435,2246,2247],{},"đã cấp phát"," cho internal array.",[431,2250,2251],{},"Khi append vượt Capacity → cấp array mới ~2× Capacity cũ, copy sang. Khởi tạo với capacity ước tính sẵn giúp tránh re-allocation:",[577,2253,2255],{"className":739,"code":2254,"language":741,"meta":585,"style":585},"var sb = new StringBuilder(capacity: 1024);   \u002F\u002F pre-alloc 1024 ký tự\n",[462,2256,2257],{"__ignoreMap":585},[745,2258,2259],{"class":747,"line":748},[745,2260,2254],{},[529,2262],{},[426,2264,2266,2267,472,2269,472,2272],{"id":2265},"_5-so-sánh-equals-referenceequals","5. So sánh: ",[462,2268,1271],{},[462,2270,2271],{},"Equals",[462,2273,2274],{},"ReferenceEquals",[536,2276,2278],{"id":2277},"_51-ba-cách-so-sánh","5.1. Ba cách so sánh",[611,2280,2281,2294],{},[614,2282,2283],{},[617,2284,2285,2288,2291],{},[620,2286,2287],{},"Method",[620,2289,2290],{},"Mặc định",[620,2292,2293],{},"Override được?",[627,2295,2296,2309,2325],{},[617,2297,2298,2303,2306],{},[632,2299,2300,2302],{},[462,2301,1271],{}," (operator)",[632,2304,2305],{},"Reference (trừ string, được overload)",[632,2307,2308],{},"Có (overload operator)",[617,2310,2311,2316,2322],{},[632,2312,2313],{},[462,2314,2315],{},".Equals(obj)",[632,2317,2318,2319,1306],{},"Reference (",[462,2320,2321],{},"Object.Equals",[632,2323,2324],{},"Có (override)",[617,2326,2327,2332,2335],{},[632,2328,2329],{},[462,2330,2331],{},"ReferenceEquals(a, b)",[632,2333,2334],{},"Luôn so sánh reference",[632,2336,2337,2340],{},[435,2338,2339],{},"Không"," — sealed",[536,2342,2344],{"id":2343},"_52-demo","5.2. Demo",[577,2346,2348],{"className":739,"code":2347,"language":741,"meta":585,"style":585},"class Point { public int X, Y; }\n\nvar p1 = new Point { X = 1, Y = 2 };\nvar p2 = new Point { X = 1, Y = 2 };\nvar p3 = p1;\n\np1 == p2;            \u002F\u002F False — 2 object khác nhau, không override ==\np1 == p3;            \u002F\u002F True  — cùng object\np1.Equals(p2);       \u002F\u002F False — default Equals = reference\nReferenceEquals(p1, p2);   \u002F\u002F False\nReferenceEquals(p1, p3);   \u002F\u002F True\n",[462,2349,2350,2355,2359,2364,2369,2374,2378,2383,2388,2393,2398],{"__ignoreMap":585},[745,2351,2352],{"class":747,"line":748},[745,2353,2354],{},"class Point { public int X, Y; }\n",[745,2356,2357],{"class":747,"line":754},[745,2358,788],{"emptyLinePlaceholder":787},[745,2360,2361],{"class":747,"line":760},[745,2362,2363],{},"var p1 = new Point { X = 1, Y = 2 };\n",[745,2365,2366],{"class":747,"line":766},[745,2367,2368],{},"var p2 = new Point { X = 1, Y = 2 };\n",[745,2370,2371],{"class":747,"line":772},[745,2372,2373],{},"var p3 = p1;\n",[745,2375,2376],{"class":747,"line":778},[745,2377,788],{"emptyLinePlaceholder":787},[745,2379,2380],{"class":747,"line":784},[745,2381,2382],{},"p1 == p2;            \u002F\u002F False — 2 object khác nhau, không override ==\n",[745,2384,2385],{"class":747,"line":791},[745,2386,2387],{},"p1 == p3;            \u002F\u002F True  — cùng object\n",[745,2389,2390],{"class":747,"line":797},[745,2391,2392],{},"p1.Equals(p2);       \u002F\u002F False — default Equals = reference\n",[745,2394,2395],{"class":747,"line":803},[745,2396,2397],{},"ReferenceEquals(p1, p2);   \u002F\u002F False\n",[745,2399,2400],{"class":747,"line":809},[745,2401,2402],{},"ReferenceEquals(p1, p3);   \u002F\u002F True\n",[536,2404,2406,2407,2409],{"id":2405},"_53-override-equals-đúng-cách","5.3. Override ",[462,2408,2271],{}," đúng cách",[488,2411,2412,2423],{"color":1686,"icon":1687},[431,2413,516,2414],{},[435,2415,2416,2417,2419,2420,479],{},"Override ",[462,2418,2271],{}," thì BẮT BUỘC override ",[462,2421,2422],{},"GetHashCode",[431,2424,2425],{},"Vì sao? Vì Dictionary\u002FHashSet dùng hash để tìm bucket trước, sau đó dùng Equals để confirm. Nếu 2 object Equals nhưng hash khác → Dictionary mất hẳn.",[577,2427,2429],{"className":739,"code":2428,"language":741,"meta":585,"style":585},"class Point : IEquatable\u003CPoint> {\n    public int X, Y;\n    \n    public override bool Equals(object? obj) => obj is Point p && Equals(p);\n    public bool Equals(Point? other) => other != null && X == other.X && Y == other.Y;\n    public override int GetHashCode() => HashCode.Combine(X, Y);\n    \n    public static bool operator ==(Point a, Point b) => a.Equals(b);\n    public static bool operator !=(Point a, Point b) => !a.Equals(b);\n}\n",[462,2430,2431,2436,2441,2446,2451,2456,2461,2465,2470,2475],{"__ignoreMap":585},[745,2432,2433],{"class":747,"line":748},[745,2434,2435],{},"class Point : IEquatable\u003CPoint> {\n",[745,2437,2438],{"class":747,"line":754},[745,2439,2440],{},"    public int X, Y;\n",[745,2442,2443],{"class":747,"line":760},[745,2444,2445],{},"    \n",[745,2447,2448],{"class":747,"line":766},[745,2449,2450],{},"    public override bool Equals(object? obj) => obj is Point p && Equals(p);\n",[745,2452,2453],{"class":747,"line":772},[745,2454,2455],{},"    public bool Equals(Point? other) => other != null && X == other.X && Y == other.Y;\n",[745,2457,2458],{"class":747,"line":778},[745,2459,2460],{},"    public override int GetHashCode() => HashCode.Combine(X, Y);\n",[745,2462,2463],{"class":747,"line":784},[745,2464,2445],{},[745,2466,2467],{"class":747,"line":791},[745,2468,2469],{},"    public static bool operator ==(Point a, Point b) => a.Equals(b);\n",[745,2471,2472],{"class":747,"line":797},[745,2473,2474],{},"    public static bool operator !=(Point a, Point b) => !a.Equals(b);\n",[745,2476,2477],{"class":747,"line":803},[745,2478,781],{},[488,2480,2481,2490,2519],{"color":1791,"icon":268},[431,2482,509,2483,2489],{},[435,2484,2485,2486],{},"C# 9+ có ",[462,2487,2488],{},"record"," — tự sinh Equals, GetHashCode, ToString, deconstruct với value equality.",[577,2491,2493],{"className":739,"code":2492,"language":741,"meta":585,"style":585},"public record Point(int X, int Y);\n\nvar p1 = new Point(1, 2);\nvar p2 = new Point(1, 2);\np1 == p2;           \u002F\u002F True — record tự dùng value equality\n",[462,2494,2495,2500,2504,2509,2514],{"__ignoreMap":585},[745,2496,2497],{"class":747,"line":748},[745,2498,2499],{},"public record Point(int X, int Y);\n",[745,2501,2502],{"class":747,"line":754},[745,2503,788],{"emptyLinePlaceholder":787},[745,2505,2506],{"class":747,"line":760},[745,2507,2508],{},"var p1 = new Point(1, 2);\n",[745,2510,2511],{"class":747,"line":766},[745,2512,2513],{},"var p2 = new Point(1, 2);\n",[745,2515,2516],{"class":747,"line":772},[745,2517,2518],{},"p1 == p2;           \u002F\u002F True — record tự dùng value equality\n",[431,2520,2521],{},"Cho mọi DTO, data class — dùng record. Code ngắn hơn nhiều.",[529,2523],{},[426,2525,2527,2528,2219,2530,2219,2532],{"id":2526},"_6-const-vs-readonly-vs-static-readonly","6. ",[462,2529,471],{},[462,2531,475],{},[462,2533,478],{},[536,2535,2537],{"id":2536},"_61-bảng-so-sánh","6.1. Bảng so sánh",[611,2539,2540,2558],{},[614,2541,2542],{},[617,2543,2544,2546,2550,2554],{},[620,2545],{},[620,2547,2548],{},[462,2549,471],{},[620,2551,2552],{},[462,2553,475],{},[620,2555,2556],{},[462,2557,478],{},[627,2559,2560,2574,2596,2610,2623],{},[617,2561,2562,2565,2568,2571],{},[632,2563,2564],{},"Khi set giá trị",[632,2566,2567],{},"Compile-time",[632,2569,2570],{},"Constructor (mỗi instance)",[632,2572,2573],{},"Static constructor (1 lần)",[617,2575,2576,2579,2591,2594],{},[632,2577,2578],{},"Kiểu được phép",[632,2580,2581,2582,472,2584,472,2586,2588,2589],{},"Primitive (",[462,2583,1197],{},[462,2585,464],{},[462,2587,1203],{},"…) + ",[462,2590,1291],{},[632,2592,2593],{},"Mọi kiểu",[632,2595,2593],{},[617,2597,2598,2601,2604,2607],{},[632,2599,2600],{},"Mỗi instance khác nhau?",[632,2602,2603],{},"–",[632,2605,2606],{},"✅",[632,2608,2609],{},"❌ (1 cho cả class)",[617,2611,2612,2615,2618,2621],{},[632,2613,2614],{},"Compile vào nơi dùng?",[632,2616,2617],{},"✅ (inline)",[632,2619,2620],{},"❌",[632,2622,2620],{},[617,2624,2625,2628,2631,2633],{},[632,2626,2627],{},"Đổi cần build module gọi?",[632,2629,2630],{},"✅ Phải build lại",[632,2632,2620],{},[632,2634,2620],{},[536,2636,2638],{"id":2637},"_62-ví-dụ-minh-hoạ","6.2. Ví dụ minh hoạ",[577,2640,2642],{"className":739,"code":2641,"language":741,"meta":585,"style":585},"public class Config {\n    public const double Pi = 3.14159;                       \u002F\u002F compile inline\n    public readonly DateTime CreatedAt;                     \u002F\u002F per-instance\n    public static readonly string Version = LoadVersion();  \u002F\u002F 1 lần khi class load\n    \n    public Config() {\n        CreatedAt = DateTime.UtcNow;                        \u002F\u002F mỗi new Config(), CreatedAt khác\n    }\n    \n    private static string LoadVersion() => \"1.0.0\";\n}\n",[462,2643,2644,2649,2654,2659,2664,2668,2673,2678,2683,2687,2692],{"__ignoreMap":585},[745,2645,2646],{"class":747,"line":748},[745,2647,2648],{},"public class Config {\n",[745,2650,2651],{"class":747,"line":754},[745,2652,2653],{},"    public const double Pi = 3.14159;                       \u002F\u002F compile inline\n",[745,2655,2656],{"class":747,"line":760},[745,2657,2658],{},"    public readonly DateTime CreatedAt;                     \u002F\u002F per-instance\n",[745,2660,2661],{"class":747,"line":766},[745,2662,2663],{},"    public static readonly string Version = LoadVersion();  \u002F\u002F 1 lần khi class load\n",[745,2665,2666],{"class":747,"line":772},[745,2667,2445],{},[745,2669,2670],{"class":747,"line":778},[745,2671,2672],{},"    public Config() {\n",[745,2674,2675],{"class":747,"line":784},[745,2676,2677],{},"        CreatedAt = DateTime.UtcNow;                        \u002F\u002F mỗi new Config(), CreatedAt khác\n",[745,2679,2680],{"class":747,"line":791},[745,2681,2682],{},"    }\n",[745,2684,2685],{"class":747,"line":797},[745,2686,2445],{},[745,2688,2689],{"class":747,"line":803},[745,2690,2691],{},"    private static string LoadVersion() => \"1.0.0\";\n",[745,2693,2694],{"class":747,"line":809},[745,2695,781],{},[536,2697,2699,2700,2702],{"id":2698},"_63-bẫy-const-cross-assembly","6.3. Bẫy ",[462,2701,471],{}," cross-assembly",[488,2704,2705,2725,2736],{"color":542,"icon":1399},[431,2706,516,2707,2713,2714,2717,2718,1603,2721,2724],{},[435,2708,2709,2710,2712],{},"Vì ",[462,2711,471],{}," được inline vào nơi dùng"," — nếu ",[462,2715,2716],{},"Library.dll"," có ",[462,2719,2720],{},"const Pi = 3.14",[462,2722,2723],{},"App.dll"," reference nó, App build sẽ có giá trị 3.14 nhúng trực tiếp vào IL.",[431,2726,2727,2728,2731,2732,2735],{},"Nếu sau đó update Library thành ",[462,2729,2730],{},"Pi = 3.14159"," ",[435,2733,2734],{},"mà KHÔNG build lại App",", App vẫn dùng 3.14 cũ → bug khó debug.",[431,2737,2738,2739,2741,2742,479],{},"→ Quy tắc: với giá trị có thể đổi giữa các bản release của library, dùng ",[462,2740,478],{}," thay vì ",[462,2743,471],{},[529,2745],{},[426,2747,2749],{"id":2748},"_7-nullable-null-safety","7. Nullable & null-safety",[536,2751,2753,2754,2756],{"id":2752},"_71-int-thực-chất-là-gì","7.1. ",[462,2755,1302],{}," thực chất là gì?",[488,2758,2759,2773,2785],{"color":490,"icon":491},[431,2760,502,2761,1545,2763,2766,2767,2769,2770,2772],{},[462,2762,1302],{},[435,2764,2765],{},"syntactic sugar"," cho ",[462,2768,1878],{}," — một ",[435,2771,1209],{}," chứa:",[440,2774,2775,2780],{},[443,2776,2777],{},[462,2778,2779],{},"bool HasValue",[443,2781,2782],{},[462,2783,2784],{},"int Value",[431,2786,1018,2787,472,2789,2792,2793,2796,2797,479],{},[462,2788,1291],{},[462,2790,2791],{},"HasValue = false",", truy cập ",[462,2794,2795],{},".Value"," ném ",[462,2798,2799],{},"InvalidOperationException",[577,2801,2803],{"className":739,"code":2802,"language":741,"meta":585,"style":585},"int? age = null;\nConsole.WriteLine(age.HasValue);     \u002F\u002F False\n\u002F\u002F Console.WriteLine(age.Value);     \u002F\u002F throws\n\nage = 25;\nConsole.WriteLine(age.HasValue);     \u002F\u002F True\nConsole.WriteLine(age.Value);        \u002F\u002F 25\n\n\u002F\u002F Cú pháp tắt\nint safeAge = age ?? 0;              \u002F\u002F ?? trả 0 nếu null\n",[462,2804,2805,2810,2815,2823,2827,2832,2837,2842,2846,2851],{"__ignoreMap":585},[745,2806,2807],{"class":747,"line":748},[745,2808,2809],{},"int? age = null;\n",[745,2811,2812],{"class":747,"line":754},[745,2813,2814],{},"Console.WriteLine(age.HasValue);     \u002F\u002F False\n",[745,2816,2817,2820],{"class":747,"line":760},[745,2818,2819],{},"\u002F\u002F Console.WriteLine(age.Value);",[745,2821,2822],{},"     \u002F\u002F throws\n",[745,2824,2825],{"class":747,"line":766},[745,2826,788],{"emptyLinePlaceholder":787},[745,2828,2829],{"class":747,"line":772},[745,2830,2831],{},"age = 25;\n",[745,2833,2834],{"class":747,"line":778},[745,2835,2836],{},"Console.WriteLine(age.HasValue);     \u002F\u002F True\n",[745,2838,2839],{"class":747,"line":784},[745,2840,2841],{},"Console.WriteLine(age.Value);        \u002F\u002F 25\n",[745,2843,2844],{"class":747,"line":791},[745,2845,788],{"emptyLinePlaceholder":787},[745,2847,2848],{"class":747,"line":797},[745,2849,2850],{},"\u002F\u002F Cú pháp tắt\n",[745,2852,2853],{"class":747,"line":803},[745,2854,2855],{},"int safeAge = age ?? 0;              \u002F\u002F ?? trả 0 nếu null\n",[536,2857,2859],{"id":2858},"_72-nullable-reference-type-c-8","7.2. Nullable reference type (C# 8+)",[431,2861,2862,2863,2866],{},"Trước C# 8, mọi reference type ngầm cho phép null. Từ C# 8, khi bật ",[462,2864,2865],{},"\u003CNullable>enable\u003C\u002FNullable>"," trong csproj:",[440,2868,2869,2874],{},[443,2870,2871,2873],{},[462,2872,464],{}," = không null (compiler cảnh báo nếu gán null).",[443,2875,2876,2879],{},[462,2877,2878],{},"string?"," = có thể null.",[577,2881,2883],{"className":739,"code":2882,"language":741,"meta":585,"style":585},"string name = null;       \u002F\u002F ⚠ Compiler warning: CS8600\nstring? maybeName = null; \u002F\u002F OK\n\nvoid Print(string s) {\n    Console.WriteLine(s.Length);          \u002F\u002F OK — compiler tin s không null\n}\n\nvoid PrintMaybe(string? s) {\n    Console.WriteLine(s.Length);          \u002F\u002F ⚠ Warning: s có thể null\n    Console.WriteLine(s?.Length ?? 0);    \u002F\u002F OK — null-safe\n}\n",[462,2884,2885,2890,2895,2899,2904,2909,2913,2917,2922,2927,2932],{"__ignoreMap":585},[745,2886,2887],{"class":747,"line":748},[745,2888,2889],{},"string name = null;       \u002F\u002F ⚠ Compiler warning: CS8600\n",[745,2891,2892],{"class":747,"line":754},[745,2893,2894],{},"string? maybeName = null; \u002F\u002F OK\n",[745,2896,2897],{"class":747,"line":760},[745,2898,788],{"emptyLinePlaceholder":787},[745,2900,2901],{"class":747,"line":766},[745,2902,2903],{},"void Print(string s) {\n",[745,2905,2906],{"class":747,"line":772},[745,2907,2908],{},"    Console.WriteLine(s.Length);          \u002F\u002F OK — compiler tin s không null\n",[745,2910,2911],{"class":747,"line":778},[745,2912,781],{},[745,2914,2915],{"class":747,"line":784},[745,2916,788],{"emptyLinePlaceholder":787},[745,2918,2919],{"class":747,"line":791},[745,2920,2921],{},"void PrintMaybe(string? s) {\n",[745,2923,2924],{"class":747,"line":797},[745,2925,2926],{},"    Console.WriteLine(s.Length);          \u002F\u002F ⚠ Warning: s có thể null\n",[745,2928,2929],{"class":747,"line":803},[745,2930,2931],{},"    Console.WriteLine(s?.Length ?? 0);    \u002F\u002F OK — null-safe\n",[745,2933,2934],{"class":747,"line":809},[745,2935,781],{},[536,2937,2939],{"id":2938},"_73-operators-thường-dùng","7.3. Operators thường dùng",[488,2941,2942,2945],{"color":1791,"icon":268},[431,2943,2944],{},"🔵",[611,2946,2947,2959],{},[614,2948,2949],{},[617,2950,2951,2954,2957],{},[620,2952,2953],{},"Operator",[620,2955,2956],{},"Tác dụng",[620,2958,1192],{},[627,2960,2961,2976,2991,3006,3021],{},[617,2962,2963,2968,2971],{},[632,2964,2965],{},[462,2966,2967],{},"??",[632,2969,2970],{},"Null-coalescing — trả vế phải nếu trái null",[632,2972,2973],{},[462,2974,2975],{},"string n = name ?? \"guest\";",[617,2977,2978,2983,2986],{},[632,2979,2980],{},[462,2981,2982],{},"??=",[632,2984,2985],{},"Gán nếu đang null",[632,2987,2988],{},[462,2989,2990],{},"name ??= \"guest\";",[617,2992,2993,2998,3001],{},[632,2994,2995],{},[462,2996,2997],{},"?.",[632,2999,3000],{},"Null-conditional — trả null thay vì throw",[632,3002,3003],{},[462,3004,3005],{},"user?.Address?.City",[617,3007,3008,3013,3016],{},[632,3009,3010],{},[462,3011,3012],{},"?[]",[632,3014,3015],{},"Null-conditional indexer",[632,3017,3018],{},[462,3019,3020],{},"arr?[0]",[617,3022,3023,3028,3031],{},[632,3024,3025],{},[462,3026,3027],{},"!",[632,3029,3030],{},"Null-forgiving (tell compiler \"I know\")",[632,3032,3033],{},[462,3034,3035],{},"Console.WriteLine(name!.Length);",[577,3037,3039],{"className":739,"code":3038,"language":741,"meta":585,"style":585},"string? GetName() => \u002F* maybe null *\u002F;\n\n\u002F\u002F Chain an toàn\nint len = GetName()?.Trim().Length ?? 0;\n\n\u002F\u002F Nếu chắc chắn không null (vd. vừa check) — dùng ! để tắt warning\nif (name != null) {\n    var upper = name!.ToUpper();   \u002F\u002F hoặc compiler tự suy luận sau check\n}\n",[462,3040,3041,3046,3050,3055,3060,3064,3069,3074,3079],{"__ignoreMap":585},[745,3042,3043],{"class":747,"line":748},[745,3044,3045],{},"string? GetName() => \u002F* maybe null *\u002F;\n",[745,3047,3048],{"class":747,"line":754},[745,3049,788],{"emptyLinePlaceholder":787},[745,3051,3052],{"class":747,"line":760},[745,3053,3054],{},"\u002F\u002F Chain an toàn\n",[745,3056,3057],{"class":747,"line":766},[745,3058,3059],{},"int len = GetName()?.Trim().Length ?? 0;\n",[745,3061,3062],{"class":747,"line":772},[745,3063,788],{"emptyLinePlaceholder":787},[745,3065,3066],{"class":747,"line":778},[745,3067,3068],{},"\u002F\u002F Nếu chắc chắn không null (vd. vừa check) — dùng ! để tắt warning\n",[745,3070,3071],{"class":747,"line":784},[745,3072,3073],{},"if (name != null) {\n",[745,3075,3076],{"class":747,"line":791},[745,3077,3078],{},"    var upper = name!.ToUpper();   \u002F\u002F hoặc compiler tự suy luận sau check\n",[745,3080,3081],{"class":747,"line":797},[745,3082,781],{},[529,3084],{},[426,3086,3088],{"id":3087},"_8-exception-trycatchfinally","8. Exception — try\u002Fcatch\u002Ffinally",[536,3090,3092],{"id":3091},"_81-cú-pháp-cơ-bản","8.1. Cú pháp cơ bản",[577,3094,3096],{"className":739,"code":3095,"language":741,"meta":585,"style":585},"try {\n    DoSomething();\n}\ncatch (FileNotFoundException ex) {\n    \u002F\u002F Bắt cụ thể trước\n    logger.Warn($\"Missing file: {ex.FileName}\");\n    throw;        \u002F\u002F rethrow — giữ stack trace gốc\n}\ncatch (IOException ex) when (ex.HResult == -2147024864) {\n    \u002F\u002F Filter — chỉ catch nếu điều kiện đúng\n    HandleSharingViolation();\n}\ncatch (Exception ex) {\n    \u002F\u002F Catch-all — cuối cùng\n    logger.Error(ex);\n    throw new ApplicationException(\"Wrapped\", ex);  \u002F\u002F wrap với inner\n}\nfinally {\n    Cleanup();    \u002F\u002F luôn chạy, kể cả exception hay return\n}\n",[462,3097,3098,3103,3108,3112,3117,3122,3127,3132,3136,3141,3146,3151,3155,3160,3165,3171,3177,3182,3188,3194],{"__ignoreMap":585},[745,3099,3100],{"class":747,"line":748},[745,3101,3102],{},"try {\n",[745,3104,3105],{"class":747,"line":754},[745,3106,3107],{},"    DoSomething();\n",[745,3109,3110],{"class":747,"line":760},[745,3111,781],{},[745,3113,3114],{"class":747,"line":766},[745,3115,3116],{},"catch (FileNotFoundException ex) {\n",[745,3118,3119],{"class":747,"line":772},[745,3120,3121],{},"    \u002F\u002F Bắt cụ thể trước\n",[745,3123,3124],{"class":747,"line":778},[745,3125,3126],{},"    logger.Warn($\"Missing file: {ex.FileName}\");\n",[745,3128,3129],{"class":747,"line":784},[745,3130,3131],{},"    throw;        \u002F\u002F rethrow — giữ stack trace gốc\n",[745,3133,3134],{"class":747,"line":791},[745,3135,781],{},[745,3137,3138],{"class":747,"line":797},[745,3139,3140],{},"catch (IOException ex) when (ex.HResult == -2147024864) {\n",[745,3142,3143],{"class":747,"line":803},[745,3144,3145],{},"    \u002F\u002F Filter — chỉ catch nếu điều kiện đúng\n",[745,3147,3148],{"class":747,"line":809},[745,3149,3150],{},"    HandleSharingViolation();\n",[745,3152,3153],{"class":747,"line":815},[745,3154,781],{},[745,3156,3157],{"class":747,"line":1474},[745,3158,3159],{},"catch (Exception ex) {\n",[745,3161,3162],{"class":747,"line":1480},[745,3163,3164],{},"    \u002F\u002F Catch-all — cuối cùng\n",[745,3166,3168],{"class":747,"line":3167},15,[745,3169,3170],{},"    logger.Error(ex);\n",[745,3172,3174],{"class":747,"line":3173},16,[745,3175,3176],{},"    throw new ApplicationException(\"Wrapped\", ex);  \u002F\u002F wrap với inner\n",[745,3178,3180],{"class":747,"line":3179},17,[745,3181,781],{},[745,3183,3185],{"class":747,"line":3184},18,[745,3186,3187],{},"finally {\n",[745,3189,3191],{"class":747,"line":3190},19,[745,3192,3193],{},"    Cleanup();    \u002F\u002F luôn chạy, kể cả exception hay return\n",[745,3195,3197],{"class":747,"line":3196},20,[745,3198,781],{},[536,3200,3202,3203,2219,3206,3208],{"id":3201},"_82-throw-vs-throw-ex-bẫy-kinh-điển","8.2. ",[462,3204,3205],{},"throw",[462,3207,485],{}," — bẫy kinh điển",[488,3210,3211,3222,3236],{"color":1686,"icon":1687},[431,3212,509,3213,3218,3219,479],{},[435,3214,3215],{},[462,3216,3217],{},"throw;"," rethrow exception ",[435,3220,3221],{},"giữ nguyên stack trace",[431,3223,3224,2731,3229,3232,3233,3235],{},[435,3225,3226],{},[462,3227,3228],{},"throw ex;",[435,3230,3231],{},"reset"," stack trace về dòng ",[462,3234,485],{}," → mất thông tin nguồn gốc lỗi.",[431,3237,3238,3239,3244],{},"→ ",[435,3240,3241,3242],{},"Luôn dùng ",[462,3243,3217],{}," trừ khi cố ý wrap exception.",[577,3246,3248],{"className":739,"code":3247,"language":741,"meta":585,"style":585},"try {\n    File.ReadAllText(\"\u002Fmissing.txt\");\n}\ncatch (FileNotFoundException ex) {\n    \u002F\u002F ❌ throw ex;  → stack trace chỉ tới dòng này, mất chỗ ReadAllText\n    \n    \u002F\u002F ✅ Đúng\n    throw;\n    \n    \u002F\u002F ✅ Hoặc wrap có chủ ý — giữ inner exception\n    throw new DataLoadException(\"Couldn't load config\", ex);\n}\n",[462,3249,3250,3254,3259,3263,3267,3272,3276,3281,3286,3290,3295,3300],{"__ignoreMap":585},[745,3251,3252],{"class":747,"line":748},[745,3253,3102],{},[745,3255,3256],{"class":747,"line":754},[745,3257,3258],{},"    File.ReadAllText(\"\u002Fmissing.txt\");\n",[745,3260,3261],{"class":747,"line":760},[745,3262,781],{},[745,3264,3265],{"class":747,"line":766},[745,3266,3116],{},[745,3268,3269],{"class":747,"line":772},[745,3270,3271],{},"    \u002F\u002F ❌ throw ex;  → stack trace chỉ tới dòng này, mất chỗ ReadAllText\n",[745,3273,3274],{"class":747,"line":778},[745,3275,2445],{},[745,3277,3278],{"class":747,"line":784},[745,3279,3280],{},"    \u002F\u002F ✅ Đúng\n",[745,3282,3283],{"class":747,"line":791},[745,3284,3285],{},"    throw;\n",[745,3287,3288],{"class":747,"line":797},[745,3289,2445],{},[745,3291,3292],{"class":747,"line":803},[745,3293,3294],{},"    \u002F\u002F ✅ Hoặc wrap có chủ ý — giữ inner exception\n",[745,3296,3297],{"class":747,"line":809},[745,3298,3299],{},"    throw new DataLoadException(\"Couldn't load config\", ex);\n",[745,3301,3302],{"class":747,"line":815},[745,3303,781],{},[536,3305,3307,3308,3311],{"id":3306},"_83-using-giải-phóng-tài-nguyên","8.3. ",[462,3309,3310],{},"using"," — giải phóng tài nguyên",[488,3313,502,3314,1545,3316,2766,3318,3321,3322,3325],{"color":490,"icon":491},[462,3315,3310],{},[435,3317,2765],{},[462,3319,3320],{},"try \u002F finally { obj.Dispose(); }"," — đảm bảo ",[462,3323,3324],{},"Dispose()"," chạy kể cả có exception.",[577,3327,3329],{"className":739,"code":3328,"language":741,"meta":585,"style":585},"\u002F\u002F Cú pháp block\nusing (var stream = new FileStream(\"a.txt\", FileMode.Open)) {\n    \u002F\u002F ...\n}   \u002F\u002F tự gọi stream.Dispose() ở đây\n\n\u002F\u002F C# 8+ — using declaration (tắt block, scope theo enclosing)\nvoid Read() {\n    using var stream = new FileStream(\"a.txt\", FileMode.Open);\n    \u002F\u002F ... \n}   \u002F\u002F stream.Dispose() khi method return\n",[462,3330,3331,3336,3341,3346,3351,3355,3360,3365,3370,3375],{"__ignoreMap":585},[745,3332,3333],{"class":747,"line":748},[745,3334,3335],{},"\u002F\u002F Cú pháp block\n",[745,3337,3338],{"class":747,"line":754},[745,3339,3340],{},"using (var stream = new FileStream(\"a.txt\", FileMode.Open)) {\n",[745,3342,3343],{"class":747,"line":760},[745,3344,3345],{},"    \u002F\u002F ...\n",[745,3347,3348],{"class":747,"line":766},[745,3349,3350],{},"}   \u002F\u002F tự gọi stream.Dispose() ở đây\n",[745,3352,3353],{"class":747,"line":772},[745,3354,788],{"emptyLinePlaceholder":787},[745,3356,3357],{"class":747,"line":778},[745,3358,3359],{},"\u002F\u002F C# 8+ — using declaration (tắt block, scope theo enclosing)\n",[745,3361,3362],{"class":747,"line":784},[745,3363,3364],{},"void Read() {\n",[745,3366,3367],{"class":747,"line":791},[745,3368,3369],{},"    using var stream = new FileStream(\"a.txt\", FileMode.Open);\n",[745,3371,3372],{"class":747,"line":797},[745,3373,3374],{},"    \u002F\u002F ... \n",[745,3376,3377],{"class":747,"line":803},[745,3378,3379],{},"}   \u002F\u002F stream.Dispose() khi method return\n",[431,3381,3382],{},"Tương đương:",[577,3384,3386],{"className":739,"code":3385,"language":741,"meta":585,"style":585},"{\n    var stream = new FileStream(\"a.txt\", FileMode.Open);\n    try { \u002F* ... *\u002F }\n    finally { stream.Dispose(); }\n}\n",[462,3387,3388,3393,3398,3403,3408],{"__ignoreMap":585},[745,3389,3390],{"class":747,"line":748},[745,3391,3392],{},"{\n",[745,3394,3395],{"class":747,"line":754},[745,3396,3397],{},"    var stream = new FileStream(\"a.txt\", FileMode.Open);\n",[745,3399,3400],{"class":747,"line":760},[745,3401,3402],{},"    try { \u002F* ... *\u002F }\n",[745,3404,3405],{"class":747,"line":766},[745,3406,3407],{},"    finally { stream.Dispose(); }\n",[745,3409,3410],{"class":747,"line":772},[745,3411,781],{},[536,3413,3415],{"id":3414},"_84-exception-filter-c-6","8.4. Exception filter — C# 6+",[488,3417,3418,3424,3436],{"color":542,"icon":268},[431,3419,516,3420,3423],{},[462,3421,3422],{},"catch (ExType ex) when (condition)"," — chỉ catch nếu condition true. Khác chỗ:",[440,3425,3426,3433],{},[443,3427,3428,3429,3432],{},"Stack trace của exception ",[435,3430,3431],{},"không bị unwind"," khi condition false → giữ context gốc.",[443,3434,3435],{},"Có thể log mà không catch:",[577,3437,3439],{"className":739,"code":3438,"language":741,"meta":585,"style":585},"catch (Exception ex) when (LogAndReturn(ex, false)) { }\n\u002F\u002F ↑ LogAndReturn luôn return false → không catch, nhưng đã log\n",[462,3440,3441,3446],{"__ignoreMap":585},[745,3442,3443],{"class":747,"line":748},[745,3444,3445],{},"catch (Exception ex) when (LogAndReturn(ex, false)) { }\n",[745,3447,3448],{"class":747,"line":754},[745,3449,3450],{},"\u002F\u002F ↑ LogAndReturn luôn return false → không catch, nhưng đã log\n",[529,3452],{},[426,3454,3456],{"id":3455},"_9-bài-tập-coding-học-cách-suy-nghĩ-không-chỉ-code","9. Bài tập coding — học cách suy nghĩ, không chỉ code",[536,3458,3460],{"id":3459},"_91-fizzbuzz","9.1. FizzBuzz",[431,3462,3463,3466],{},[435,3464,3465],{},"Đề:"," in 1 đến 100. Số chia hết 3 → \"Fizz\". 5 → \"Buzz\". Cả 3 và 5 → \"FizzBuzz\".",[431,3468,3469],{},[435,3470,3471],{},"Cách suy nghĩ:",[1694,3473,3474,3477,3480],{},[443,3475,3476],{},"Check chia hết 15 trước (vì 15 = 3 × 5).",[443,3478,3479],{},"Sau đó check 3, rồi 5.",[443,3481,3482],{},"Nếu không, in số.",[577,3484,3486],{"className":739,"code":3485,"language":741,"meta":585,"style":585},"for (int i = 1; i \u003C= 100; i++) {\n    if (i % 15 == 0) Console.WriteLine(\"FizzBuzz\");\n    else if (i % 3 == 0) Console.WriteLine(\"Fizz\");\n    else if (i % 5 == 0) Console.WriteLine(\"Buzz\");\n    else Console.WriteLine(i);\n}\n",[462,3487,3488,3493,3498,3503,3508,3513],{"__ignoreMap":585},[745,3489,3490],{"class":747,"line":748},[745,3491,3492],{},"for (int i = 1; i \u003C= 100; i++) {\n",[745,3494,3495],{"class":747,"line":754},[745,3496,3497],{},"    if (i % 15 == 0) Console.WriteLine(\"FizzBuzz\");\n",[745,3499,3500],{"class":747,"line":760},[745,3501,3502],{},"    else if (i % 3 == 0) Console.WriteLine(\"Fizz\");\n",[745,3504,3505],{"class":747,"line":766},[745,3506,3507],{},"    else if (i % 5 == 0) Console.WriteLine(\"Buzz\");\n",[745,3509,3510],{"class":747,"line":772},[745,3511,3512],{},"    else Console.WriteLine(i);\n",[745,3514,3515],{"class":747,"line":778},[745,3516,781],{},[488,3518,509,3519,3522],{"color":542,"icon":543},[435,3520,3521],{},"Bẫy fresher hay mắc:"," check 3 trước, rồi 5, không check 15 → số 15 chỉ in \"Fizz\". Interviewer sẽ thử số 15, 30.",[536,3524,3526],{"id":3525},"_92-đảo-chuỗi","9.2. Đảo chuỗi",[431,3528,3529],{},[435,3530,3531],{},"Cách 1 — dùng Array.Reverse:",[577,3533,3535],{"className":739,"code":3534,"language":741,"meta":585,"style":585},"public static string Reverse(string s) {\n    var arr = s.ToCharArray();\n    Array.Reverse(arr);\n    return new string(arr);\n}\n",[462,3536,3537,3542,3547,3552,3557],{"__ignoreMap":585},[745,3538,3539],{"class":747,"line":748},[745,3540,3541],{},"public static string Reverse(string s) {\n",[745,3543,3544],{"class":747,"line":754},[745,3545,3546],{},"    var arr = s.ToCharArray();\n",[745,3548,3549],{"class":747,"line":760},[745,3550,3551],{},"    Array.Reverse(arr);\n",[745,3553,3554],{"class":747,"line":766},[745,3555,3556],{},"    return new string(arr);\n",[745,3558,3559],{"class":747,"line":772},[745,3560,781],{},[431,3562,3563],{},[435,3564,3565],{},"Cách 2 — two pointer (tự viết):",[577,3567,3569],{"className":739,"code":3568,"language":741,"meta":585,"style":585},"public static string ReverseManual(string s) {\n    var arr = s.ToCharArray();\n    int l = 0, r = arr.Length - 1;\n    while (l \u003C r) {\n        (arr[l], arr[r]) = (arr[r], arr[l]);   \u002F\u002F swap qua tuple\n        l++;\n        r--;\n    }\n    return new string(arr);\n}\n",[462,3570,3571,3576,3580,3585,3590,3595,3600,3605,3609,3613],{"__ignoreMap":585},[745,3572,3573],{"class":747,"line":748},[745,3574,3575],{},"public static string ReverseManual(string s) {\n",[745,3577,3578],{"class":747,"line":754},[745,3579,3546],{},[745,3581,3582],{"class":747,"line":760},[745,3583,3584],{},"    int l = 0, r = arr.Length - 1;\n",[745,3586,3587],{"class":747,"line":766},[745,3588,3589],{},"    while (l \u003C r) {\n",[745,3591,3592],{"class":747,"line":772},[745,3593,3594],{},"        (arr[l], arr[r]) = (arr[r], arr[l]);   \u002F\u002F swap qua tuple\n",[745,3596,3597],{"class":747,"line":778},[745,3598,3599],{},"        l++;\n",[745,3601,3602],{"class":747,"line":784},[745,3603,3604],{},"        r--;\n",[745,3606,3607],{"class":747,"line":791},[745,3608,2682],{},[745,3610,3611],{"class":747,"line":797},[745,3612,3556],{},[745,3614,3615],{"class":747,"line":803},[745,3616,781],{},[431,3618,3619,3622],{},[435,3620,3621],{},"Complexity:"," O(n) thời gian, O(n) space (cho mảng char + chuỗi mới).",[536,3624,3626],{"id":3625},"_93-đếm-tần-suất-ký-tự","9.3. Đếm tần suất ký tự",[577,3628,3630],{"className":739,"code":3629,"language":741,"meta":585,"style":585},"public static Dictionary\u003Cchar, int> CountChars(string s) {\n    var dict = new Dictionary\u003Cchar, int>();\n    foreach (var c in s) {\n        if (dict.ContainsKey(c)) dict[c]++;\n        else dict[c] = 1;\n    }\n    return dict;\n}\n",[462,3631,3632,3637,3642,3647,3652,3657,3661,3666],{"__ignoreMap":585},[745,3633,3634],{"class":747,"line":748},[745,3635,3636],{},"public static Dictionary\u003Cchar, int> CountChars(string s) {\n",[745,3638,3639],{"class":747,"line":754},[745,3640,3641],{},"    var dict = new Dictionary\u003Cchar, int>();\n",[745,3643,3644],{"class":747,"line":760},[745,3645,3646],{},"    foreach (var c in s) {\n",[745,3648,3649],{"class":747,"line":766},[745,3650,3651],{},"        if (dict.ContainsKey(c)) dict[c]++;\n",[745,3653,3654],{"class":747,"line":772},[745,3655,3656],{},"        else dict[c] = 1;\n",[745,3658,3659],{"class":747,"line":778},[745,3660,2682],{},[745,3662,3663],{"class":747,"line":784},[745,3664,3665],{},"    return dict;\n",[745,3667,3668],{"class":747,"line":791},[745,3669,781],{},[431,3671,3672],{},[435,3673,3674,3675,1936],{},"Hoặc gọn hơn với ",[462,3676,3677],{},"GetValueOrDefault",[577,3679,3681],{"className":739,"code":3680,"language":741,"meta":585,"style":585},"public static Dictionary\u003Cchar, int> CountChars(string s) {\n    var dict = new Dictionary\u003Cchar, int>();\n    foreach (var c in s) {\n        dict[c] = dict.GetValueOrDefault(c) + 1;\n    }\n    return dict;\n}\n",[462,3682,3683,3687,3691,3695,3700,3704,3708],{"__ignoreMap":585},[745,3684,3685],{"class":747,"line":748},[745,3686,3636],{},[745,3688,3689],{"class":747,"line":754},[745,3690,3641],{},[745,3692,3693],{"class":747,"line":760},[745,3694,3646],{},[745,3696,3697],{"class":747,"line":766},[745,3698,3699],{},"        dict[c] = dict.GetValueOrDefault(c) + 1;\n",[745,3701,3702],{"class":747,"line":772},[745,3703,2682],{},[745,3705,3706],{"class":747,"line":778},[745,3707,3665],{},[745,3709,3710],{"class":747,"line":784},[745,3711,781],{},[431,3713,3714,3716],{},[435,3715,3621],{}," O(n) thời gian, O(k) space (k = số ký tự distinct).",[536,3718,3720],{"id":3719},"_94-kiểm-tra-palindrome","9.4. Kiểm tra palindrome",[577,3722,3724],{"className":739,"code":3723,"language":741,"meta":585,"style":585},"public static bool IsPalindrome(string s) {\n    int l = 0, r = s.Length - 1;\n    while (l \u003C r) {\n        if (char.ToLower(s[l]) != char.ToLower(s[r])) return false;\n        l++;\n        r--;\n    }\n    return true;\n}\n",[462,3725,3726,3731,3736,3740,3745,3749,3753,3757,3762],{"__ignoreMap":585},[745,3727,3728],{"class":747,"line":748},[745,3729,3730],{},"public static bool IsPalindrome(string s) {\n",[745,3732,3733],{"class":747,"line":754},[745,3734,3735],{},"    int l = 0, r = s.Length - 1;\n",[745,3737,3738],{"class":747,"line":760},[745,3739,3589],{},[745,3741,3742],{"class":747,"line":766},[745,3743,3744],{},"        if (char.ToLower(s[l]) != char.ToLower(s[r])) return false;\n",[745,3746,3747],{"class":747,"line":772},[745,3748,3599],{},[745,3750,3751],{"class":747,"line":778},[745,3752,3604],{},[745,3754,3755],{"class":747,"line":784},[745,3756,2682],{},[745,3758,3759],{"class":747,"line":791},[745,3760,3761],{},"    return true;\n",[745,3763,3764],{"class":747,"line":797},[745,3765,781],{},[431,3767,3768,3771],{},[435,3769,3770],{},"Tại sao two pointer?"," Vì palindrome đối xứng — so sánh ký tự đối xứng từ 2 đầu vào giữa.",[431,3773,3774,3776],{},[435,3775,3621],{}," O(n) thời gian, O(1) space.",[529,3778],{},[426,3780,3782],{"id":3781},"_10-câu-hỏi-tự-test-cuối-ngày","10. Câu hỏi tự test cuối ngày",[488,3784,3786,3791,3810,3839,3860],{"color":490,"icon":3785},"i-lucide-help-circle",[431,3787,3788],{},[435,3789,3790],{},"Level 🟢 Intern:",[1694,3792,3793,3796,3799],{},[443,3794,3795],{},"Stack và Heap khác nhau ra sao? Lưu cái gì?",[443,3797,3798],{},"Value type và Reference type — định nghĩa + ví dụ.",[443,3800,3801,1603,3803,3806,3807,3809],{},[462,3802,1291],{},[462,3804,3805],{},"undefined"," — C# có cả hai không? (Trả lời: chỉ ",[462,3808,1291],{},".)",[431,3811,3812,3815,3816,3818,3819,1603,3821,3823,3824,472,3826,472,3828,3830,3831,3834,3835,3838],{},[435,3813,3814],{},"Level 🔵 Junior:","\n4. Boxing\u002Funboxing là gì? Khi nào xảy ra ngầm?\n5. Vì sao ",[462,3817,2140],{}," trong loop chậm? Fix sao?\n6. ",[462,3820,3205],{},[462,3822,485],{}," khác nhau? Vì sao quan trọng?\n7. ",[462,3825,471],{},[462,3827,475],{},[462,3829,478],{}," — chọn cho ",[462,3832,3833],{},"Pi"," là gì? Cho ",[462,3836,3837],{},"DateTime.UtcNow","?",[431,3840,3841,3844,3845,3847,3848,3851,3852,3855,3856,3859],{},[435,3842,3843],{},"Level 🟡 Mid:","\n8. Override ",[462,3846,2271],{}," thì cần override gì nữa? Vì sao?\n9. Vẽ memory cho: ",[462,3849,3850],{},"int x = 5; var u = new User { Name = \"A\" };",".\n10. ",[462,3853,3854],{},"int? x = null; object o = x;"," — ",[462,3857,3858],{},"o"," là gì? Vì sao?",[431,3861,3862,3865,3866,3868,3869,3872],{},[435,3863,3864],{},"Level 🔴 Senior:","\n11. .NET GC dùng generation nào? Vì sao chia generation?\n12. LOH (Large Object Heap) khác Gen 0\u002F1\u002F2 ra sao?\n13. Trong ",[462,3867,2488],{},", equality dùng cơ chế gì để generate?\n14. Exception filter ",[462,3870,3871],{},"when"," khác bình thường ra sao về stack trace?",[431,3874,3875,3878,3879,479],{},[435,3876,3877],{},"Đáp án:"," xem ",[1602,3880,3881],{"href":74},"Ngân hàng câu hỏi C#",[529,3883],{},[488,3885,3887,3888],{"color":490,"icon":3886},"i-lucide-arrow-right","➡️ Sang ngày mai: ",[1602,3889,3890],{"href":38},"Ngày 2 — OOP & SOLID",[3892,3893,3894],"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":585,"searchDepth":754,"depth":754,"links":3896},[3897,3898,3904,3912,3919,3929,3936,3943,3949,3957,3963],{"id":428,"depth":754,"text":429},{"id":533,"depth":754,"text":534,"children":3899},[3900,3901,3902,3903],{"id":538,"depth":760,"text":539},{"id":588,"depth":760,"text":589},{"id":829,"depth":760,"text":830},{"id":967,"depth":760,"text":968},{"id":1135,"depth":754,"text":1136,"children":3905},[3906,3907,3908,3909,3910],{"id":1139,"depth":760,"text":1140},{"id":1312,"depth":760,"text":1313},{"id":1355,"depth":760,"text":1356},{"id":1395,"depth":760,"text":1396},{"id":1536,"depth":760,"text":3911},"2.5. string — reference nhưng hành xử như value",{"id":1632,"depth":754,"text":1633,"children":3913},[3914,3915,3916,3917],{"id":1636,"depth":760,"text":1637},{"id":1682,"depth":760,"text":1683},{"id":1787,"depth":760,"text":1788},{"id":1864,"depth":760,"text":3918},"3.4. Câu trick — int? x = null; có boxing không?",{"id":1967,"depth":754,"text":3920,"children":3921},"4. string immutable & StringBuilder",[3922,3923,3924,3925,3927],{"id":1977,"depth":760,"text":1978},{"id":2025,"depth":760,"text":2026},{"id":2078,"depth":760,"text":2079},{"id":2149,"depth":760,"text":3926},"4.4. Khi nào dùng string thường?",{"id":2214,"depth":760,"text":3928},"4.5. StringBuilder.Capacity vs Length — câu hỏi sâu",{"id":2265,"depth":754,"text":3930,"children":3931},"5. So sánh: ==, Equals, ReferenceEquals",[3932,3933,3934],{"id":2277,"depth":760,"text":2278},{"id":2343,"depth":760,"text":2344},{"id":2405,"depth":760,"text":3935},"5.3. Override Equals đúng cách",{"id":2526,"depth":754,"text":3937,"children":3938},"6. const vs readonly vs static readonly",[3939,3940,3941],{"id":2536,"depth":760,"text":2537},{"id":2637,"depth":760,"text":2638},{"id":2698,"depth":760,"text":3942},"6.3. Bẫy const cross-assembly",{"id":2748,"depth":754,"text":2749,"children":3944},[3945,3947,3948],{"id":2752,"depth":760,"text":3946},"7.1. int? thực chất là gì?",{"id":2858,"depth":760,"text":2859},{"id":2938,"depth":760,"text":2939},{"id":3087,"depth":754,"text":3088,"children":3950},[3951,3952,3954,3956],{"id":3091,"depth":760,"text":3092},{"id":3201,"depth":760,"text":3953},"8.2. throw vs throw ex — bẫy kinh điển",{"id":3306,"depth":760,"text":3955},"8.3. using — giải phóng tài nguyên",{"id":3414,"depth":760,"text":3415},{"id":3455,"depth":754,"text":3456,"children":3958},[3959,3960,3961,3962],{"id":3459,"depth":760,"text":3460},{"id":3525,"depth":760,"text":3526},{"id":3625,"depth":760,"text":3626},{"id":3719,"depth":760,"text":3720},{"id":3781,"depth":754,"text":3782},"Stack\u002Fheap, value vs reference type, boxing\u002Funboxing, string\u002FStringBuilder, exception. Giải thích từ con số 0 cho intern → kiến thức nâng cao cho senior.","md",null,{},{"title":32,"icon":35},{"title":32,"description":3964},"V11XYUxFg84CVs4VO6mOd0kOWvekRQYzTAVg4Ms1pkI",[3972,3974],{"title":22,"path":23,"stem":24,"description":3973,"icon":25,"children":-1},"Kế hoạch học 7 ngày cho fresher .NET — mỗi ngày tập trung 1 chủ đề, lý thuyết + bài tập + câu hỏi phỏng vấn.",{"title":37,"path":38,"stem":39,"description":3975,"icon":40,"children":-1},"4 tính chất OOP, Interface vs Abstract class, 5 nguyên lý SOLID kèm ví dụ C Sharp.",1783490351068]