<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="/Skins/Default/Rss.xsl" ?>
<rss version="2.0">
<channel>
<title>Các lĩnh vực khác : Solution</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/</link>
<description>Các giải pháp giải quyết vấn đề...</description>
<publisher>Vietnam .NET Community</publisher>
<language>vi-VN</language>
<managingEditor>automail-noreply@dot.net.vn</managingEditor>
<webMaster>automail-noreply@dot.net.vn</webMaster>
<copyright>Copyright 2005-2008 Vietnam .NET Community</copyright>
<pubDate>Thu, 20 Nov 2008 22:52:51 GMT</pubDate>
<category>Các lĩnh vực khác</category>
<ttl>60</ttl>
<docs>http://cyber.law.harvard.edu/rss/rss.html</docs>
<generator>VIE Portal RSS Generator - Version 5.6.3183.28143 - http://www.vieportal.vn/</generator>
<item>
<title>"University of tayside" - Help ..thanks nhiều!</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/University_of_tayside-Help_thanks_nhieu/</link>
<description>Chào anh chị!&lt;br&gt;&lt;br&gt;Anh chị&amp;nbsp; có làm project "&lt;span style="font-weight: bold;"&gt;University of Tayside&lt;/span&gt;" (asp.net) rồi,reply bên dưới cho em biết nhé,em có vài điều trao đổi,..để yahoo cho em liên lạc hén, vì em ít time lên mạng lắm, thanks anh chị đã đọc!&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/University_of_tayside-Help_thanks_nhieu/1.viePortal</guid>
<pubDate>Wed, 22 Oct 2008 15:59:01 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Select với ký tự đặt biệt trong dotnet 2005</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Select_voi_ky_tu_dat_biet_trong_dotnet_2005/</link>
<description>trong đối tượng DataTable của dotnet có suport Method &amp;nbsp; DataTable.Select('điều kiện Filter'), có một vấn đề là khi tôi select với chuỗi có ký tự đặt biệt ví dụ là dấu nháy đơn thì trong dotnet 2005 ko suport cho kiểu select này các cao thủ có giải pháp gì xin giúp đở cho mọi người cùng học hỏi luôn, nói thêm theo tôi được biết ,vấn đề này được giải quyết tốt trong dotnet 2008 (dùng linQ),mong nhận được góp ý của các Bác thanks.&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/Select_voi_ky_tu_dat_biet_trong_dotnet_2005/1.viePortal</guid>
<pubDate>Wed, 08 Oct 2008 17:35:55 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Mỗi tuần một ý tưởng</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Moi_tuan_mot_y_tuong/</link>
<description>- Nơi ghi lại tất cả các ý tưởng của các bạn, dù đó là 1 ý tưởng nho nhỏ hay là 1 idea điên rồ. Có thể bạn là người nêu ra và không giải quyết được, nhưng có thể người khác sẽ giúp ích được. Trên tinh thần "knowledge is free" mình muốn có 1 chủ đề tập hợp lại các ý tưởng của cộng đồng dot.net&lt;br&gt;- Các bạn hãy thể hiện khả năng về ý tưởng của mình vào đây, cộng đồng chúng ta sẽ cùng nhau trao đổi về vấn đề này.&lt;br&gt;- Các bạn nghĩ sao khi mình tạo chủ đề này, đây cũng chính là 1 idea.&lt;br&gt;- Trên wiki cá nhân của mình thường xuyên ghi lại những ý tưởng điên rồ, hay là những ideas vô ích. Dù thế nào đi nữa thì đó cũng là IDEA.&lt;br&gt;- Là người create chủ đề, hôm nay mình pop lên 1 số ý tưởng của bản thân mình&lt;br&gt;&lt;br&gt;&lt;div class="wikipage"&gt;
    &lt;div id="searchable"&gt;&lt;h2 id="Crawlernhậnbiếtcónộidungmớitrênforum"&gt;Crawler nhận biết có nội dung mới trên forum&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Khi mình quan tâm đến chủ đề nào đó trên diễn đàn. Để có thể
nhận biết được có bài viết mới trong chủ đề của mình đang quan tâm, ý
tưởng của mình là viết 1 con crawler nhỏ tự động phân tích chủ đề cần
quan tâm trên forum đó. Khi crawler phát hiện có nội dung mới sẽ tự
động gửi nội dung mới về email của mình.
&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
   &lt;/div&gt;&lt;h2 id="Crawlernhậnbiếtcónộidungmớitrênforum"&gt;Ứng dụng Hadoop, HBase xây dựng hệ thống SubVersion&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;/h2&gt;&lt;br&gt;&lt;div class="wikipage"&gt;
    &lt;div id="searchable"&gt;&lt;h2 id="Crawlerlấyemailtừyahooblog"&gt;Crawler lấy email từ yahoo blog&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Đây là ý tưởng khá táo bạo. Trong yahoo blog ta có thể lấy tất
cả các friends list từ blog yahoo của mổi cá nhân. Và từ mỗi cá nhân
trong friends list đó ta lại tiếp tục lấy friends list. Như vậy là ta
có được tập các yahoo blog, điều này là thực hiện được
&lt;/li&gt;&lt;li&gt;Vấn đề khó khăn ở đây là trong mỗi blog yahoo cá nhân đó ta
chỉ thấy được liên kết của cá nhân đó với đoạn ID cho nick name đó, ta
không thể thấy được nick name của chủ nhân blog đó.
&lt;/li&gt;&lt;li&gt;Ví dụ: Ta có blog &lt;a class="ext-link" href="http://360.yahoo.com/profile-5TEeWNUidKgSGMiFaWR5SVVc"&gt;&lt;span class="icon"&gt;http://360.yahoo.com/profile-5TEeWNUidKgSGMiFaWR5SVVc&lt;/span&gt;&lt;/a&gt;.
bây giờ muốn lấy nick name hoặc email của ông này thì bó tay. Không
biết dòng mã hóa 5TEeWNUidKgSGMiFaWR5SVVc có phải là ID hay không, và
yahoo có hỗ trợ API cho phép lấy nick name hay email từ dòng mã hóa đó
hay không
&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
   &lt;/div&gt;&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/Moi_tuan_mot_y_tuong/1.viePortal</guid>
<pubDate>Wed, 08 Oct 2008 00:17:23 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Abstract and interface</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Abstract_and_interface/</link>
<description>&lt;b&gt;Abstract:&lt;/b&gt;&lt;br&gt;
- Single inheritance&lt;br&gt;
- Fast performance&lt;br&gt;
- Security problem (trong môi trường distributed application, rõ ràng
ta không muốn đưa code cho clients mà nên dùng interface để cho phép
clients có thể làm chuyện gì đó thôi đặng khỏi bị reverse engineer)&lt;br&gt;
- Khi base class thay đổi thì class kế thừa sẽ bị ảnh hưởng theo. (Điều
này vừa tốt vừa xấu, muốn biết tại sao thì xem blogs của Whidbey
architects có bàn về chuyện này)&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Interface:&lt;/b&gt;&lt;br&gt;
- multiple inheritance. Chính xác hơn thì interace không phải là inheritance mà là một "contracts".&lt;br&gt;
- Chậm hơn tí xíu nhưng flexible hơn abstract hoặc virtual&lt;br&gt;
- Tuyệt vời khi cần tách biệt giữa những thứ mà mà 1 assembly cung cấp
hoặc yêu cầu với code thực tế. (vì lý do bảo mật, vì mô hình module,
vv.)&lt;br&gt;
- Một điểm nữa là interface được sử dụng rất nhiều trong design patterns. &lt;br&gt;
&lt;br&gt;
Bạn cứ áp dụng design patterns nhiều nhiều đi. Sẽ có lúc những thứ này
ăn vào da vào thịt bạn đến độ khỏi suy nghĩ cũng biết nên sử dụng
abstraction hay interface cho từng trường hợp &lt;img src="http://ddth.com/images/smilies/smile.gif" alt="" title="Smilie" class="inlineimg" border="0"&gt;&lt;br&gt;
&lt;br&gt;
Code ví dụ:&lt;br&gt;
&lt;b&gt;Abstract: &lt;/b&gt;&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 338px; text-align: left;"&gt;             public abstract class AnimalBase&lt;br&gt;	{&lt;br&gt;		public abstract void Roar();&lt;br&gt;&lt;br&gt;		public abstract int NumberOfLegs{get;set;}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public class Dog : AnimalBase&lt;br&gt;	{&lt;br&gt;		public override void Roar()&lt;br&gt;		{&lt;br&gt;			MessageBox.Show("Bark bark bark");&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		public override int NumberOfLegs&lt;br&gt;		{&lt;br&gt;			get { return 4; }&lt;br&gt;			set { throw new Exception("Huh? A dog with more than 4 legs?"); }&lt;br&gt;		}&lt;br&gt;	}&lt;/pre&gt;
&lt;/div&gt;[b]Interface:[b]&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 386px; text-align: left;"&gt;             public interface ICanRoar&lt;br&gt;	{&lt;br&gt;		void Roar();&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public interface IHasLegs&lt;br&gt;	{&lt;br&gt;		int NumberOfLegs { get;set;}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public class Cat : ICanRoar, IHasLegs&lt;br&gt;	{&lt;br&gt;		public void Roar()&lt;br&gt;		{&lt;br&gt;			MessageBox.Show("Meow");&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		public int NumberOfLegs&lt;br&gt;		{&lt;br&gt;			get { return 4; }&lt;br&gt;			set { throw new Exception("Sorry you meanie, I don't wanna change my little cat's DNA"); }&lt;br&gt;		}&lt;br&gt;	}&lt;/pre&gt;
&lt;/div&gt;
		&lt;!-- / message --&gt;&lt;!-- controls --&gt; &lt;br&gt;&lt;div id="post_message_426866"&gt;&lt;b&gt;Benchmark performance of Abstract, Virtual and Interface:&lt;/b&gt;&lt;br&gt;
Sau đây là kết quả mà mình đạt được nhờ benchmarking. (Mình dùng đỡ
DateTime.Now.Ticks, tuy không chính xác như querycounter nhưng cũng
chấp nhận được)&lt;br&gt;
&lt;br&gt;
- Method calling 1 billion times - Virtual class: 3366.576 ms&lt;br&gt;
- Method calling 1 billion times - Abstract class: 3382.162 ms&lt;br&gt;
- Method calling 1 billion times - Interface: 966.332 ms&lt;br&gt;
&lt;br&gt;
- Property accessing 1 billion times - Virtual class: 3397.748 ms&lt;br&gt;
- Property accessing 1 billion times - Abstract class: 3460.092 ms&lt;br&gt;
- Property accessing 1 billion times - Interface: 996.332 ms&lt;br&gt;
(Compiled with Whidbey 2.0 beta 2, release mode,  &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt;:  &lt;a href="http://www.ddth.com/autolink.php?id=17&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Advanced Micro Devices, Inc.&lt;/b&gt; (AMD) là nhà sản xuất CPU x86 lớn thứ hai thế giới sau Intel và là một trong những nhà sản xuất bộ nhớ flash hàng đầu trên thế giới; ngoài ra AMD còn sản xuất chipset và các linh kiện điện tử bán dẫn khác.&lt;br /&gt;\r\n&lt;br /&gt;\r\n-------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\nBạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;AMD&lt;/a&gt; 3000+, 1GB  &lt;a href="http://www.ddth.com/autolink.php?id=19&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Random Access Memory&lt;/b&gt; - RAM là một loại &lt;b&gt;bộ nhớ&lt;/b&gt; máy tính, nội dung của nó có thể được truy cập theo bất kỳ thứ tự nào.   &lt;br /&gt;\r\n&lt;br /&gt;\r\nMáy tính sử dụng RAM để lưu trữ mã chương trình và dữ liệu trong suốt quá trình thực thi.&lt;br /&gt;\r\n&lt;br /&gt;\r\n----------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\nBạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;RAM&lt;/a&gt;)&lt;br&gt;
&lt;br&gt;
Kết quả hoàn toàn ngược lại như mình dự đoán. Mình đoán rằng Interface sẽ chậm hơn vì phải qua &lt;b&gt;boxing&lt;/b&gt;
(nếu bạn chưa biết hiện tượng boxing/unboxing thì rất nên tìm đọc về
chuyện này, major performance hit đấy). Trong khi đó, abstract và
virtual không phải qua boxing, không phải qua context checking, lẽ ra
phải nhanh hơn, nhưng ngược lại thì lại chậm hơn interface thấy rõ.
Ngoài ra, cũng cùng 1 benchmark nếu compile trong .NET 2.0 thì nhanh
hơn .NET 1.1 một tẹo.&lt;br&gt;
&lt;br&gt;
Mình rất bất ngờ, đã cố gắng kiếm tài liệu xem như thế nào. Nhưng chưa
tìm ra nên đành tạm giải thích rằng Interface cũng như type reflection
là một trong những công cụ nền tảng của .NET nên đã được optimize rất
kỹ. (Đúng là reflection chậm, nhưng type reflection nhanh cực kỳ đấy,
.NET dùng quá nhiều type reflection mà). Hy vọng bữa nào rảnh rảnh mình
sẽ xem cái emitted IL code xem .NET compiler đã optimize cho Interface
như thế nào.&lt;br&gt;
&lt;br&gt;
Đây là benchmark code, bạn cứ copy, paste để tự mình test lấy:&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 498px; text-align: left;"&gt;using System;&lt;br&gt;&lt;br&gt;namespace AbstractVsInterface&lt;br&gt;{&lt;br&gt;	class Program&lt;br&gt;	{		&lt;br&gt;		static void Main(string[] args)&lt;br&gt;		{&lt;br&gt;			int tmp;&lt;br&gt;			DateTime StartTime;&lt;br&gt;			DateTime EndTime;&lt;br&gt;			TimeSpan Duration;&lt;br&gt;			int Iteration = 1000000000;&lt;br&gt;&lt;br&gt;			Console.WriteLine("In same assembly, same namespace");&lt;br&gt;&lt;br&gt;			#region Benchmark Method calling - virtual class&lt;br&gt;			VirtualDog vdog = new VirtualDog();&lt;br&gt;			StartTime = DateTime.Now;&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				vdog.Roar();&lt;br&gt;			}&lt;br&gt;			EndTime = DateTime.Now;&lt;br&gt;			Duration = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			Console.WriteLine(string.Format("Method calling ({0:#,###} times) - virtual: {1} ms", Iteration, Duration.TotalMilliseconds));&lt;br&gt;			#endregion&lt;br&gt;&lt;br&gt;			#region Benchmark Method calling - abstract class&lt;br&gt;			Dog dog = new Dog();&lt;br&gt;			StartTime = DateTime.Now;&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				dog.Roar();&lt;br&gt;			}&lt;br&gt;			EndTime = DateTime.Now;&lt;br&gt;			Duration = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			Console.WriteLine(string.Format("Method calling ({0:#,###} times) - Abstract: {1} ms", Iteration, Duration.TotalMilliseconds));&lt;br&gt;			#endregion&lt;br&gt;&lt;br&gt;			#region Benchmark method calling - interface&lt;br&gt;			Cat cat = new Cat();&lt;br&gt;			StartTime = DateTime.Now;&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				cat.Roar();&lt;br&gt;			}&lt;br&gt;			EndTime = DateTime.Now;&lt;br&gt;			Duration = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			Console.WriteLine(string.Format("Method calling ({0:#,###} times) - Interface: {1} ms", Iteration, Duration.TotalMilliseconds));&lt;br&gt;			#endregion&lt;br&gt;&lt;br&gt;			Console.WriteLine();&lt;br&gt;			&lt;br&gt;			#region Benchmark Property accessing - virtual&lt;br&gt;			StartTime = DateTime.Now;&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				tmp = vdog.NumberOfLegs;&lt;br&gt;			}&lt;br&gt;			EndTime = DateTime.Now;&lt;br&gt;			Duration = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			Console.WriteLine(string.Format("Property accessing ({0:#,###} times) - Virtual: {1} ms", Iteration, Duration.TotalMilliseconds));&lt;br&gt;			#endregion&lt;br&gt;		&lt;br&gt;			#region Benchmark Property accessing - abstract&lt;br&gt;			StartTime = DateTime.Now;&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				tmp = dog.NumberOfLegs;&lt;br&gt;			}&lt;br&gt;			EndTime = DateTime.Now;&lt;br&gt;			Duration = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			Console.WriteLine(string.Format("Property accessing ({0:#,###} times) - Abstract: {1} ms", Iteration, Duration.TotalMilliseconds));&lt;br&gt;			#endregion&lt;br&gt;&lt;br&gt;			#region Benchmark Property accessing - interface&lt;br&gt;			StartTime = DateTime.Now;&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				tmp = cat.NumberOfLegs;&lt;br&gt;			}&lt;br&gt;			EndTime = DateTime.Now;&lt;br&gt;			Duration = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			Console.WriteLine(string.Format("Property accessing ({0:#,###} times) - Interface: {1} ms", Iteration, Duration.TotalMilliseconds));&lt;br&gt;			#endregion&lt;br&gt;&lt;br&gt;			Console.ReadLine();&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		#region Virtual class&lt;br&gt;		public class VirtualAnimalBase&lt;br&gt;		{&lt;br&gt;			public virtual void Roar() { }&lt;br&gt;&lt;br&gt;			public virtual int NumberOfLegs &lt;br&gt;			{&lt;br&gt;				get { return 4; }&lt;br&gt;				set { }&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		public class VirtualDog : VirtualAnimalBase&lt;br&gt;		{&lt;br&gt;			public override void Roar()&lt;br&gt;			{&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			public override int NumberOfLegs&lt;br&gt;			{&lt;br&gt;				get { return 4; }&lt;br&gt;				set { throw new Exception("Huh? A dog with more than 4 legs?"); }&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;		#endregion&lt;br&gt;&lt;br&gt;		#region Abstract class&lt;br&gt;		public abstract class AnimalBase&lt;br&gt;		{&lt;br&gt;			public abstract void Roar();&lt;br&gt;&lt;br&gt;			public abstract int NumberOfLegs { get;set;}&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		public class Dog : AnimalBase&lt;br&gt;		{&lt;br&gt;			public override void Roar()&lt;br&gt;			{&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			public override int NumberOfLegs&lt;br&gt;			{&lt;br&gt;				get { return 4; }&lt;br&gt;				set { throw new Exception("Huh? A dog with more than 4 legs?"); }&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;		#endregion&lt;br&gt;&lt;br&gt;		#region Interface&lt;br&gt;		public interface ICanRoar&lt;br&gt;		{&lt;br&gt;			void Roar();&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		public interface IHasLegs&lt;br&gt;		{&lt;br&gt;			int NumberOfLegs { get;set;}&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		public class Cat : ICanRoar, IHasLegs&lt;br&gt;		{&lt;br&gt;			public void Roar()&lt;br&gt;			{&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			public int NumberOfLegs&lt;br&gt;			{&lt;br&gt;				get { return 4; }&lt;br&gt;				set { throw new Exception("Sorry you meanie, I don't wanna change my little cat's DNA"); }&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;		#endregion&lt;br&gt;	}&lt;br&gt;}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
		&lt;!-- / message --&gt;&lt;!-- controls --&gt; &lt;b&gt;@Bazen:&lt;/b&gt;&lt;br&gt;
  Ý của mình là trong môi trường distributed application (web, client-server, vv) thì nên có interface riêng. Client và  &lt;a href="http://www.ddth.com/autolink.php?id=5&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;DigiPower Co., Ltd.&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nWEB HOSTING IN VIETNAM DATACENTER&lt;br /&gt;\r\nShared hosting, VPS, Dedicated Server, Co-location, Domain Name, Web Design, Email Server, Media Server, Game Server etc.&lt;br /&gt;\r\n&lt;br /&gt;\r\nVui lòng xem &lt;a href=\"http://www.digipower.vn\" target=_blank&gt;http://www.digipower.vn&lt;/a&gt; để biết thêm chi tiết.", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;Server&lt;/a&gt; chỉ nói chuyện qua interface, còn  &lt;a href="http://www.ddth.com/autolink.php?id=5&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;DigiPower Co., Ltd.&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nWEB HOSTING IN VIETNAM DATACENTER&lt;br /&gt;\r\nShared hosting, VPS, Dedicated Server, Co-location, Domain Name, Web Design, Email Server, Media Server, Game Server etc.&lt;br /&gt;\r\n&lt;br /&gt;\r\nVui lòng xem &lt;a href=\"http://www.digipower.vn\" target=_blank&gt;http://www.digipower.vn&lt;/a&gt; để biết thêm chi tiết.", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;Server&lt;/a&gt;
sẽ giữ implementation code riêng không cho phép client được rờ mó gì vô
ráo trọi. Mô hình này bạn sẽ gặp rất nhiều trong
service-oriented-programming. Đại khái là càng đưa ít code cho clients
càng tốt. Với lại clients đâu có cần biết nhiều, chỉ cần biết nó dùng
"service" gì để thực hiện 1 công việc, thế là đủ. Interface chính xác
là 1 contract, giữa người mua và kẻ bán chỉ "tiền trao cháo múc", người
nhận tiền, kẻ nhận hàng, không cần quan tâm đến chuyện gì khác.&lt;br&gt;
&lt;br&gt;
Ngoài ra, interface được dùng nhiều để lập trình theo mô hình module (plug-in, snap-in, vv). Tức là phần  &lt;a href="http://www.ddth.com/autolink.php?id=1&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;DigiPower Co., Ltd.&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nWEB HOSTING IN VIETNAM DATACENTER&lt;br /&gt;\r\nShared hosting, VPS, Dedicated Server, Co-location, Domain Name, Web Design, Email Server, Media Server, Game Server etc.&lt;br /&gt;\r\n&lt;br /&gt;\r\nVui lòng xem &lt;a href=\"http://www.digipower.vn\" target=_blank&gt;http://www.digipower.vn&lt;/a&gt; để biết thêm chi tiết.", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;host&lt;/a&gt;
không quan tâm tới chuyện cái plug-in của mình tròn méo ra làm sao,
miễn là plug-in đó thỏa điều kiện IPlugin nào đó. Một ví dụ khác là bản
thân .NET đấy, bạn viết ngôn ngữ C#, J#, VB.NET chi chi cũng được. Bản
thân .NET FX đâu thèm quan tâm, miễn là code của bạn thỏa ICompiler để
biên dịch ra ngôn ngữ chung IL là chạy được tất.&lt;br&gt;
&lt;br&gt; Cỏn abstraction dùng để cung cấp features cho những lớp kế thừa.
Lấy ví dụ hôm nay tui định nghĩa con vật gồm 4 chân, biết kêu. Mai mốt
tui định nghĩa thêm con vật có răng, biết cắn thì tất cả các con vật kế
thừa (chó, gà, heo, vịt, ...) đều ngay lập tức được thừa hưởng đặc tính
mới này.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;@Contrarin:&lt;/b&gt;&lt;br&gt;
Performance of Java versus C#:&lt;br&gt;
kẻ tám lạng, người nửa cân. Bạn cứ việc tìm trên mạng sẽ tha hồ thấy
nhiều benchmark, scientific study, commercial research về so sánh giữa
Java và C# (hay .NET). Nói ngắn gọn lại thì tùy mỗi lúc mỗi khác à. Có
cái thì Java nhanh, viết code ít. Có cái thì C# hay hơn.&lt;br&gt;
&lt;br&gt;
Bữa hổm mình đọc 1 bài viết ca ngợi Java, nói C# chạy chậm rùa bò, chậm
hơn đến 20-30 lần làm mình tức quá, chép cái code của hắn về chạy lại.
Kết quả: y chang nhau :-) (có lẽ hắn xài .NET 1.0, còn mình dùng 2.0.5)&lt;br&gt;
&lt;br&gt;
Có người nói Java chạy chậm trong win, chạy nhanh trong embedded, còn .NET thì ngược lại. Vân vân và vân vân.&lt;br&gt;
&lt;br&gt;
Theo mình thì .NET mới ra đời, còn Java ra lâu rồi. Mấy cái benchmark
đó đều là benchmark giữa 1 chàng thanh niên và 1 cậu bé, làm sao mà so
sánh đây? Nói .NET chậm ư? Thế thì đừng dùng .NET 1.1 nữa mà nhảy lên
whidbey nhé, xem coi có còn chậm nữa không? Nhanh rùng rợn đấy, chả kém
java đâu. Đó là còn chưa kể đến 3rd-party optimization nữa (cho value
type, cho generics), họ còn tuyên bố làm cho whidbey chạy nhanh hơn vài
lần nữa kìa.&lt;br&gt;
&lt;br&gt;
Nói tóm lại thì chuyện performance chỉ là marketing-hype. Quan trọng là
optimization ra làm sao. Nếu .NET hoặc Java có chỗ nào đó chưa nhanh
thì chính bạn phải optimize lấy, nếu không thì đợi phiên bản kế tiếp.&lt;br&gt;
&lt;br&gt;
Về chuyện &lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				Em nghĩ C# chính là Java-on-.NET nên những issue của .NET có thể áp dụng trên Java được
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt; thì mình chưa rõ ý của bạn lắm.&lt;br&gt;
Java-on-.NET thì đã có J#&lt;br&gt;
&lt;br&gt;
"issue của .NET"? Issues nào vậy bạn? Mình chỉ thấy là C# nói riêng và .NET nói chung = C + Delphi + Java + 20% innovation.&lt;br&gt;
Nếu bạn nói về tốc độ và architecture thì bạn hãy đợi Whidbey + Avalon
+ Indigo. Hai cái Longhorn pillars đó cũng dễ sợ đấy, mấy thứ đó được
design ngay từ đầu để đối mặt với Java, hay chính xác hơn là những hạn
chế trong software development nói chung. Như có lần mình đã nói, mình
chẳng tâng bốc Microsoft đâu, nhưng mình phải chấp nhận là Microsoft có
rất nhiều tiền, đủ để mua architects về để cạnh tranh mà. Mình thấy rất
thú vị khi ngay bản thân những technology mới của Microsoft rất... quen
thuộc. Từ cả tên cho tới architecture design. Mới thì có mới nhưng vẫn
cứ là thiên hạ có gì hay thì chôm lại, phát triển thêm rồi gắn mác MS$.
Nhưng có gì lạ đâu, ai chả thế&lt;br&gt;&lt;br&gt;1. Bạn đã thực hiện bao nhiêu lần thí nghiệm này??? Nếu bạn mới chỉ thí
nghiệm một lần thì cần thí nghiệm nhiều lần nữa mới có thể kết luận
được. Vì môi trường chúng ta đang dùng là môi trường đa nhiệm, không
thể kết luận chắc chắn là trong lúc bạn đang bấm giờ lại không có một
"Process" của Window đang tranh giành &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt;. Ví dụ lúc bạn chạy Interfacing thì  &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt; đang rỗi, nhưng lúc bạn chạy Abstraction thì  &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt; có nhu cầu xử lý một process khác.&lt;br&gt;
&lt;br&gt;
2. Trước đây mình nghĩ là Interfacing chỉ có ý nghĩa về mặt thiết kế và
lập trình, còn Khi đã dịch thì phương thức có trong lớp (được chỉ ra
trong Interfacing) cũng giống như mọi phương thức khác. Vì vậy cũng
không có căn cứ để kết luận cái nào chạy nhanh hơn: abstraction hay
interfacing.&lt;br&gt;
&lt;br&gt;
3. Ý kiến thứ 2 của mình là suy nghĩ khi thực hiện trên một máy đơn, còn trong ứng dụng phân tán thì không biết.&lt;br&gt;&lt;br&gt;&lt;b&gt;@mt333:&lt;/b&gt;&lt;br&gt;
1/ Vâng thưa bạn mình biết một tí về GC và Multi-threading cho nên
trước khi benchmark đã chọn release mode (best optimized), tắt hết các
chương trình khác (most &lt;a href="http://www.ddth.com/autolink.php?id=19&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Random Access Memory&lt;/b&gt; - RAM là một loại &lt;b&gt;bộ nhớ&lt;/b&gt; máy tính, nội dung của nó có thể được truy cập theo bất kỳ thứ tự nào.   &lt;br /&gt;\r\n&lt;br /&gt;\r\nMáy tính sử dụng RAM để lưu trữ mã chương trình và dữ liệu trong suốt quá trình thực thi.&lt;br /&gt;\r\n&lt;br /&gt;\r\n----------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\nBạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;RAM&lt;/a&gt;
available), chọn số lần iteration là 1 tỉ iteration cho mỗi benchmark,
không sử dụng Thread.Sleep, không sử dụng Timers, thậm chí không có bất
kỳ processing code nào hết (=&amp;gt; GC và memory management là irrelevant
hoặc insignificant).&lt;br&gt; Tất nhiên, quan trọng nhất là mình phải test
đi test lại để xem kết quả có đồng nhất không. Thậm chí mình còn đi xa
hơn một bước là test cùng 1 code cho 2 &lt;a href="http://www.ddth.com/autolink.php?id=27&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Khuyến mãi đặc biệt nhân dịp năm mới 2007&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nKhi mua trọn bộ máy tính ở Trần Anh, bạn sẽ được tặng: 01 máy in Canon IP-1200 + 01 phần mềm Antivirus Bitdefender có bản quyền + 01 Áo T-Shirt Tiger + 01 Mũ Tiger và nhiều quà tặng...&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;a href=\"http://www.trananh.vn/NewsDetail.Asp?Id=149\" target=_blank&gt;Xem chi tiết tại đây&lt;/a&gt;", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;máy tính&lt;/a&gt; khác nhau: 1  &lt;a href="http://www.ddth.com/autolink.php?id=17&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Advanced Micro Devices, Inc.&lt;/b&gt; (AMD) là nhà sản xuất CPU x86 lớn thứ hai thế giới sau Intel và là một trong những nhà sản xuất bộ nhớ flash hàng đầu trên thế giới; ngoài ra AMD còn sản xuất chipset và các linh kiện điện tử bán dẫn khác.&lt;br /&gt;\r\n&lt;br /&gt;\r\n-------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\nBạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;AMD&lt;/a&gt;, 1 Intel platform.&lt;br&gt;
  Kết quả benchmark tuy gây ngạc nhiên nhưng mình cảm thấy vẫn hợp lệ.&lt;br&gt;
&lt;br&gt;
2/ Về lý thuyết thì interface và abstraction đều như nhau (tất cả chỉ
là method pointer, thậm chí giống luôn cả direct method call). Sự khác
nhau nảy sinh trong .NET là context bound, boxing/unboxing, và code
access security. Do đó sẽ dẫn đến optimization khác nhau.&lt;br&gt;
Nếu bạn nghi ngờ, hãy chạy test trên dưới chế độ debug mode bạn sẽ thấy
kết quả y như nhau, không có cái nảo nhanh hơn cái nào.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;@Bazen:&lt;/b&gt;&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				&lt;div&gt;
					Được gửi bởi &lt;strong&gt;bazen&lt;/strong&gt;
					
				&lt;/div&gt;
				&lt;div style="font-style: italic;"&gt;Anh bienca101 đo tốc độ như thế nào vậy, anh chỉ em cách đo được ko? Dùng hàm hay tools vậy anh ?&lt;/div&gt;
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Bazen ạ, đo tốc độ thì có khá nhiều cách:&lt;br&gt;
1/Profiler: dùng 3rd-party profiler hoặc System.Diagnostic sẽ có ích trong việc tweak performance của toàn bộ chương trình.&lt;br&gt;
&lt;br&gt;
2/Đối với benchmarking, làm như thế không ổn mà cần phải cặp "que dò"
ngay tại chỗ phát sinh code gần nhất. Càng gần processing code càng
tốt. Trong .NET không có timer chính xác sẵn cho bạn. Hoặc bạn dùng
cách đo bằng TimeSpan như trong code ví dụ của mình đấy:&lt;br&gt;
  &lt;b&gt;TimeSpan ts = new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;/b&gt;&lt;br&gt;
&lt;br&gt;
Cách trên lợi dụng tính chất của type DateTime là thực chất nó chỉ là
longint không hơn không kém (mỗi giá trị là 1 "tick"). Một tick này
hoàn toàn chả ăn nhập gì với core &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt; "tick" cả, do đó nó kém chính xác là ở chỗ đó. (nhưng vẫn còn ăn đứt cái Timer)&lt;br&gt;
&lt;br&gt;
Cách chính xác hơn là phải dùng đến WinAPI, gồm 2 hàm
QueryPerformanceCounter và QueryPerformanceFrequency. Hai hàm này cung
cấp thời gian theo xung nhịp của &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt; nên độ chính xác rất cao. Thường là best-choice-timer cho game.&lt;br&gt;
&lt;br&gt;
Nếu bạn muốn chính xác tuyệt đối thì bạn phải mua 1 mạch đồng hồ nguyên tử. Mình chỉ nghe kể là  &lt;a href="http://www.ddth.com/autolink.php?id=27&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Khuyến mãi đặc biệt nhân dịp năm mới 2007&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nKhi mua trọn bộ máy tính ở Trần Anh, bạn sẽ được tặng: 01 máy in Canon IP-1200 + 01 phần mềm Antivirus Bitdefender có bản quyền + 01 Áo T-Shirt Tiger + 01 Mũ Tiger và nhiều quà tặng...&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;a href=\"http://www.trananh.vn/NewsDetail.Asp?Id=149\" target=_blank&gt;Xem chi tiết tại đây&lt;/a&gt;", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;máy tính&lt;/a&gt; quân sự thì có cái này thôi chớ cũng chưa được rớ tới bao giờ&lt;br&gt;&lt;br&gt;theo mình biết 1 "ticks" mà bạn nói đúng là chả liên quan đến  &lt;a href="http://www.ddth.com/autolink.php?id=21&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;Central Processing Unit&lt;/b&gt; - CPU, tạm dịch là đơn vị xử lí trung tâm. Nhiệm vụ chính của CPU là xử lý các chương trình vi tính và dữ kiện.&lt;br /&gt;\r\n&lt;br /&gt;\r\n--------------------&lt;br /&gt;\r\n&lt;br /&gt;\r\n&lt;b&gt;Bạn muốn quảng cáo trên từ khóa này ?&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nHãy liên hệ &lt;b&gt;0903.69.69.92&lt;/b&gt; hoặc email &lt;a href=&lt;\"mailto:ads@vikhoa.com\"&gt;ads@vikhoa.com&lt;/a&gt; để biết thêm chi tiết.&lt;br /&gt;\r\n&lt;br /&gt;\r\nYahoo ID: vikhoa141", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;CPU&lt;/a&gt;,
mà là phụ thuộc vào OS (Hệ điều hành). Một "tick" của WinXP không nhớ
rõ là bao nhiêu hình như &amp;gt;= 7ms hay 5ms. Vì thế, nếu ai dùng
Thread.Sleep(x) (x&amp;lt;7) thì sẽ chả có tác dụng.&lt;br&gt;&lt;br&gt;&lt;div id="post_message_427269"&gt;Không phải là không có đâu. Có tác dụng đấy nhưng do ngắn ngủi quá nên bạn không cảm nhận thấy đó thôi.&lt;br&gt;
&lt;br&gt;
Để minh chứng, bạn chạy thử cái test này đi. Mình cho lặp đi lặp lại 10.000 lần Thread.Sleep(1).&lt;br&gt;
Expected time = 10.000 x 1ms = 10.000ms&lt;br&gt;
Actual elapsed time = 19.654ms&lt;br&gt;
&lt;br&gt;
Khác biệt thấy rõ đấy. Điều này chẳng có gì lạ bởi vì overhead cho cái ThreadPool trong .NET tốn kém quá mà.&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 274px; text-align: left;"&gt;int Iteration = 10000;&lt;br&gt;			Console.WriteLine("Start - Please wait about 10 seconds");&lt;br&gt;			DateTime StartTime;&lt;br&gt;			DateTime EndTime;&lt;br&gt;			TimeSpan elapsed = new TimeSpan();&lt;br&gt;			for (int i = 0; i &amp;lt; Iteration; i++)&lt;br&gt;			{&lt;br&gt;				StartTime = DateTime.Now;&lt;br&gt;				System.Threading.Thread.Sleep(1);&lt;br&gt;				EndTime = DateTime.Now;&lt;br&gt;				elapsed += new TimeSpan(EndTime.Ticks - StartTime.Ticks);&lt;br&gt;			}&lt;br&gt;			Console.WriteLine("Stop");&lt;br&gt;&lt;br&gt;			Console.WriteLine(string.Format("Elapsed time: {0:#,###}ms - Expected: {1:#,###}ms", elapsed.TotalMilliseconds, Iteration));&lt;br&gt;			Console.ReadLine();&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
		&lt;!-- / message --&gt;
	
		
		
		
		
		
		
		
		
		
		&lt;!-- edit note --&gt;
						&lt;hr style="color: rgb(252, 252, 252);" size="1"&gt;&lt;b&gt;1/Abstract:&lt;/b&gt;&lt;br&gt;
Abstract là 1 công cụ cơ bản của lập trình hướng đối tượng. Nó bổ sung
cho chức năng inheritance (kế thừa). Lớp kế thừa được thừa hưởng những
đặc tính và chức năng của lớp cha. Khi những đặc tính và chức năng đó
của cha chưa được biết trước thì người ta dùng abstraction.&lt;br&gt;
&lt;br&gt;
Ví dụ:&lt;br&gt;
- Định nghĩa con vật thì phải có chân, số chân bi nhiêu thì chưa biết trước.&lt;br&gt;
- Con mèo kế thừa từ con vật, vậy con mèo cũng có chân.&lt;br&gt;
- Con vịt cũng là con vật, con vịt có chân.&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 226px; text-align: left;"&gt;public class Animal&lt;br&gt;	{&lt;br&gt;		public bool HasLegs&lt;br&gt;		{ get { return true; } }&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public class Cat: Animal&lt;br&gt;	{&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public class Duck : Animal&lt;br&gt;	{&lt;br&gt;	}&lt;/pre&gt;
&lt;/div&gt;Nhờ kế thừa nên cả Duck lẫn Cat không cần viết dòng code nào vẫn
nghiễm nhiên được thừa hưởng thuộc tính HasLegs. Tuy nhiên, con vịt có
2 chân, con mèo có bốn chân. Vậy làm sao mình đếm được số chân của 1
con vật &lt;b&gt;bất kỳ&lt;/b&gt; nào đó? Mình sẽ dùng abstraction để sửa lại như sau:&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 402px; text-align: left;"&gt;public class Animal&lt;br&gt;	{&lt;br&gt;		public bool HasLegs&lt;br&gt;		{ get { return true; } }&lt;br&gt;&lt;br&gt;		public abstract int NumberOfLegs&lt;br&gt;		{ get;}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public class Cat: Animal&lt;br&gt;	{&lt;br&gt;		public override int NumberOfLegs&lt;br&gt;		{&lt;br&gt;			get { return 4; }&lt;br&gt;		}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	public class Duck : Animal&lt;br&gt;	{&lt;br&gt;		public override int NumberOfLegs&lt;br&gt;		{&lt;br&gt;			get { return 2; }&lt;br&gt;		}&lt;br&gt;	}&lt;/pre&gt;
&lt;/div&gt;Thật tiện lợi, phải không? Nhờ có abstract nên ngay từ lớp cha
(Animal) đã có thể định nghĩa được thuộc tính NumberOfLegs mà không
biết trước sẽ có bao nhiêu chân cả. Lớp kế thừa (Duck, Cat) sẽ có nhiệm
vụ trả lời chuyện này.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;2/Interface:&lt;/b&gt;&lt;br&gt;
&lt;br&gt;
Interface thực ra chính là abstraction nhưng cao cấp hơn abstract đơn
thuần như đã nói ở trên. Interface uyển chuyển hơn abstract rất nhiều
do đó nó gần như là lựa chọn số một khi bạn cần thiết kế mô hình có cấu
trúc mở.&lt;br&gt;
&lt;br&gt;
Ví dụ: mình biết con mèo, con vịt có thuộc tính trọng lượng. Mình lại
có những vật khác cũng lại có trọng lượng như cái bàn, cái ghế. Rõ ràng
2 nhóm đối tượng này tuy chung thuộc tính nhưng không kế thừa được,
cũng không abstract được vì chúng thuộc 2 nhóm khác nhau xa lắc xa lơ.
(không lẽ cái bàn lại kế thừa từ con vật?)&lt;br&gt;
&lt;br&gt;
Do đó, thay vì dùng abstract, mình dùng interface. Ví dụ trên chính là
đặc tính multiple-inheritance. (hay nói cho sang hơn, là poly-morphism)&lt;br&gt;
&lt;br&gt;
Nhưng chức năng đặc sắc nhất của interface lại là ở chỗ "required
contract". Ví dụ như Photoshop ấy. Hãng Adobe khi cho ra lò Photoshop
thì dành riêng 1 số plug-ins interface để mọi người có thể viết filters
cho Photoshop. Bản thân Adobe không hề biết trước khách hàng của mình
sẽ cần những gì. Nhờ có plug-ins, những lập trình viên khác, nắm bắt
được yêu cầu khách hàng tốt hơn, sẽ viết filters thêm cho Photoshop. Họ
cứ việc dựa vào interface sẵn có của Photoshop để viết. Nếu không nhờ
interface thì chuyện này sẽ không thể nào xảy ra, muốn có tính năng mới
thì bắt buộc phải viết Photoshop lại, bắt buộc phải compile lại.&lt;br&gt;&lt;br&gt;BẠn hãy thử với Thread.Sleep(5) thấy kết quả nó sẽ tưng tự Thread.Sleep(1).&lt;br&gt;&lt;br&gt;Bạn hãy xem kỹ về ThreadPool sẽ thấy là cái ThreadPool của .NET tự động
có khoảng chờ nho nhỏ trước khi thực hiện 1 WorkItem. Do đó nên
Thread.Sleep(5) sẽ tương tự như Thread.Sleep(1) là hoàn toàn hợp lý.&lt;br&gt;&lt;br&gt;Nhiều khi bạn sleep 5 hay 1 gì như nhau là do nhiều thứ. Bạn
đang chạy trên windows. Bạn có bảo đảm trong 1 thời gian chỉ có
mỗi thread của bạn chạy ko ?&lt;br&gt;
Tốt nhất, nếu muốn thử thì thử 2 thread cùng start nó mới chính xác dc.&lt;br&gt;&lt;br&gt;Mình chưa được rõ ý của bạn lắm Contrarin à.&lt;br&gt;
&lt;br&gt;
abstract = must override&lt;br&gt;
virtual    = overridable&lt;br&gt;
&lt;br&gt;
Do đó, trong C# nếu đã là abstract thì bắt buộc phải là virtual nốt.
Làm sao lại có non-virtual abstract (not-overridable but must override)
được?&lt;br&gt;
&lt;br&gt;
Nếu ý bạn muốn nói non-virtual là direct method call thì tất nhiên là nhanh rồi, khỏi cần thử.&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				&lt;div&gt;
					Được gửi bởi &lt;strong&gt;nowforever&lt;/strong&gt;
					
				&lt;/div&gt;
				&lt;div style="font-style: italic;"&gt;Nhiều
khi bạn sleep 5 hay 1 gì như nhau là do nhiều thứ. Bạn đang chạy
trên windows. Bạn có bảo đảm trong 1 thời gian chỉ có mỗi
thread của bạn chạy ko ?&lt;br&gt;
Tốt nhất, nếu muốn thử thì thử 2 thread cùng start nó mới chính xác dc.&lt;/div&gt;
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;&lt;b&gt;@Nowforever:&lt;/b&gt;&lt;br&gt;
&lt;br&gt; Theo mình biết thì không nên benchmark bằng threads. Lý do rất đơn
giản là mỗi thread sẽ được cấp timeslice hoàn toàn khác nhau. Dù cùng
priority đi chăng nữa thì threads vẫn không được cấp ngang nhau. Có lúc
1, có lúc 2,3 rồi mới đến thread khác. Đó là còn chưa kể đến chuyện cái
ThreadPool có cơ chế tự động đợi trước khi thực hiện 1 workitem cho nên
chuyện benchmark bằng cách cho nhiều threads chạy song song là hết sức
khó thực hiện cho chính xác.&lt;br&gt;&lt;br&gt;Bản thân interface không phải là multiple-inheritance lẫn poly-morphism nhưng có phần nào mang tính chất đó &lt;br&gt;&lt;br&gt;&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/Abstract_and_interface/1.viePortal</guid>
<pubDate>Sat, 23 Aug 2008 20:40:46 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>nơi đóng góp và chia sẽ giải pháp cho nhau</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/noi_dong_gop_va_chia_se_giai_phap_cho_nhau/</link>
<description>trong một ứng dụng web SMS khi đồng thời lượng Connect đến Server tăng đột biến thì giải pháp đưa ra ở đây như thế nào(ứng dụng sử dụng sql Server2k5) nào chúng ta cùng nhau đóng góp cho 4room thêm sôi động đi các cao thủ&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/noi_dong_gop_va_chia_se_giai_phap_cho_nhau/1.viePortal</guid>
<pubDate>Wed, 13 Aug 2008 17:49:13 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>xay dung dong co thu thap tu dong bao dien tu</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/xay_dung_dong_co_thu_thap_tu_dong_bao_dien_tu/</link>
<description>Co ai biet cach tim kiem ngu nghia trong mot trang web khong chi cho minh di</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/xay_dung_dong_co_thu_thap_tu_dong_bao_dien_tu/1.viePortal</guid>
<pubDate>Sat, 14 Jun 2008 21:45:11 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Tại sao template nước ngoài lại đẹp không rườm rà như Việt Nam</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Tai_sao_template_nuoc_ngoai_lai_dep_khong_ruom_ra_nhu_Viet_Nam/</link>
<description>&lt;strong style="font-family: Tahoma;"&gt;Những từ viết tắt sử dụng trong bài viết:&lt;/strong&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;i style="font-family: Tahoma;"&gt;&lt;strong&gt;Web nước ngoài&lt;/strong&gt;: Những trang Web phối hợp hài hoà yếu tố thẩm mỹ và tính tiện dụng&lt;br&gt;&lt;strong&gt;Web Việt Nam&lt;/strong&gt;: Những trang Web Việt Nam nói chung không đáp ứng việc phối hợp hài hoà&lt;/i&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Trước
khi phân tích Web nước ngoài và Web Việt Nam, mời các bác dạo với em
một vòng để tìm hiểu về trục thiết kế trong thiết kế Web trước đã nhé.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Mục
đích của thiết kế giao diện Web là định hướng giao tiếp. Có thể hiểu
giàu tính thẩm mỹ là một chức năng của cái đẹp, của sự cuốn hút, của
cảm xúc sâu và sự ảnh hưởng thị giác.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Sự phong phú của chức năng có thể hiểu là tính tiện ích, là tổng hợp của dễ sử dụng và tính ứng dụng của các chức năng.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;strong style="font-family: Tahoma;"&gt;&lt;span style="font-size: 11pt;"&gt;I. Thiết kế Web là thiết kế sản phẩm trên trục thẩm mỹ và chức năng&lt;/span&gt;&lt;/strong&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;" class="aligncenter"&gt;&lt;span style="font-size: 11pt;" class="img"&gt;&lt;img alt="" src="http://files.myopera.com/iguru/blog/Aesthetic-Function.jpg"&gt;&lt;/span&gt;&lt;br&gt;&lt;i&gt;Hình minh hoạ 1: Trục thiết kế&lt;/i&gt;&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Vùng
màu vàng là phạm vi mà một sản phẩm có thể hoạt động. Tất cả các sản
phẩm đều nằm đâu đó bên trong các đường biên của hình cầu. Mô hình thể
hiện các khía cạnh quan trọng của thiết kế và hướng giải quyết vấn đề
trong sự ràng buộc của sáng tạo.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Mô hình này chỉ ứng dụng khi
đối tượng là sản phẩm thị giác và có yếu tố truyền thông; không áp dụng
cho mỹ thuật công nghiệp hoặc máy móc.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Sản phẩm có yêu cầu hiệu
ứng thị giác cao và đẹp sẽ có vị trí cao nhất trên trục Giàu tính thẩm
mỹ. Càng đề cao vẻ đẹp và chất lượng thẩm mỹ thì càng giảm hiệu năng sử
dụng. Một thiết kế không đẹp, rườm rà có vị trí thấp trong trục này.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Một
thiết kế sản phẩm đem lại tính tiện dụng cao sẽ có trị trí cao nhất
trong trục Phong phú chức năng. Phong phú chức năng là tổng hợp của:&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;ul style="font-family: Tahoma;" class="bullets"&gt;&lt;li&gt;Thông tin trong truyền thông thị giác dễ hiểu và rõ ràng&lt;br&gt;  &lt;/li&gt;&lt;li&gt;Cung cấp nhiều cách nhập thông tin hiệu quả&lt;br&gt;  &lt;/li&gt;&lt;li&gt;Cung cấp nhiều công cụ giúp dễ dàng thực hiện các chức năng phức tạp&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Một sản phẩm đẹp, phong phú các chức năng và dễ sử dụng nó nằm ở đâu đó điểm (3)&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Một sản phẩm xấu xí và sử dụng khó khăn nằm gần gốc toạ độ&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Một sản phẩm sử dụng được nhưng có giao diện xấu thì nằm ở điểm (1) và ngược lại thì nó nằm tại điểm (6)&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;strong style="font-family: Tahoma;"&gt;&lt;span style="font-size: 11pt;"&gt;II. Trục thiết kế có ý nghĩa gì?&lt;/span&gt;&lt;/strong&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;ol style="font-family: Tahoma;"&gt;&lt;li&gt;Đây
là mối giao hoà tự nhiên giữa sự phong phú chức năng và giàu tính thẩm
mỹ. Bạn không thể vừa có một sản phẩm có trình ứng dụng chức năng cao
cấp và giao diện thiết kế tuyệt vời. Nếu có thì sản phẩm này nằm ngoài
hình cầu của thiết kế. Lý do là nếu sản phẩm có tính thẩm mỹ cao và
cuốn hút nhất thì bạn sẽ dừng làm việc và ngắm nhìn chúng; trong khi
những sản phẩm có chức năng hiệu quả nhất thì giúp bạn thực hiện tốt
công việc của bạn mà không phải lưu tâm việc ngắm nghía chúng. Không
thể xảy ra cả hai.&lt;br&gt;  &lt;/li&gt;&lt;li&gt;Giao diện thiết kế là một cuộc đối
thoại hai chiều giữa ý đồ thiết kế và người dùng. Ý đồ thiết kế giao
tiếp và người truy nhập tương tác lẫn nhau thông qua ngôn ngữ của thiết
kế, ở đây là tính thẩm mỹ và chức năng.&lt;br&gt;a. Hầu hết những Web site có
chức năng tốt đều phong phú thông tin, tải nhanh và sử dụng thuận tiện.
Chúng tập trung vào chức năng nhưng nếu muốn cuốn hút, ấn tượng người
dùng thì hiệu suất sử dụng lại phải thoả hiệp.&lt;br&gt;b. Những thiết kế đẹp
nhất - luôn khiến bạn dừng lại và ngắm nhìn, chúng giàu tính biểu đạt.
Nếu muốn có tính hữu dụng cao, họ không thể tăng tỉ trọng các chức năng
cao cấp vào.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Những giao diện thiết kế có tính ứng dụng cao
đều cần thẩm mỹ cao. Những thiết kế tiện dụng, hay sử dụng ( chẳng hạn
các hướng dẫn lắp đặt đồ gia dụng, chỉ dẫn kỹ thuật, biểu mẫu và báo
cáo) đem lại hiệu quả cao nhất khi chúng phối hợp các yếu tố thẩm mỹ
như tính cân bằng, màu sắc và độ tương phản.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Những giao
diện có tính thẩm mỹ cao cũng cần hoà trộn với tính tiện dụng. Nếu sản
phẩm không có khả năng sử dụng, nó chỉ đơn thuần là nghệ thuật không
phải thiết kế. Xa hơn một Web site, những sản phẩm đẹp nhất sẽ chỉ thu
hút sự chú ý của con người khi nó có thể sử dụng.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Vị trí lý
tưởng cho một sản phẩm nằm ở đường biên giữa vị trí (3) (chỉ toàn chức
năng) và (chỉ có vẻ đẹp). Một sản phẩm trí tuệ là sự phối hợp của việc
ngắm và làm việc.&lt;br&gt;Có thể gọi đây là một tiêu chuẩn mới dựa trên sự
cân bằng của tính thẩm mỹ và chất lượng chức năng. Điều cơ bản và cũng
quan trọng nhất của một thiết kế viên là luôn có ý đồ rõ ràng khi thiết
kế sản phẩm và sản phẩm thiết kế phải nằm trên phạm vi này. &lt;/li&gt;&lt;/ol&gt; &lt;br style="font-family: Tahoma;"&gt;&lt;ul style="font-family: Tahoma;" class="bullets"&gt;&lt;li&gt;Một
site mà mục đích chính là phục vụ công việc người dùng và có nhiều chức
năng chẳng hạn thuế, kế toán, tài chính ngân hàng nên nằm phía Bắc của
giao điểm.&lt;br&gt;  &lt;/li&gt;&lt;li&gt;Một site phục vụ các mục đích như quảng bá thương hiệu, giải trí, cuộc sống nên nằm phía Đông của giao điểm.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Khi
thiết kế các sản phẩm có chức năng truyền thông, thiết kế tiện dụng là
đơn giản và cũng là tốt nhất. Tính tiện dụng là yếu tố chính để thiết
kế thành công.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Hầu hết các thiết kế viên đều nghĩ sự đối nghịch
của thiết kế và tính tiện dụng cũng là sự đối nghịch của nghệ thuật đồ
hoạ và thiết kế; và đa số các cuộc tranh luận đều xoay quanh hai điểm
quan trọng của tính thẩm mỹ và chức năng (nhìn thay vì làm việc). Thiết
kế giao diện Web là nguyên tắc ứng dụng các kỹ thuật đồ hoạ, Web để
giải quyết vấn đề truyền thông; trong khi Nghệ thuật đồ hoạ là sử dụng
các kỹ năng tương tự dùng cho lợi ích của họ. Nghệ thuật có chỗ đứng
của nó và là một phần quan trọng của Web site tuy nhiên thành công của
Web site được đem lại hoàn toàn từ Thiết kế. Thiết kế là tìm kiếm những
giải pháp tốt nhất để giải quyết các vấn đề truyền thông. &lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Web
nên bao gồm cả sự cuốn hút thị giác và tính dễ sử dụng. Hai yếu tố này
không loại trừ lẫn nhau. Trong một số trường hợp thiết kế thành công
dựa trên sự cuốn hút thị giác. Hiệu ứng cuốn hút và đẹp có thể khiến
người sử dụng dừng chân trên Web lâu hơn hoặc khám phá sâu hơn, làm
tăng trải nghiệm cụ thể và tạo sự cuốn hút một sản phẩm để bán hàng.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Tuy
nhiên vấn đề thường phát sinh khi nghệ thuật đồ hoạ được sử dụng thay
thế cho thiết kế. Khi nghệ thuật đồ hoạ được ứng dụng để đạt các mục
tiêu của Web, hậu quả kinh tế thường khá nghiêm trọng. Thông thường
nguyên nhân của thiết kế không truyền thông hiệu quả là do tính thẩm mỹ
không đạt. Những điều xảy ra trong lĩnh vực web cũng đang xảy ra trong
các lĩnh vực truyền thông khác nhưng trong khoảng thời gian nhanh hơn. &lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Luôn
xảy ra áp lực sáng tạo giữa cách thiết kế mang tính thẩm mỹ và trách
nhiệm để sản xuất ra một sản phẩm phục vụ cho công việc. Và đây là vấn
đề chính của thiết kế Web.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Cùng với năng lực nhận thức, năng lực
ứng dụng chưa cao, nhiều Web Việt Nam mới chỉ dừng lại ở nghệ thuật đồ
hoạ hoặc công cụ. Điều này khiến cho Web Việt Nam trở nên hoặc rườm rà,
không khoa học hoặc khó sử dụng. Nhiều Web Việt Nam nằm tại gốc toạ độ
của trục Thẩm mỹ - Chức năng. (Xem hình minh hoạ 2)&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Chú ý rằng bạn
đang giao tiếp không phải thiết kế. Tất cả các yếu tố đơn lẻ và quyết
định phải giúp người sử dụng đạt được mục đích của họ và mục đích của
site.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Một vài ví dụ tại Việt Nam. Đây là các đánh giá độc lập của iGURU.&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;" class="aligncenter"&gt;&lt;span style="font-size: 11pt;" class="img"&gt;&lt;img alt="" src="http://files.myopera.com/iguru/blog/Aesthetic-Function1.jpg"&gt;&lt;/span&gt; &lt;br&gt; &lt;i&gt;Hình minh hoạ 2: Sắp xếp các Site trên trục thiết kế&lt;/i&gt;&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;strong style="font-family: Tahoma;"&gt;Các Website được đánh giá:&lt;/strong&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;1.www.mozilla.org&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;2.http://vi.wikipedia.org &lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;3.www.baamboo.com&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;4.www.vietnamworks.com&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;5.www.iguru.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;6.www.google.com.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;7.http://www.yahoo.com.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;8.www.cyworld.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;9.www.vietnamnet.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;10.www.templatesmonster.com&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;11.www.24h.com.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;12.www.firewheel.com&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;13.www.designchapel.com&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;14.www.chodientu.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;15.www.clip.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;16.www.vietspace.net.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;17.www.tamtay.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;18.www.cinet.gov.vn&lt;/span&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;strong style="font-family: Tahoma;"&gt;Câu hỏi mở rộng:&lt;/strong&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;ul style="font-family: Tahoma;" class="bullets"&gt;&lt;li&gt;Theo bạn, các Site Việt Nam nên đi theo hướng nào trong Thiết kế Web?&lt;br&gt;  &lt;/li&gt;&lt;li&gt;Vị trí biên nào phù hợp với site của bạn? Bạn cần yêu tố nào hơn: chức năng hay tính thẩm mỹ? Và tại sao?&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Tải phiên bản PDF: &lt;/span&gt;&lt;a style="font-family: Tahoma;" href="http://files.myopera.com/iguru/blog/TrucThietKeTrongThietKeWeb2008.10.04.pdf" target="_blank"&gt;http://files.myopera.com/iguru/blog/TrucThietKeTrongThietKeWeb2008.10.04.pdf&lt;/a&gt;&lt;br style="font-family: Tahoma;"&gt;&lt;span style="font-family: Tahoma; font-size: 11pt;"&gt;Traceback: &lt;/span&gt;&lt;a style="font-family: Tahoma;" href="http://my.opera.com/iguru/blog/web-template-iguru-ban-su-dung-trai-phep-nuoc-ngoai" target="_blank"&gt;http://my.opera.com/iguru/blog/web-template-iguru-ban-su-dung-trai-phep-nuoc-ngoai&lt;/a&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/Tai_sao_template_nuoc_ngoai_lai_dep_khong_ruom_ra_nhu_Viet_Nam/1.viePortal</guid>
<pubDate>Tue, 13 May 2008 22:21:37 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>định hướng lập trình game chơi qua Lan</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/dinh_huong_lap_trinh_game_choi_qua_Lan/</link>
<description>mình có đồ án làm game chơi qua mang mạng lan nhưng mình kô điịnh hướung được phải làm những công vịêc j, &lt;br&gt;nên xây dựng theo hướng nào, phải lập trình theo kiểu TCP/Ip hay UDP ???&lt;br&gt;nói chung mình mới đọc tài liệu mà ko hiểu lắm. mong các bạn đưa ra cách giải quyết vấn đề này giùm mình&lt;br&gt;cám ơn các bạn&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/dinh_huong_lap_trinh_game_choi_qua_Lan/1.viePortal</guid>
<pubDate>Tue, 06 May 2008 00:07:19 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Optimize</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Optimize/</link>
<description>Tui đọc dc cái này, thấy hay, post lên cho mọi người cùng xem&lt;br&gt;&lt;br&gt;Viết lại đoạn code sau để chạy nhanh hơn : )&lt;br&gt;
&lt;br&gt;
Lang: C#&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 274px; text-align: left;"&gt;int CountBit (bool[] bits)&lt;br&gt;{&lt;br&gt;   int total = 0;&lt;br&gt;&lt;br&gt;   for (int i = 0; i &amp;lt; bits.Length; i++)&lt;br&gt;   {&lt;br&gt;     if (bits[i])&lt;br&gt;     {&lt;br&gt;        total++;&lt;br&gt;     }&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   return total;&lt;br&gt;}&lt;/pre&gt;
&lt;/div&gt;Đây là kết quả benchmark tui thử nghiệm (bits chứa 1024 items, mỗi phương pháp test 10.000 iterations):&lt;br&gt;
&lt;br&gt;
Original     : 20,62 ms - CPU cycles per count: 4,31&lt;br&gt;
CountBit2  : 17,67 ms - CPU cycles per count: 3,69 - Improvement: 16,70%&lt;br&gt;
Unsafe       : 15,44 ms - CPU cycles per count: 3,22 - Improvement: 33,56%&lt;br&gt;
Ints            : 13,19 ms - CPU cycles per count: 2,75 - Improvement: 56,39%&lt;br&gt;
&lt;br&gt;
Lưu ý là benchmark chạy trên Xeon QuadCore CPU, với cpu ko phải Xeon hay Itanium thì kết quả có lẽ khác hẳn.&lt;br&gt;
&lt;br&gt;
Còn đây là code:&lt;br&gt;
&lt;br&gt;
&lt;b&gt;CountBit2:&lt;/b&gt; đưa biến total ra ngoài. Cách optimize này tùy trường hợp cụ thể mà có thể nhanh hơn, có thể chậm hơn.&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 258px; text-align: left;"&gt;        int total = 0;&lt;br&gt;        int CountBit2(bool[] bits)&lt;br&gt;        {&lt;br&gt;            total = 0;&lt;br&gt;&lt;br&gt;            for (int i = 0; i &amp;lt; bits.Length; i++)&lt;br&gt;            {&lt;br&gt;                if (bits[i])&lt;br&gt;                {&lt;br&gt;                    total++;&lt;br&gt;                }&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            return total;&lt;br&gt;        }&lt;/pre&gt;
&lt;/div&gt;&lt;b&gt;Unsafe:&lt;/b&gt;  Array là primitive structure có overhead cao nhất do có range checking, dùng unsafe pointer để tránh chuyện này.&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 306px; text-align: left;"&gt;        unsafe int UnsafeCount(bool[] bits)&lt;br&gt;        {&lt;br&gt;            int total = 0;&lt;br&gt;            int len = bits.Length;&lt;br&gt;&lt;br&gt;            fixed (bool* t = &amp;amp;bits[0])&lt;br&gt;            {&lt;br&gt;                bool* b = t;&lt;br&gt;&lt;br&gt;                for (int i = 0; i &amp;lt; bits.Length; i++)&lt;br&gt;                {&lt;br&gt;                    if (*b == true) total++;&lt;br&gt;                    b++;&lt;br&gt;                }&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            return total;&lt;br&gt;        }&lt;/pre&gt;
&lt;/div&gt;&lt;b&gt;Ints:&lt;/b&gt; thay vì dùng mảng bool[] thì dùng ints[]. Thường thì
optimization phụ thuộc rất nhiều vào cấu trúc dữ liệu. Trong trường hợp
này, thay vì lưu boolean thì lưu 0, 1 với int. (Chủ yếu để khỏi phải có
code branching ở đoạn if )&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 194px; text-align: left;"&gt;        int CountInt(int[] bits)&lt;br&gt;        {&lt;br&gt;            int total = 0;&lt;br&gt;&lt;br&gt;            for (int i = 0; i &amp;lt; bits.Length; i++)&lt;br&gt;            {&lt;br&gt;                total += bits[i];&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            return total;&lt;br&gt;        }&lt;/pre&gt;
&lt;/div&gt;Cái &lt;b&gt;Ints&lt;/b&gt; không hợp lệ rồi, không sửa input.&lt;br&gt;
&lt;br&gt;
Test bé quá, có 1024 items, đề nghị test với 32 * 1024 * 1024 items trở lên.&lt;br&gt;
&lt;br&gt;
Còn vài hướng optimize nữa mà ;; )&lt;font color="red"&gt;&lt;br&gt;
  &lt;/font&gt;&lt;br&gt;
&lt;b&gt;FasterCount1&lt;/b&gt;: bool của .NET thực tế là byte với giá trị 0, 1. Kết hợp với unsafe code loại bỏ range check, branch miss.&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 290px; text-align: left;"&gt;        static unsafe int FasterCount1 (bool[] bits)&lt;br&gt;        {&lt;br&gt;            int total = 0;&lt;br&gt;&lt;br&gt;            fixed (bool * boolPtr = bits)&lt;br&gt;            {&lt;br&gt;                byte* bytePtr = (byte*) boolPtr;&lt;br&gt;&lt;br&gt;                for (int i = 0; i &amp;lt; bits.Length; i++)&lt;br&gt;                {&lt;br&gt;                    total += *bytePtr;&lt;br&gt;                    bytePtr++;&lt;br&gt;                }&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            return total;&lt;br&gt;        }&lt;/pre&gt;
&lt;/div&gt;Test với 32 * 1024 * 1024 items&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 82px; text-align: left;"&gt;            for (int i = 0; i &amp;lt; bits.Length; i++)&lt;br&gt;            {&lt;br&gt;                bits [i] = i % 2 == 0;&lt;br&gt;            }&lt;/pre&gt;
&lt;/div&gt;Data này là worst-case của OrginalCount (CPU không đoán đúng được if rẽ đi đâu)&lt;br&gt;
&lt;br&gt;
FasterCount1 = 7.18x OrginalCount trong trường hợp này.&lt;br&gt;
&lt;br&gt;
Với test 10,000 iteration 1024 items.&lt;br&gt;
&lt;br&gt;
50% true: FasterCount1: 8.5ms, UnsafeCount: 30.9ms  --&gt; 3.63x &lt;br&gt;
10% true: FasterCount1: 8.5ms, UnsafeCount: 15.8ms  --&amp;gt; 1.85x&lt;font color="red"&gt;&lt;br&gt;
  &lt;/font&gt;&lt;br&gt;
&lt;b&gt;FasterCount2&lt;/b&gt; Tương tự như FasterCount1 nhưng thay vì xử lí từng byte thì xử lí theo từng block 4 byte (32 bit).&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 354px; text-align: left;"&gt;        static unsafe int FasterCount2(bool[] bits)&lt;br&gt;        {&lt;br&gt;            int total = 0;            &lt;br&gt;            int len = bits.Length/4;&lt;br&gt;&lt;br&gt;            fixed (bool* boolPtr = bits)&lt;br&gt;            {&lt;br&gt;                int* intPtr = (int*)boolPtr;                &lt;br&gt;&lt;br&gt;                for (int i = 0; i &amp;lt; len; i++)&lt;br&gt;                {&lt;br&gt;                    int x = * intPtr;&lt;br&gt;&lt;br&gt;                    total += (x &amp;amp; 1) + ((x &amp;amp; 256) &amp;gt;&amp;gt; 8) + ((x &amp;amp; 65536) &amp;gt;&amp;gt; 16) + ((x &amp;amp; 16777216) &amp;gt;&amp;gt; 24);&lt;br&gt;&lt;br&gt;                    intPtr++;&lt;br&gt;                }&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            return total;&lt;br&gt;        }&lt;/pre&gt;
&lt;/div&gt;FasterCount2 nhanh hơn FasterCount1 ~19% (1.19x)&lt;br&gt;&lt;br&gt;Chài, đã lén lén đưa unsafe vào tính ăn gian rồi, ai dè Zero còn ăn
gian đậm nữa, unsafe type casting luôn. Chưa nói tới chuyện người ta
dùng int[] thì kêu phạm quy, còn gian lận cast bool sang int thì lại
được. &lt;img src="http://ddth.com/images/smilies/biggrin.gif" alt="" title="Big Grin" class="inlineimg" border="0"&gt;&lt;br&gt;
&lt;br&gt;
Thôi, buồn ngủ nữa rồi, kệ. Để ăn no ngủ kỹ, đợi các hảo hán khác lên tỉ thí với Zero trước đã.&lt;br&gt;
&lt;br&gt;
T/B: Zero này, FasterCount2 cũng là dạng thường gặp. Nhưng ko biết sang
64bit CPU + 64bit OS, nếu mình dùng cách này (tăng thêm 4 op nữa thành
8 op) có nhanh hơn ko nhỉ? Về mặt lý thuyết thì có, nhưng tui chưa có
thử. (Lười quá, tối qua cũng có nghĩ tới cách gôm 4 op vô 1 iteration
như FasterCount2 nhưng buồn ngủ quá nên thui)&lt;br&gt;
&lt;br&gt;
Sẵn cũng hỏi nốt, tối qua tui cũng nghĩ tới chuyện với single-core CPU
thì đương nhiên mình optimize thế là nhanh. Nhưng nếu có multi-core và
lots of data, mình dùng threading thì performance có cao hơn ko nhỉ?
(Dạ, cũng lại là lười nốt, chưa thử, nên sẵn Zero đã đố thì biết đâu đã
test rồi, nên hỏi cho nhanh)&lt;br&gt;&lt;br&gt;&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				&lt;div&gt;
					Được gửi bởi &lt;strong&gt;bienca101&lt;/strong&gt;&amp;nbsp;
				&lt;/div&gt;
				&lt;div style="font-style: italic;"&gt;Chài,
đã lén lén đưa unsafe vào tính ăn gian rồi, ai dè Zero còn ăn gian đậm
nữa, unsafe type casting luôn. Chưa nói tới chuyện người ta dùng int[]
thì kêu phạm quy, còn gian lận cast bool sang int thì lại được. &lt;img src="http://ddth.com/images/smilies/biggrin.gif" alt="" title="Big Grin" class="inlineimg" border="0"&gt;&lt;/div&gt;
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Input không có bị sửa&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				&lt;div&gt;
					Được gửi bởi &lt;strong&gt;bienca101&lt;/strong&gt;&amp;nbsp;
				&lt;/div&gt;
				&lt;div style="font-style: italic;"&gt;T/B:
Zero này, FasterCount2 cũng là dạng thường gặp. Nhưng ko biết sang
64bit CPU + 64bit OS, nếu mình dùng cách này (tăng thêm 4 op nữa thành
8 op) có nhanh hơn ko nhỉ? Về mặt lý thuyết thì có, nhưng tui chưa có
thử. (Lười quá, tối qua cũng có nghĩ tới cách gôm 4 op vô 1 iteration
như FasterCount2 nhưng buồn ngủ quá nên thui)&lt;/div&gt;
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Em nghĩ là khó mà nhanh hơn được do các tính toán dạng này khá
đơn giản, chỉ 2-3 cycles/op. Bottle-neck sẽ là memory-access, 64 bit
cũng không giúp được. (L2, L3 lớn là chuyện khác &lt;img src="http://ddth.com/images/smilies/biggrin.gif" alt="" title="Big Grin" class="inlineimg" border="0"&gt;)&lt;br&gt;
&lt;br&gt;
&lt;i&gt;Thường khi optimize mọi người chỉ chú ý đến calculation chứ ít khi
optimize memory access - L2 cache miss có thể cost 100-150 CPU cycles.&lt;/i&gt;&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				&lt;div&gt;
					Được gửi bởi &lt;strong&gt;bienca101&lt;/strong&gt;&amp;nbsp;
				&lt;/div&gt;
				&lt;div style="font-style: italic;"&gt;Sẵn
cũng hỏi nốt, tối qua tui cũng nghĩ tới chuyện với single-core CPU thì
đương nhiên mình optimize thế là nhanh. Nhưng nếu có multi-core và lots
of data, mình dùng threading thì performance có cao hơn ko nhỉ?&lt;/div&gt;
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Multi-core: compiler tối ưu khá tốt cho cái này, nhất là mấy cái
loop, anh để ý Task Manager sẽ thấy là CPU bị đẩy lên 50-75%
(Quad-core) trong khi đúng ra max chỉ là 25% (single-thread).&lt;br&gt;
&lt;br&gt;
Còn trong trường hợp này: bottle neck ở memory.&lt;br&gt;
&lt;br&gt;
Với C++ hay native code có thể chạy nhanh hơn nữa nhờ memory prefetch -
hide cost của L2 miss, rất tiếc JIT, IL, C# ko có vụ này :|&lt;br&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/Optimize/1.viePortal</guid>
<pubDate>Fri, 25 Apr 2008 09:29:25 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Join hai DataTable lại với nhau!</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Join_hai_DataTable_lai_voi_nhau/</link>
<description>&lt;div class="smallfont"&gt;
				
				&lt;strong&gt;Join hai DataTable lại với nhau!&lt;/strong&gt;
			&lt;/div&gt;
			&lt;hr style="color: rgb(252, 252, 252);" size="1"&gt;
			&lt;!-- / icon and title --&gt;&lt;!-- message --&gt;
		
		
		
		Vì
có một số lý do nên tớ phải lấy dữ liệu từ hai Database khác
nhau lên hai DataTable, tất nhiên là hai table có thể kết nối
được với nhau.&lt;br&gt;
&lt;br&gt;
Tớ muốn xây dựng thuật toán "LEFT OUTER JOIN" hay "INNER JOIN" cho hai table này trên C#, có bạn nào biết không nhỉ?&lt;br&gt;Mình chưa hiểu rõ ý của bạn lắm. Có phải bạn có 2 table từ database(s)
đâu đó, không có mối liên hệ nào cả. Sau khi đã nạp vô .NET (dataset
của ADO.NET, maybe), thì bạn muốn tạo relationship cho 2 tables này
giống như là đã dùng Inner Join của SQL phải vậy không?&lt;br&gt;
&lt;br&gt;
Nếu bạn dùng dataset, xem cách dynamically add relationship của dataset. (Cứ google hoặc vô MSDN)&lt;br&gt;
&lt;br&gt;
Nếu bạn không dùng dataset mà đọc trực tiếp vào data collection nào đó
của bạn thì bạn phải làm bằng tay thôi. Lúc đó thì lại có nhiều vấn đề
để bàn lắm chẳng hạn như bạn muốn chạy nhanh hay muốn ít tốn bộ nhớ, có
muốn sau này bind vô một cái datagrid nào không. &lt;br&gt;
&lt;br&gt;
1/ Thuật toán dễ nhất, tốn bộ nhớ, cách mà SQL nói chung hay làm khi bạn dùng join là Product:&lt;br&gt;
&lt;br&gt;
Table 1:&lt;br&gt;
A&lt;br&gt;
B&lt;br&gt;
&lt;br&gt;
Table 2:&lt;br&gt;
1&lt;br&gt;
2&lt;br&gt;
&lt;br&gt;
Product của nó là mảng 2 chiều:&lt;br&gt;
array[,] = { (A,1), (A,2), (B,1), (B,2) }&lt;br&gt;
&lt;br&gt;
Khi đó, muốn lấy ra kết quả theo A chẳng hạn sẽ là: array[A, x]&lt;br&gt;
Còn muốn lấy theo 2 chẳng hạn thì sẽ là: array[x, 2]&lt;br&gt;
&lt;br&gt;
2/ Một cách khác ít tốn bộ nhớ hơn và nhanh tương đương: dùng Hashtable (Dictionary trong .NET 2.0)&lt;br&gt;
&lt;br&gt;
a/ Hash of hash: Hash(table 1, Hash (table 2))&lt;br&gt;
b/ Hash - List - Hash:&lt;br&gt;
    table 1: Hash (table 1, list(table 2 - ID))&lt;br&gt;
    table 2: Hash (table 2, list(table 1 - ID))&lt;br&gt;
&lt;br&gt;
Cách a chính là Left Outer Join đấy. Còn cách b thậm chí cho bạn M:N
relationship luôn. Nhìn sơ qua thì thấy cách b chiếm nhiều bộ nhớ hơn
phương pháp Product nhưng thực tế không phải vậy bởi vì HashTable chỉ
lưu reference pointer thôi.&lt;br&gt;&lt;br&gt;Bạn nói tớ cũng hiểu sơ sơ, hiện tại tớ không quan tâm nhiều
đến performance của nó, output của tớ chỉ cần return một
datatable là đủ, ý tớ muốn nói rằng vì hiện tại hai Table
không cùng nằm trên một Database nên tớ không thể SELECT các giá
trị trên hai bảng đấy bằng cách LEFT OUTER JOIN chúng nó (tớ
quan tâm đến LEFT OUTER JOIN hơn), do vậy tớ phải load hai table
đấy lên hai DataTable của C# và bắt buộc phải SELECT các giá
trị và LEFT OUTER JOIN trên đấy.&lt;br&gt;
&lt;br&gt;
Khổ nổi thằng Dataset trên C# không hỗ trợ câu lệnh SELECT như
trong Database, chỉ có thằng DataTable chỉ hỗ trợ câu lệnh
SELECT thôi. Do vậy bằng cách nào đấy tớ vẫn có thể lấy dữ
liệu trên hai DataTable như là lấy dữ liệu bằng câu lệnh SELECT
và LEFT OUTER JOIN hai table như trong Database.&lt;br&gt;
&lt;br&gt;
Ví dụ nhé:&lt;br&gt;
&lt;br&gt;
Giả sữ tớ đã load lên hai DataTable:&lt;br&gt;
&lt;br&gt;
Table1&lt;br&gt;
&lt;br&gt;
ObjectCode               Description&lt;br&gt;
...                           ...&lt;br&gt;
&lt;br&gt;
Table2&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
UserID                Name          Email&lt;br&gt;
...		...              ....&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Nếu hai table trong một Database thì quá dễ:&lt;br&gt;
&lt;br&gt;
SELECT ObjectCode, Description, Email &lt;br&gt;
FROM Table1 LEFT OUTER JOIN table2		&lt;br&gt;
ON Table1.ObjectCode = Table2.Name&lt;br&gt;
&lt;br&gt;
Bi giờ tớ muốn lấy dữ liệu trả về DataTable y như câu lệnh SELECT ở trên nhưng bằng code C#&lt;br&gt;&lt;br&gt;&lt;div id="post_message_410534"&gt;Mình không hiểu tại sao bạn lại phải khổ
công như thế, nếu bạn chỉ muốn filter records của một table thì dùng
dataview, nếu bạn muốn lấy records của 1 table dựa theo relationship
của nó với table khác thì dùng relation giống như bài viết này:&lt;br&gt;
&lt;a href="http://www.c-sharpcorner.com/database/DataRelationVK.asp" target="_blank"&gt;http://www.c-sharpcorner.com/databas...RelationVK.asp&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
Còn nếu bạn vẫn cứ "ngoan cố" khăng khăng đòi cho bằng được cái left
outer join đó bằng C# thì đây, mình làm cho bạn rồi nè. Bạn nợ mình 1
ly cafe đá vì cái "tội" làm mình mất đứt 45 phút. :-)&lt;br&gt;
&lt;br&gt;
Tóm tắt "quy trình công nghệ" như sau:&lt;br&gt;
- Tạo hashtable (để lookup cho lẹ) với key là join field ID của table 1&lt;br&gt;
- tạo table mới với tất cả columns của cả table 1 lẫn table 2&lt;br&gt;
- iterate toàn bộ rows trong table 2, chép dữ liệu sang table kết quả,
dùng hashtable để kiếm row tương ứng của table 1 và điền sang table kết
quả luôn.&lt;br&gt;
&lt;br&gt;
Cách làm này sẽ chậm hơn SQL join query nếu dữ liệu ít, còn nếu dữ liệu
nhiều thì tất nhiên sẽ nhanh hơn bởi vì SQL phải làm product join trước
khi left join.&lt;br&gt;
&lt;br&gt;
Source của class chính nằm dưới đây. Cho mình email nếu bạn muốn cả cái demo project nữa.&lt;br&gt;
&lt;br&gt;
(xin lỗi bác admin cho tui paste code ở đây nhá, bữa nay làm biếng quá nên post source ở đây luôn cho lẹ)&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 498px; text-align: left;"&gt;public class JoinTable&lt;br&gt;    {&lt;br&gt;        /// &amp;lt;summary&amp;gt;&lt;br&gt;        /// This method is similar to the following SQL query:&lt;br&gt;        /// &lt;br&gt;        /// SELECT *&lt;br&gt;        /// FROM T1 LEFT OUTER JOIN T2 &lt;br&gt;        /// ON T1.T1JoinField = T2.T2JoinField&lt;br&gt;        /// &amp;lt;/summary&amp;gt;&lt;br&gt;        public static DataTable LeftOuterJoin(DataTable T1, DataTable T2, string T1JoinField, string T2JoinField)&lt;br&gt;        {&lt;br&gt;            DataTable result = new DataTable();&lt;br&gt;&lt;br&gt;            //add all columns of T1 to result table&lt;br&gt;            for (int i=0; i&amp;lt; T1.Columns.Count; i++)            &lt;br&gt;            {&lt;br&gt;                DataColumn newcolumn = new DataColumn(T1.Columns[i].ColumnName, T1.Columns[i].DataType);&lt;br&gt;                result.Columns.Add(newcolumn);&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            //add all columns of T2 to result table&lt;br&gt;            for (int i = 0; i &amp;lt; T2.Columns.Count; i++)&lt;br&gt;            {&lt;br&gt;                DataColumn newcolumn = new DataColumn(T2.Columns[i].ColumnName, T2.Columns[i].DataType);&lt;br&gt;                result.Columns.Add(newcolumn);&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            //create a hash for lookup of T1, key is T1JoinField&lt;br&gt;            Hashtable T1hash = new Hashtable();&lt;br&gt;            DataColumn dc = T1.Columns[T1JoinField];&lt;br&gt;            for (int i=0; i&amp;lt; T1.Rows.Count; i++)&lt;br&gt;            {&lt;br&gt;                DataRow dr = T1.Rows[i];&lt;br&gt;                T1hash.Add(dr[dc], dr);&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            //iterate through all rows in T2, add to result table&lt;br&gt;            int MergedColumnCount = T1.Columns.Count + T2.Columns.Count;&lt;br&gt;            DataColumn dcLookup = T2.Columns[T2JoinField];&lt;br&gt;            for (int r = 0; r &amp;lt; T2.Rows.Count; r++)&lt;br&gt;            {&lt;br&gt;                DataRow dr = T2.Rows[r];&lt;br&gt;                object[] data = new object[MergedColumnCount];&lt;br&gt;&lt;br&gt;                //get lookup key&lt;br&gt;                object key = dr[dcLookup];&lt;br&gt;&lt;br&gt;                //copy values from T1 row    &lt;br&gt;                DataRow T1Row = (DataRow)T1hash[key];&lt;br&gt;                for (int i = 0; i &amp;lt; T1.Columns.Count; i++)&lt;br&gt;                {&lt;br&gt;                    data[i] = T1Row[i];&lt;br&gt;                }&lt;br&gt;&lt;br&gt;                //copy values from T2 row&lt;br&gt;                for (int i = 0; i &amp;lt; T2.Columns.Count; i++)&lt;br&gt;                {&lt;br&gt;                    data[i + T1.Columns.Count] = dr[i];&lt;br&gt;                }&lt;br&gt;&lt;br&gt;                //add new row to result table&lt;br&gt;                result.Rows.Add(data);&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            return result;&lt;br&gt;        }&lt;br&gt;    }&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
		&lt;!-- / message --&gt;
	
		
		
		
		
		
		
		
		
		
		&lt;!-- edit note --&gt;
			&lt;div class="smallfont"&gt;			&lt;hr style="color: rgb(252, 252, 252);" size="1"&gt;nhưng hình như "quy trình công nghệ" của bạn không mang tính LEFT
OUTER JOIN, vì trong trường hợp với một row trong T1 nó lại
không có các child rows của nó trong T2, với trường hợp này
chúng ta cũng phải nhét 1 row với các trường của T2 là null
vào trong bảng result và ngược lại với RIGHT OUTER JOIN, một row
trong T2 nó không có parent row trong T1.&lt;br&gt;
&lt;br&gt;
Bạn hãy nhìn vào đoạn code này:&lt;br&gt;
&lt;br&gt;
 //copy values from T1 row    &lt;br&gt;
                DataRow T1Row = (DataRow)T1hash[key];&lt;br&gt;
                for (int i = 0; i &amp;lt; T1.Columns.Count; i++)&lt;br&gt;
                {&lt;br&gt;
                    data[i] = T1Row[i];&lt;br&gt;
                }&lt;br&gt;
&lt;br&gt;
trong trường hợp T1Row trả về null thì sao ---&amp;gt; gần như chương trình sẽ báo lỗi, tớ thay đổi code một chút:&lt;br&gt;
&lt;br&gt;
 	DataRow T1Row = (DataRow)T1hash[key];&lt;br&gt;
	if (T1Row != null)&lt;br&gt;
	{&lt;br&gt;
		for (int i = 0; i &amp;lt; T1.Columns.Count; i++)&lt;br&gt;
               	 {&lt;br&gt;
                    		data[i] = T1Row[i];&lt;br&gt;
                	}&lt;br&gt;
	}&lt;br&gt;
&lt;br&gt;
có thể với code như vậy thì giải quyết được vấn đề INNER JOIN.&lt;br&gt;
&lt;br&gt;
Tớ cũng đã nghĩ ra cách giải quyết như thế này, nhưng chưa code:&lt;br&gt;
&lt;br&gt;
1. Add hai DataTable T1, T2 vào trong một DataSet, tạo DataRelation cho hai DataTable đó.&lt;br&gt;
2. Tạo bảng T3 có column là tất cả T1 và T2&lt;br&gt;
3. Iterate toàn bộ row trong T1 -&amp;gt; với mỗi row trong T1 lấy các childrows của nó trong T2&lt;br&gt;
&lt;br&gt;
4. Nếu childrows.Length &amp;gt; 0:&lt;br&gt;
	iterate các childrows, và add vào T3, với mỗi childrow lấy parentrow tương ứng với nó để add vào T3.&lt;br&gt;
&lt;br&gt;
5. Nếu childrows.Lenghth == 0:&lt;br&gt;
	add row trong T1 vào T3 với các trường của T2 là null.&lt;br&gt;
&lt;br&gt;
Nếu bỏ trường hợp 5 là bài toán INNER JOIN.&lt;br&gt;&lt;br&gt;Đúng vậy đấy bạn ạ. Mình có kiểm tra và phát hiện lỗi này khi viết code
cho bạn. Có điều mình nghĩ viết cái code trên để tóm tắt cách làm thôi
chứ không cần phải hoàn chỉnh hết cho bạn. Mình đang viết opensource
cho bạn mà, muốn customize hay finish thì ngoài ly cafe bạn phải trả
thêm tô hủ tiếu nữa cho phí consulting chứ &lt;img src="http://ddth.com/images/smilies/smile.gif" alt="" title="Smilie" class="inlineimg" border="0"&gt;&lt;br&gt;
&lt;br&gt;
Cái ý tưởng của bạn là đúng hướng rồi đấy. Có điều hình như bước 3 là
Right outer join chớ đâu phải Left nhỉ? Mình không chắc cho lắm. Mà
cũng chả sao, miễn ra kết quả bạn cần là được rồi.&lt;br&gt;
&lt;br&gt;
Mình thắc mắc tại sao bạn lại phải nhọc công thế nhỉ? Có phải vì bạn
muốn tạo table tạm thời cho reporting chăng? Mình mắc cái tật không
thích chơi với ADO.NET và CrystalReport cho nên cũng không thích SQL
nốt. Chương trình của bạn có Data Abstraction Layer không đó? Nếu có
thì không cần sql join chi vậy cho mệt đâu. Mình có 1 cái DAL
made-in-tự-tui không đến nỗi xuất sắc nhưng cũng khá hay. Ví dụ để
select table 2 với ID là SomeID1 chẳng hạn thì chỉ cần thế này:&lt;br&gt;
&lt;br&gt;
 SimpleCondition condition = Condition.Equal("ID", SomeID1);&lt;br&gt;
 objects = Database.Get(typeof(Table2), condition);&lt;br&gt;
&lt;br&gt;
Còn cái chuyện join khỏi cần là vì với object, mình hoàn toàn có thể làm vầy:&lt;br&gt;
 table2object.table1object.Description = "something";&lt;br&gt;
&lt;br&gt;
Tức là reference giữa object với object là chuyện đương nhiên, khỏi cần select với chả join.&lt;br&gt;
&lt;br&gt;
Các DAL khác cũng na ná như của mình vậy. (nếu bạn chưa tìm hiểu về DAL
thì có thể google các khái niệm: Objection-Relational database mapper,
Persistent framework layer)&lt;br&gt;&lt;br&gt;Về câu hỏi của bạn thì tùy:&lt;br&gt;
- tùy theo reporting engine nào (threaded hay không, có  &lt;a href="http://www.ddth.com/autolink.php?id=5&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;DigiPower Co., Ltd.&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nWEB HOSTING IN VIETNAM DATACENTER&lt;br /&gt;\r\nShared hosting, VPS, Dedicated Server, Co-location, Domain Name, Web Design, Email Server, Media Server, Game Server etc.&lt;br /&gt;\r\n&lt;br /&gt;\r\nVui lòng xem &lt;a href=\"http://www.digipower.vn\" target=_blank&gt;http://www.digipower.vn&lt;/a&gt; để biết thêm chi tiết.", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;server&lt;/a&gt; hay không, có cache hay không, vv)&lt;br&gt;
- tùy theo khả năng DBA của bạn (reporting engine lớn được đầu tư rất
nhiều để optimize data-load mà. Còn mình chắc gì đã bằng họ. Nhiều khi
thấy câu SQL query có 1, 2 dòng nghĩ là nhanh nhưng chưa chắc đã vậy).&lt;br&gt;
- tùy theo database engine và reporting engine nằm cách nhau bao xa. (remote or local)&lt;br&gt;
- tùy theo report engine và user interface cách nhau bao xa (thin, fat, hay smart client)&lt;br&gt;
- tùy theo chương trình của bạn cần scalable như thế nào, có bao nhiêu tier.&lt;br&gt;
&lt;br&gt;
Nói túm lại thì phải "trông trời trông đất trông mây, trông cho chân cứng đá mềm...." &lt;img src="http://ddth.com/images/smilies/smile.gif" alt="" title="Smilie" class="inlineimg" border="0"&gt;&lt;br&gt;
&lt;br&gt;
Mình nghĩ quan trọng nhất là project của bạn cần phải hoàn tất trong
bao lâu, budget bi nhiêu, sau này có cần sửa đổi nhiều hay không. Chớ
còn cái chuyện optimize giữa SQL và Reporting cái nào hơn thì khó nói
lắm bạn ạ. Bản thân professional DBA chưa chắc gì đã dám khẳng định cái
nào hơn.&lt;br&gt;
&lt;br&gt;
Tuy nhiên, không phải là đã &lt;a href="http://www.p%c3%b3tay.com/" target="_blank"&gt;www.pótay.com&lt;/a&gt;
. Nếu bạn có thời gian thì cứ benchmark hết tất cả mọi thứ là xong.
Benchmarking và profiling tốn nhiều thời gian lắm (vì thấy kết quả chậm
quá phải xóa hết đi viết lại). Tuy nhiên nó sẽ cho bạn nhiều kinh
nghiệm ngạc nhiên mà đến dân pro cũng chưa chắc đã biết.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;</description>
<author>automail-noreply@dot.net.vn</author>
<guid>http://dot.net.vn/Desktop.aspx/Threads/Solution/Join_hai_DataTable_lai_voi_nhau/1.viePortal</guid>
<pubDate>Thu, 20 Mar 2008 19:13:48 GMT</pubDate>
<source>http://dot.net.vn/Desktop.aspx/Threads/Solution/</source>
<category>Solution</category>
</item>
<item>
<title>Tree</title>
<link>http://dot.net.vn/Desktop.aspx/Threads/Solution/Tree/</link>
<description>&lt;div class="smallfont"&gt;
				
				&lt;strong&gt;Thuật toán Tree&lt;/strong&gt;
			&lt;/div&gt;
			&lt;hr style="color: rgb(252, 252, 252);" size="1"&gt;
			&lt;!-- / icon and title --&gt;&lt;!-- message --&gt;
		
		
		
		Tớ có một DB với 2 table như sau:&lt;br&gt;
&lt;br&gt;
Table: OBJECT, gồm 2 trường ObjectID, Name&lt;br&gt;
Table: HIERARCHY gồm hai trường ParentObjecID, ChildObjectID chứa quan hệ cha con giữa hai Object&lt;br&gt;
&lt;br&gt;
Tớ load DB lên memory dựa trên câu lệnh SQL như sau:&lt;br&gt;
&lt;br&gt;
SELECT H.ParentObjectID, O.ObjectID, O.Name&lt;br&gt;
FROM Hierarchy H INNER JOIN Object O&lt;br&gt;
ON (H.ChildObjectID = O.ObjectID)&lt;br&gt;
&lt;br&gt;
Bi giờ tớ muốn xây dựng một cây object như sau với một node thuộc interface sau:&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 114px; text-align: left;"&gt;interface ITreeNode&lt;br&gt;{&lt;br&gt;	ITreeNode 	ParentNode 	{ get; set; }&lt;br&gt;	string 		Name 		{get; set; }&lt;br&gt;	ArrayList		ChildNodes 	{ get; } 		&lt;br&gt;}&lt;/pre&gt;
&lt;/div&gt;(Note: ArrayList chủ yếu chứa đối tượng ITreeNode và không hạn chế số lượng node con của nó)&lt;br&gt;
&lt;br&gt;
Nếu là root: ParentNode = null;&lt;br&gt;
Nếu là leaf: ChildNodes = null;&lt;br&gt;
&lt;br&gt;
Bạn nào có cách giải hay cho bài toán này chỉ tớ với&lt;br&gt;&lt;br&gt;Theo mình thì thừa.Chỉ cần 1 table là đủ&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 66px; text-align: left;"&gt;Table Node&lt;br&gt;  ID&lt;br&gt;  ParentID&lt;/pre&gt;
&lt;/div&gt;Mối quan hệ kiểu tree là quan hệ 1:N (self-joined), đâu cần 2 tables và inner join cho phí phạm.&lt;br&gt;
&lt;br&gt;
Pseudo code để rebuild tree:&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 322px; text-align: left;"&gt;   //read from database&lt;br&gt;   objects = select * from table Object&lt;br&gt;&lt;br&gt;   //create lookup hash&lt;br&gt;   foreach (object obj in objects)&lt;br&gt;  {&lt;br&gt;         TreeNode node = new TreeNode(obj);&lt;br&gt;         hashtable.add(obj.ID, node);&lt;br&gt;  }&lt;br&gt;&lt;br&gt;  //rebuild tree&lt;br&gt;  foreach (Object obj in Objects)&lt;br&gt;  {&lt;br&gt;          if (obj.ParentID == null) //no parent =&amp;gt; add to root&lt;br&gt;              rootNode.ChildNodes.Add( hashtable[obj.ID] )&lt;br&gt;          else&lt;br&gt;             //has parent, add to parent's children nodes&lt;br&gt;            hashtable[obj.ID].ChildNodes.Add( hashtable[obj.ID] );&lt;br&gt;  }&lt;/pre&gt;
&lt;/div&gt;1 hay 2 tables thì cũng còn tùy. Có vài vấn đề cần nêu ra ở đây, vì bạn
Hatred không đưa ra requirements rõ rang, nên tôi chỉ đóan thôi:&lt;br&gt;
&lt;br&gt;
1/ Nếu đây là “toy project”, nghĩa là làm để chơi mà chẳng dùng cho công ty nào cả, thì 1 table đủ rồi.&lt;br&gt;
&lt;br&gt;
2/ Nếu đây là 1 project để dùng cho 1 công ty nào đó thật sự, thì 2
tables có nhiều lợi điểm hơn. Sau đây là những lợi điểm của 2 tables:&lt;br&gt;
&lt;br&gt;
Lợi điểm 1: Phân chia rõ ràng, 1 table dùng cho data (là “objects” của
bạn), table kia chứa relationships của objects trong table kia. Trong
tương lai, nếu bạn cần tạo ra 1 lọai relationship khác hẳn với current
relationship, mà vẫn muốn giữ current relationship (2 quan hệ song
song), thì chỉ cần tạo thêm 1 table thứ 3 để chứa relationship mới mà
không cần break hay đổi table thứ 2 (chứa current relationship). Nếu
bạn cần tạo ra 1 relationship thứ 3 mà vẫn muốn giữ 2 relationships
kia? Tạo ra 1 table thứ 4, thế là xong. &lt;br&gt;
&lt;br&gt;
Lợi điểm 2: Bạn không muốn tạo ra quan hệ mới, mà chỉ muốn “refresh”
lại hết tất cả những relationship trong database? Chỉ cần “refresh”
relationship table mà không cần thay dổi table chứa data (objects)&lt;br&gt;
&lt;br&gt;
Lợi điểm 3: Không có gì bảo đảm là trong tương lai object của bạn chỉ
có ID và Name, mà sẽ có thêm rất nhiều attributes trong dó. Nếu cả
object + object attributes + relationship đều nằm trong 1 table thì
sao? Chắc chắn bạn sẽ tốn rất nhiều thời gian để query cho 1 tree.&lt;br&gt;
&lt;br&gt;
3/ Nếu giải quyết như bienca, thì tòan database chỉ có 1 tree mà thôi.
Trong thực tế hầu như không có trừong hợp như vậy. Trong database của
bạn thông thường sẽ có nhiều root nodes, mỗi root node là gốc của 1
tree. &lt;br&gt;
&lt;br&gt;
Nếu xếp của bạn buồn buồn bảo rằng requirements đổi, bây giờ không chứa
trees mà chứa "forests". 1 forest là 1 set của trees mà có quan hệ dính
líu tới nhau, cho nên 1 forests có nhiều root nodes trong dó có liên hệ
lẫn nhau. &lt;br&gt;
&lt;br&gt;
Thông thường bạn sẽ phải có những queries như sau:&lt;br&gt;
&lt;br&gt;
Query 1: tìm 1 tree mà root node có tên là “ROOTA”&lt;br&gt;
&lt;br&gt;
Query 2: tìm 1 tree mà root node có tên có chữ “OT” trong đó. Những
root node có tên là “ROOTA”, “AOTIM”, “BOT” đều thỏa mãn query này. Dĩ
nhiên là bạn có thể đặt thêm điều kiện “bắt đầu bằng” hoặc “kết thúc
bằng”&lt;br&gt;
&lt;br&gt;
Query 3: tìm 1 tree mà root node có ID = xxx&lt;br&gt;
&lt;br&gt;
Query 4: tìm root node mà object name = “OBJ01” nằm trong tree của root
node đó, dĩ nhiên từ đó bạn có thể tìm duoc tòan bộ tree đó&lt;br&gt;
&lt;br&gt;
Có thể có vài queries khác, tùy theo requirements của project, chẳng
hạn, so sánh 2 trees theo 1 số điều kiện nào đó, hoặc đếm xem có bao
nhiêu trees “ngắn” hơn hay “dài” hơn tree hiện có, vân vân …&lt;br&gt;
&lt;br&gt;
Với khối lượng data lớn, để tránh nhiều “round trips” đi lại giữa program của bạn và database  &lt;a href="http://www.ddth.com/autolink.php?id=5&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;DigiPower Co., Ltd.&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nWEB HOSTING IN VIETNAM DATACENTER&lt;br /&gt;\r\nShared hosting, VPS, Dedicated Server, Co-location, Domain Name, Web Design, Email Server, Media Server, Game Server etc.&lt;br /&gt;\r\n&lt;br /&gt;\r\nVui lòng xem &lt;a href=\"http://www.digipower.vn\" target=_blank&gt;http://www.digipower.vn&lt;/a&gt; để biết thêm chi tiết.", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;server&lt;/a&gt;
trong khi đi tìm và xây dựng lại 1 tree, bạn nên tạo ra store procedure
để làm chuyện này, mọi queries để tạo tree đều run tren &lt;a href="http://www.ddth.com/autolink.php?id=5&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "&lt;b&gt;DigiPower Co., Ltd.&lt;/b&gt;&lt;br /&gt;\r\n&lt;br /&gt;\r\nWEB HOSTING IN VIETNAM DATACENTER&lt;br /&gt;\r\nShared hosting, VPS, Dedicated Server, Co-location, Domain Name, Web Design, Email Server, Media Server, Game Server etc.&lt;br /&gt;\r\n&lt;br /&gt;\r\nVui lòng xem &lt;a href=\"http://www.digipower.vn\" target=_blank&gt;http://www.digipower.vn&lt;/a&gt; để biết thêm chi tiết.", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;server&lt;/a&gt; thì không có vấn đề gì về performance (trừ khi bạn viet store procedure quá … tệ)&lt;br&gt;&lt;br&gt;Về chuyện&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
3/ Nếu giải quyết như bienca, thì tòan database chỉ có 1 tree mà thôi.
Trong thực tế hầu như không có trừong hợp như vậy. Trong database của
bạn thông thường sẽ có nhiều root nodes, mỗi root node là gốc của 1 t &lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Là do mình đoán hatred dùng TreeView trong winform nên mới đưa ra
code trên. Theo định nghĩa thì 1 tree bao giờ cũng có 1 root duy nhất,
cho dù root đó là implicit hay explicit. Còn graphs thì mới có rẽ nhánh
(multiple roots) thôi.&lt;br&gt;
&lt;br&gt;
Tiện thể nếu bạn có thể góp ý thêm cho mình cách thiết kế database cho 1  &lt;a href="http://www.ddth.com/autolink.php?id=24&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "Bạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;network&lt;/a&gt;
graph thì tốt biết mấy. Lấy ví dụ là có n thành phố, từ thành phố này
có thể đi đến m thành phố nào đó. Đây là dạng toán graph kinh điển (ví
dụ: tìm đường đi ngắn nhất trong bản đồ). Mình chỉ muốn hỏi riêng về
phần lưu relationships giữa các node như thế nào. Mình muốn ứng dụng
cho multi-dimension data array. Tuy có tìm hiểu một số thuật toán nhưng
chưa tìm được cái nào ưng ý cả. Hy vọng khi bạn rảnh rỗi có thể chỉ
thêm cho mình&lt;br&gt;&lt;br&gt;&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
Là do mình đoán hatred dùng TreeView trong winform nên mới đưa ra code
trên. Theo định nghĩa thì 1 tree bao giờ cũng có 1 root duy nhất, cho
dù root đó là implicit hay explicit. Còn graphs thì mới có rẽ nhánh
(multiple roots) thôi. &lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Dù là tree nhưng thông thường sẽ có nhiều trees trong database chứ không phải chỉ có 1 tree trong database&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				Tiện thể nếu bạn có thể góp ý thêm cho mình cách thiết kế database cho 1  &lt;a href="http://www.ddth.com/autolink.php?id=24&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "Bạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;network&lt;/a&gt;
graph thì tốt biết mấy. Lấy ví dụ là có n thành phố, từ thành phố này
có thể đi đến m thành phố nào đó. Đây là dạng toán graph kinh điển (ví
dụ: tìm đường đi ngắn nhất trong bản đồ). Mình chỉ muốn hỏi riêng về
phần lưu relationships giữa các node như thế nào. Mình muốn ứng dụng
cho multi-dimension data array. Tuy có tìm hiểu một số thuật toán nhưng
chưa tìm được cái nào ưng ý cả. Hy vọng khi bạn rảnh rỗi có thể chỉ
thêm cho mình &lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Graph có 2 dạng, directed graphs &amp;amp; undirected graphs. &lt;br&gt;
&lt;br&gt;
Trong trường hợp directed graph, ít nhất bạn cần có 2 tables, 1 chứa
data, 1 chứa relationships, không thể nhập chung được vì đây là n-n
relationship. Table chứa relationship có thể nói không phải ở dạng
parent-child nữa, mà là dạng from-to (thật ra cũng gần giống như vậy,
nhưng nếu gọi là parent-child relationship thì sẽ có lúc bạn có 1 node
là parent của 1 child node, child node là parent của another child
node, mà in turn child node thư" 2 này lại là parent của cái node đầu
tiên; hoặc là tệ hại hơn, parent có 1 child mà child đó lại là parent
của node ... parent, umm... hình như có hơi ... loạn luân &lt;img src="http://ddth.com/images/smilies/smile.gif" alt="" title="Smilie" class="inlineimg" border="0"&gt;)
Giữa 2 nodes A và B, nếu ta có 1 relationship from A to B, và 1
relationship khác from B to A, trong table chứa relationship bạn phải
có 2 entries khác nhau để chứa 2 relationship này giữa A và B.&lt;br&gt;
&lt;br&gt;
Trường hợp undirected graphs cũng gần giống như directed graphs, nhưng
khi nói A có liên hệ tới B thì cũng tương đương với nói B có liên hệ
tới A, có nghĩa là không phải "from-to" relationship nữa, mà là "has
relationship with", trong ví dụ A &amp;amp; B thì là "A has relationship
with B" mà cũng là "B has relationship with A", 2 câu này tương đương
nhau. Với sự liên hệ như vậy, để chứa relationship giữa A và B trong
table relationship, bạn có thể làm 2 cách khác nhau:&lt;br&gt;
&lt;br&gt;
Cách thứ 1: cho mỗi 1 relationship (chẳng hạn relationship giữa A và
B), bạn có 2 entries, 1 từ A - B, 2 từ B - A, tức là giống như trong
trường hợp của directed graph, nhưng tự động tạo 2 entries cho mỗi 1
relationship. Cách này bạn phải bảo đảm được là cho mỗi 1 relationship
phải có 2 entries trong table, còn không nếu chỉ có 1 (A-B hay B-A
only) thì là error. Cũng vậy, khi bạn delete 1 relationship giữa A và
B, bạn phải bảo đảm được 1 điều là cả 2 entries thể hiện relationship
đó phải bị deleted. Nhưng ngược lại khi chứa relationship kiểu này,
queries của bạn sẽ đơn giản hơn&lt;br&gt;
&lt;br&gt;
Cách thư" 2: cho mỗi 1 relationship, bạn chỉ có 1 entry trong table
relationship. Trong ví dụ A và B, nếu bạn dang work trên object A, muốn
thể hiện sự liên hệ giữa A và B, bạn insert into table relationship mối
quan hệ A-B. Còn nếu như bạn đang work on object B và muốn tồn trữ sự
liên hệ giữa B và A thì insert mối quan hệ B-A. Chú ý rằng 2 trường hợp
trên tương đương nhau, và cùng nói lên 1 điều là A có liên hệ tới B,
hay là B có liên hệ tới A, như nhau cả. Làm như cách này thì bạn không
cần phải bảo đảm 1 relationship có 2 entries giống như cách 1 và không
sợ bị thiếu sót, nhưng ngược lại khi queries sẽ phải vất vả hơn. Nói ví
dụ, bạn đang có object B, bạn muốn biết những relationships của B trong
database, mà table chứa relationship lại chỉ chứa A-B (không phải B-A),
bạn phải query cho cả 2 columns của table này xem có entry nào = B hay
không, chứ query 1st column không thì không đủ.&lt;br&gt;
&lt;br&gt;
Điều này đưa ra câu hỏi là, chọn cách nào? Thời buổi bây giờ thì
storage của database không còn là vấn đề nữa, nên disk space không còn
ảnh hưởng tới sự lựa chọn 1 entry hay 2 entries cho mỗi relationship
nữa. Vậy chỉ còn chọn lư.a dựa vào sự sử dụng của system thôi.&lt;br&gt;
&lt;br&gt;
Nếu trong system này, relationship thay dổi liên tục với frequency cao,
mà không có statistic report nhiều trên sự liên hệ giữa những object
với nhau, thì cách thứ 2 có lẽ dễ dàng hơn. Relationship thay đổi nhiều
thì sẽ có nhiều insertions &amp;amp; deletions, dĩ nhiên khi tạo hay xóa 1
entry cho mỗi relationship sẽ dễ dàng hơn là tạo hay xóa 2 entries cho
mỗi relationship. Mà system lại không cần statistic reports nhiều thì
không cần query nhiêu.&lt;br&gt;
&lt;br&gt;
Nếu ngược lại relationships giữa object không thay đổi nhiều sau khi đã
được tạo nên, mà lại có nhiều nhu cầu tạo report (statistic chẳng hạn),
bạn có thể giữ 2 entries cho mỗi relationship thì querying sẽ dễ dàng
hơn nhiều.&lt;br&gt;&lt;br&gt;Về chuyện tree thì mình có 3 lý do để bảo vệ cách của mình:&lt;br&gt; - Vẫn
cho phép multiple tree: đơn giản là root node không cần phải là null mà
sẽ có 1 ID riêng, có bao nhiêu tree thì sẽ có bấy nhiêu rootnode, thế
thôi. Như vậy thuật toán trên của mình vẫn hợp lệ, chỉ cần thay đổi
dòng &lt;b&gt;if (parent = null)&lt;/b&gt; thành &lt;b&gt;if (parent = root)&lt;/b&gt; (nếu không cứ giữ nguyên thế, multiple tree chẳng qua chỉ là multiple-branch thôi)&lt;br&gt;
&lt;br&gt; - Đành ràng database engine mạnh, nhưng multiple tree mà lưu vô
chỉ 2 tables là không nên. Mỗi một tree nên tách riêng ra. Ví dụ:
Customer, Employee, Vendors đều là tree được, đều có attributes na ná
nhau nhưng vẫn nên tách riêng chứ không nên gộp chung thành 1 (hoặc 2
tables như cách của bạn) duy nhất. Lý do: scalability. Coding thì nên
gộp chung, nhưng database thì không.&lt;br&gt;
&lt;br&gt; - Database chỉ nên để dành riêng cho việc persistent. Việc xử lý
relationship và rebuild tree nên dành riêng cho phần client code. Do
đó, khi design daatabase cần phải quan tâm ngay cả đến chuyện hạn chế
dùng joins.&lt;br&gt;
&lt;br&gt;
Tuy nhiên, mình hoàn toàn đồng ý với bạn về việc khi có nhiều kiểu
relationship thì nên để relationship trong table riêng, còn attributes
trong table riêng. Điều này rất chính xác.&lt;br&gt;
&lt;br&gt;
Túm lại, về chuyện tree thì mình không cãi nữa. Chuyện 1 hay 2 table đều có cái hay trong tùy trường hợp.&lt;br&gt;
&lt;br&gt;
Về chuyện graph, theo mình hiểu thì giải pháp của bạn chính là edge
detection. Đại khái là nodes nằm trong 1 table, còn relationship sẽ nằm
trong 1 table khác:&lt;br&gt;
&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt;
	&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 82px; text-align: left;"&gt;table Edge (relationship)&lt;br&gt;   ID NodeA&lt;br&gt;   ID NodeB&lt;br&gt;   other attributes&lt;/pre&gt;
&lt;/div&gt;Phương pháp này áp dụng cho bài toán tìm đường đi thì được, nhưng
áp dụng cho multi-dimension data array thì rất phiền bởi 2 vấn đề sau:&lt;br&gt;
- nhiều dữ liệu để save quá. Nội 1 relationship đã cần đến ít nhất: 2 IDs [+ attributes].&lt;br&gt;
- query chậm chạm, thậm chí có khi chưa biết query kiểu nào.&lt;br&gt;
&lt;br&gt;
Vấn đề multi-dimension data array mình đưa ra là 1 dạng bài toán  &lt;a href="http://www.ddth.com/autolink.php?id=24&amp;amp;script=showthread&amp;amp;forumid=76" target="_blank" class="gal" onmouseover='GAL_popup(this,"1", 300, "style=\"border: 1pt solid #000000;\"", "Bạn muốn quảng cáo tại đây? Xin liên hệ 0903.69.69.92", "style=\"background: #FFFFCC;padding: 2px;font-size: 10px;color: #4D528C;\"");' onmouseout="GAL_hidepopup();"&gt;network&lt;/a&gt;
graph nhưng phức tạp hơn tìm đường đi. Lấy ví dụ như thay vì lưu
customer, order, product dưới dạng tables trong relational database,
mình sẽ lưu hết dưới dạng objects. Thế thì làm sao để query trở ra 1
object thỏa điều kiện A, B, C nào đó? Trong báo cáo quản trị người ta
có khái niệm Pivot Table, cho phép slice-n-dice data. Đây là chức năng
rất hay. Nhưng Pivot Table chỉ là 1 trường hợp rất đặc biệt của
multi-dimension data (pivot table chỉ cho phép 3 dimension, còn
relational table chỉ cho phép 2 dimension).&lt;br&gt;
&lt;br&gt;
Bài toán multi-dimension data thú vị lắm, không chỉ cho báo cáo tài
chính mà còn nhiều ứng dụng khác. Ví dụ như bộ não con người ấy, mỗi
một neuron đều là 1 node trong hàng tỉ tỉ node. Khi cần lưu cái gì thì
các node sẽ tự tạo link nối kết nhau lại. Đơn giản chỉ có thế. Ấy thế
mà khi muốn query 1 object nào cũng được. Thậm chí khi không có đủ dữ
liệu thì có thể tự gầy dựng lại dữ liệu (ví dụ: nhớ tên 1 người bạn cũ
qua gương mặt).&lt;br&gt;
&lt;br&gt;
Mình đi kiếm thuật toán cho cái này cũng 1 năm rưỡi hơn mà vẫn còn đau
đầu đây. Thấy bạn trả lời rắn rỏi về tree nên mừng quá, "vồ" ngay lấy
để hỏi thêm về multi-dimension data ấy mà &lt;img src="http://ddth.com/images/smilies/biggrin.gif" alt="" title="Big Grin" class="inlineimg" border="0"&gt;&lt;br&gt;&lt;br&gt;Tôi thấy có nhiều điều không được rõ ràng cho lắm:&lt;br&gt;
&lt;div style="margin: 5px 20px 20px;"&gt;
	&lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Quote:&lt;/div&gt;
	&lt;table border="0" cellpadding="6" cellspacing="0" width="100%"&gt;
	&lt;tbody&gt;&lt;tr&gt;
		&lt;td class="alt2" style="border: 1px inset ;"&gt;
			
				Về chuyện tree thì mình có 3 lý do để bảo vệ cách của mình:&lt;br&gt;
- Vẫn cho phép multiple tree: đơn giản là root node không cần phải là
null mà sẽ có 1 ID riêng, có bao nhiêu tree thì sẽ có bấy nhiêu
rootnode, thế thôi. Như vậy thuật toán trên của mình vẫn hợp lệ, chỉ
cần thay đổi dòng if (parent = null) thành if (parent = root) (nếu
không cứ giữ nguyên thế, multiple tree chẳng qua chỉ là multiple-branch
thôi)&lt;br&gt;
&lt;br&gt;
- Đành ràng database engine mạnh, nhưng multiple tree mà lưu vô chỉ 2
tables là không nên. Mỗi một tree nên tách riêng ra. Ví dụ: Customer,
Employee, Vendors đều là tree được, đều có attributes na ná nhau nhưng
vẫn nên tách riêng chứ không nên gộp chung thành 1 (hoặc 2 tables như
cách của bạn) duy nhất. Lý do: scalability. Coding thì nên gộp chung,
nhưng database thì không.&lt;br&gt;
&lt;br&gt;
- Database chỉ nên để dành riêng cho việc persistent. Việc xử lý
relationship và rebuild tree nên dành riêng cho phần client code. Do
đó, khi design daatabase cần phải quan tâm ngay cả đến chuyện hạn chế
dùng joins.&lt;br&gt;
&lt;br&gt;
Tuy nhiên, mình hoàn toàn đồng ý với bạn về việc khi có nhiều kiểu
relationship thì nên để relationship trong table riêng, còn attributes
trong table riêng. Điều này rất chính xác.&lt;br&gt;
&lt;br&gt;
Túm lại, về chuyện tree thì mình không cãi nữa. Chuyện 1 hay 2 table đều có cái hay trong tùy trường hợp.
			
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;Nếu coi mỗI tree là 1 table như bienca nói, vậy cách đọc “select
* from table ___” và cách kiểm tra “if (parent = null)” đổI thành “if
(parent = root)” (must be “==” here) chẳng ăn nhập gì tới nhau cả. &lt;br&gt;
&lt;br&gt;
“nhưng multiple tree mà lưu vô chỉ 2 tables”: ít nhất 2 tables trở lên, không có nhất định là phảI 2 tables&lt;br&gt;
&lt;br&gt;
“Customer, Employee, Vendors đều là tree được”: Employees data còn có
thể nói là “1 tree”, nếu application chỉ cho 1 company mà không phảI là
nhiều companies. Nhưng Customers &amp;amp; Vendors thì không biết “tree”
thế nào?&lt;br&gt;
&lt;br&gt;
“Database chỉ nên để dành riêng cho việc persistent. Việc xử lý
relationship và rebuild tree nên dành riêng cho phần client code. Do
đó, khi design daatabase cần phải quan tâm ngay cả đến chuyện hạn chế
dùng joins.”: cái ý tưởng này cần phảI coi lạI, nếu design relational
database mà sợ joins thì tòan bộ database chỉ tóm gọn lạI trong 2-3
tables sao? Bienca có design large database với large volumn of data
bao giò chưa?&lt;br&gt;
&lt;br&gt;
Để tôi đưa ra 2 ví dụ nhé. Ví dụ 1: 1 application quản lý tòan bộ dân
số trong quận 5 tpHCM. Cho là có khỏang 500 ngàn người trong quận 5 đi,
vậy có khỏang 100 ngàn hộ nhân khẩu trong quận này (mỗI hộ trung bình 5
người). Trong application ta có thể coi 1 hộ nhân khẩu là 1 tree, mà
chủ hộ là root node, mỗi 1 ngườI trong hộ là 1 child node. Vậy trong
database có khỏang 100 ngàn trees. Nếu đọc data từ database theo kiểu
“select * from table ___” thì chẳng lẽ đọc hết 100 ngàn trees và 500
ngàn records vào trong memory sao? Đó là mới có 1 quận, bây giò nếu là
application để quản lý tòan bộ dân số của thanh phố thì sao?&lt;br&gt;
&lt;br&gt;
Ví dụ 2: bienca biet human genes chứ hả. Human body có khỏang trên
30-40 ngàn known genes, chưa kể những genes mà ta không biết. Thậm chí
có lab còn nói là human body có trên 100 ngàn genes, nhưng thôi, nói
30-40 trở lên là đủ rồI. Một gene có nhiều transcripts (mRNA) và có
nhiều proteins. Database của 1 công ty thử nghiệm về genes sẽ phảI chứa
được số lượng data này. MỗI 1 gene được coi là 1 data tree mà gene là
root node, transcripts và proteins là chid nodes, dĩ nhiên mỗI lọai
genes, transcripts &amp;amp; proteins nên nằm trong 1 table riêng rẽ (đây
là truong hợp mà tree tạo ra từ nhiều tables khác nhau). Vậy nộI trong
1 table chứa gene thôi là đã có 30-40 ngàn trees trở lên rồi. Nếu đọc 1
lượt hết bao nhiêu đó vô trong memory (“select * from table ___”) thì
sao? Đó là chưa kể những cong ty nghiên cứu về genes không phảI chỉ có
nghiên cứu đơn thuần về human genes, mà c