<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vietnamese Developers&#039; Blog</title>
	<atom:link href="http://www.openandfree.org/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.openandfree.org/blog</link>
	<description>There are 10 types of people in the world: Those who know the binary system and those who don&#039;t</description>
	<lastBuildDate>Fri, 14 Aug 2009 10:34:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Umask và quyền truy nhập file</title>
		<link>http://www.openandfree.org/blog/?p=91</link>
		<comments>http://www.openandfree.org/blog/?p=91#comments</comments>
		<pubDate>Fri, 14 Aug 2009 10:29:37 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Unix/Linux/BSD]]></category>
		<category><![CDATA[umask]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=91</guid>
		<description><![CDATA[Umask là gì?
Trong Unix, khi một file hay một thư mục được tạo ra thì quyền truy nhập đối với chúng (r, w, x) sẽ được xác định dựa trên hai giá trị là quyền truy nhập cơ sở (base permission) và mặt nạ (mask). Quyền truy nhập cơ sở là giá trị được thiết [...]]]></description>
			<content:encoded><![CDATA[<h4 id="toc-umask-la-gi" style="text-align: justify;">Umask là gì?</h4>
<p style="text-align: justify;">Trong Unix, khi một file hay một thư mục được tạo ra thì quyền truy nhập đối với chúng (r, w, x) sẽ được xác định dựa trên hai giá trị là quyền truy nhập cơ sở (base permission) và mặt nạ (mask). Quyền truy nhập cơ sở là giá trị được thiết lập sẵn từ trước, đối với file là 666 (rw-rw-rw) và thư mục là 777 (rwxrwxrwx). Mặt nạ là giá trị đựợc thiết lập bởi người dùng bằng lệnh umask. Giá trị mặt nạ sẽ “che đi” một số bit trong quyền truy nhập cơ sở để tạo ra quyền truy nhập chính thức cho file (tương tự như cơ chế của subnet mask).</p>
<p style="text-align: justify;">Cụ thể, quyền truy nhập chính thức được tính bằng cách lấy giá trị nhị phân của quyền truy nhập cơ sở AND với dạng biểu diễn bù 1 của mặt nạ. Ví dụ: Vì quyền truy nhập cơ sở của file là 666 (tức 110110110), nên nếu giá trị mask là 022 (000010010) thì quyền truy nhập chính thức của file sẽ là:</p>
<p style="text-align: justify;">110 110 110 AND 111 101 101 = 110 100 100 = 644 (rw-r&#8211;r&#8211;)</p>
<p style="text-align: justify;">Như vậy, các bit trong quyền truy nhập cơ sở ứng với các bit 1 của mask sẽ bị xóa. Cũng có thể tính quyền truy nhập chính thức đơn giản hơn bằng cách lấy 666 – 022 = 644.</p>
<h4 id="toc-gia-tr-mt-n-dc-thit-lp-nh-th-nao">Giá trị mặt nạ được thiết lập như thế nào?</h4>
<p style="text-align: justify;">Giá trị mask được thiết lập nhờ lệnh umask trên terminal hoặc bằng hàm hệ thống umask. Các file được tạo ra sau lệnh umask sẽ chịu tác động của giá trị mặt nạ mới.<span id="more-91"></span></p>
<p style="text-align: justify;">Cơ chế làm việc của umask khiến chúng ta không thể tạo ra các file với quyền executable mặc định.  Vì quyền truy nhập cơ sở của file là 666, tức các bit ứng với quyền executable đều bằng 0, nên bất kể giá trị mask bằng bao nhiêu thì quyền truy nhập chính thức của file đều không có executable. Chúng ta buộc phải cấp thêm quyền executable cho file sau khi chúng đã được tạo ra.</p>
<h4 id="toc-quyn-truy-nhp-file-va-mt-s-lnh-ph-bin">Quyền truy nhập file và một số lệnh phổ biến</h4>
<p style="text-align: justify;">- Lệnh cp: Khi được sao chép sang vị trí mới, quyền truy nhập của file được tính theo công thức trình bày ở trên với giá trị mask tại vị trí đích. Trong trường hợp trùng tên file thì quyền truy nhập của file ở vị trí đích sẽ được bảo lưu. Sử dụng tùy chọn –p để lấy quyền truy nhập của file nguồn</p>
<p style="text-align: justify;">- Lệnh tar: Khi giải nén các file, lệnh tar lấy quyền truy nhập của từng file làm quyền truy nhập cơ sở cho file đó.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=91</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agile: Tổ chức của một đội dự án XP</title>
		<link>http://www.openandfree.org/blog/?p=88</link>
		<comments>http://www.openandfree.org/blog/?p=88#comments</comments>
		<pubDate>Sat, 08 Aug 2009 22:55:35 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Công nghệ phần mềm]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[extreme programming]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=88</guid>
		<description><![CDATA[Nguồn: The Art of Agile Development by J Shore &#38; S Warden.
Phần tiếp theo của: Agile Development: Giới thiệu Extreme Programming
Một đội dự án XP làm việc cùng nhau trong một không gian mở không có các phòng riêng hoặc vách ngăn. Vào đầu mỗi vòng lặp, đội tổ chức một cuộc họp kéo dài [...]]]></description>
			<content:encoded><![CDATA[<p>Nguồn: <a href="http://jamesshore.com/Agile-Book/">The Art of Agile Developmen</a>t by J Shore &amp; S Warden.<br />
Phần tiếp theo của: <a href="http://www.openandfree.org/blog/?p=82">Agile Development: Giới thiệu Extreme Programming</a></p>
<p style="text-align: justify;">Một đội dự án XP làm việc cùng nhau trong một không gian mở không có các phòng riêng hoặc vách ngăn. Vào đầu mỗi vòng lặp, đội tổ chức một cuộc họp kéo dài từ 2 đến 4 giờ để tổng kết những công việc vừa hoàn thành và lập kế hoạch cho phần việc tiếp theo. Hàng ngày, cả đội tham gia một cuộc họp ngắn từ 5 đến 10 phút thảo luận về công việc trong ngày. Ngoài hai kiểu họp chính thức này, từng thành viên tự lập kế hoạch làm việc cho mình. Hình thức “tự tổ chức” (self-organization) là một đặc điểm chung của các dự án theo triết lí Agile.<br />
Trong một dự án phần mềm, những hiểu biết về sản phẩm luôn được nắm giữ bởi nhiều cá nhân. XP thừa nhận thực tế này bằng cách tạo ra một nhóm làm việc hỗn hợp với đầy đủ các vai trò cần thiết. Một đội dự án XP thường bao gồm các thành viên sau đây:<br />
<strong>Đại diện khách hàng (onsite customer)</strong>: Chịu trách nhiệm xác định các yêu cầu (requirement) cho phần mềm. Công việc quan trọng nhất của người này là lập kế hoạch. Khi bắt đầu dự án, đại diện khách hàng xác định các tính năng (feature/story) cần có của phần mềm, tìm cách nhóm các tính năng này thành các phần nhỏ có thể phát triển và bàn giao lần lượt và định ra lịch trình bàn giao từng phần. Trong quá trình thực hiện dự án, đại diện khách hàng nhận phản hồi từ các thành viên khác và điều chỉnh kế hoạch cho phù hợp.<br />
Nhiệm vụ thứ hai của đại diện khách hàng là giúp các lập trình viên hiểu các yêu cầu chi tiết cho sản phẩm. Trong các dự án XP, tài liệu đặc tả (SRS) chỉ là công cụ trợ giúp cho đại diện khách hàng mà thôi. Người này sẽ đóng vai trò một tài liệu “sống”, luôn sẵn sàng trả lời các câu hỏi từ các lập trình viên.<br />
Đại diện khách hàng không nhất thiết phải là khách hàng thật mà chỉ cần là một thành viên hiểu rõ các yêu cầu của phần mềm. Thực nghiệm cho thấy giữa hai nhóm có chất lượng lập trình viên tương đương nhau thì nhóm có sự tham gia của khách hàng tạo ra sản phẩm tốt hơn hẳn. Nếu khách hàng không thể đến ngồi ở văn phòng của bạn, hãy đưa đội dự án của bạn đến ngồi cùng với khách hàng!<br />
Thực nghiệm cũng cho thấy tỉ lệ hai đại diện khách hàng cho ba lập trình viên là phù hợp. Tất nhiên, tỉ lệ này phụ thuộc vào độ phức tạp của sản phẩm. Hãy ghi nhớ rằng khối lượng công việc của các đại diện khách hàng là rất lớn bởi họ luôn phải “chạy trước” các lập trình viên.<span id="more-88"></span><br />
<strong>Người quản lí sản phẩm (product manager/owner)</strong>: Người này chịu trách nhiệm định hướng cho dự án và sản phẩm, bao gồm các công việc: Xác định các tính năng của sản phẩm và thứ tự ưu tiên của chúng, hướng dẫn đại diện khách hàng, làm việc với các bên liên quan đến dự án (stakeholder), đánh giá tiến độ dự án và giải quyết các vấn đề về tổ chức. Ngoài ra, người quản lí sản phẩm còn chịu trách nhiệm đưa sản phầm ra thị trường, bao gồm các việc quảng cáo, bán hàng và hỗ trợ khách hàng.<br />
Người quản lí sản phầm phải am hiểu thị trường và các lợi ích mà phần mềm sẽ mang đến cho khách hàng. Đồng thời, người này phải có khả năng cộng tác và thoả hiệp với các đòi hỏi đa dạng, nhiều khi mâu thuẫn nhau, từ các cá nhân có quyền lợi liên quan đến dự án. Người quản lí sản phẩm phải được trao đủ quyền lực để có thể nói không với các yêu cầu không phù hợp. Một dự án chỉ nên có duy nhất một người quản lí sản phầm nhằm đảm bảo tính thống nhất cho định hướng của dự án.<br />
<strong>Các chuyên gia nghiệp vụ (Domain Expert)</strong>: Các lập trình viên ít khi hiểu biết tường tận về một lĩnh vực cụ thể nào đó, ví dụ như tài chính hay hoá học. Bởi vậy, XP yêu cầu sự tham gia của các chuyên gia hiểu rõ lĩnh vực chuyên môn của phần mềm đang được phát triển, chẳng hạn như các chuyên gia phân tích tài chính hay các nhà nghiên cứu hoá học. Những người này sẽ nghiên cứu nghiệp vụ của phần mềm để sẵn sàng trả lời câu hỏi của các lập trình viên.<br />
Trong các dự án nhỏ, người quản lí sản phẩm thường kiêm luôn vai trò chuyên gia nghiệp vụ.<br />
<strong>Người thiết kế giao diện (Interaction Designer)</strong>: Giao diện người dùng (user interface) là bộ mặt của sản phẩm. Người dùng thường đánh giá chất lượng phần mềm thông qua chất lượng giao diện mà họ tương tác hàng ngày. Nhiệm vụ của người thiết kế giao diện là tìm hiểu mong muốn của khách hàng cũng như thói quen làm việc thường ngày của họ và từ đó thiết kế bộ mặt của sản phẩm.<br />
Đừng nhầm lẫn giữa người thiết kế giao diện và người thiết kế đồ họa (graphic designer). Người thiết kế giao diện nghiên cứu tương tác giữa người dùng và sản phẩm. Trong khi đó người thiết kế đồ họa tạo ra các thành phần cụ thể như âm thanh, hình ảnh hay cách bố trí giao diện (layout).<br />
<strong>Lập trình viên (Programmer)</strong>: Nếu nhiệm vụ của người đại diện khách hàng là tối đa hóa giá trị của sản phẩm thì nhiệm vụ của các lập trình viên là tối thiểu hóa chi phí  bằng việc lập trình theo cách hiệu quả nhất. Nhiệm vụ của các lập trình viên trong dự án XP là:<br />
Ước lượng thời gian và nguồn lực cần thiết để thực hiện các chức năng của phần mềm, từ đó trợ giúp đại diện khách hàng trong việc lập kế hoạch. Lập trình viên cũng trao đổi trực tiếp với đại diện khách hàng để làm rõ các yêu cầu của phần mềm.<br />
Các lập trình viên làm việc theo cặp (pair programming) và sử dụng phương pháp phát triển dựa trên test (test-driven development). Mỗi lập trình viên có trách nhiệm viết test, viết và tối ưu hóa mã nguồn, thiết kế và liên tục cải tiến thiết kế của chương trình. Mã nguồn được xem là sở hữu tập thể, tất cả các lập trình viên đều có quyền và nghĩa vụ sửa các lỗi mà họ phát hiện ra, bất kể lỗi đó do ai gây ra. Chuẩn lập trình (coding standard) đóng vai trò thiết yếu hỗ trợ cho cách làm việc này. Các lập trình viên liên tục tích hợp mã nguồn vào hệ thống và test một cách cẩn thận nhằm đảo bảo rằng phần mềm đủ tiêu chuẩn để  đóng gói và bàn giao cho khách hàng vào cuối mỗi chu kì phát triển. Các lập trình viên chỉ viết tài liệu khi cần thiết nhằm trợ giúp cho việc bảo trì phần mềm trong tương lai.<br />
Trong đội lập trình cần có một số thành viên có kinh nghiệm thiết kế phần mềm, có trách nhiệm hướng dẫn các lập trình viên khác. Đội cũng cần các thành viên có kinh nghiệm về các lĩnh vực cụ thể như cơ sở dữ liệu hay bảo mật.<br />
Thực nghiệm cho thấy một dự án XP nên có từ 4 đến 10 lập trình viên.<br />
<strong>Tester</strong>: Các dự án XP nói chung không cần nhiều tester. Các lập trình viên được trông đợi sẽ chuyển giao các chương trình gần như không có lỗi cho tester. Các chương trình test tự động (automated test) cũng làm giảm số lượng tester cần thiết.<br />
Các dự án XP thường có tỉ lệ tester/lập trình viên từ 1/4 đến 1/6. Một số dự án còn không có tester mà sử dụng đại diện khách hàng và lập trình viên vào vai trò này!<br />
<strong>Quản lí dự án/Hướng dẫn viên (Project Manager/Coach)</strong>: Là những người có kinh nghiệm về XP, làm nhiệm vụ giúp đỡ các thành viên khác thực hiện các quy tắc của XP cũng như giao tiếp với các cá nhân bên ngoài dự án.<br />
<strong>Các thành viên khác</strong>: Hãy nhớ rằng có rất nhiều người có lợi ích liên quan đến dự án nhưng không làm việc cùng đội dự án. Họ là những người dùng cuối, lãnh đạo cấp cao, phòng nhân sự&#8230;(gọi chung là các stakeholder). Những người này dù không &#8220;lộ mặt&#8221; nhưng đều có ảnh hưởng đến thành công của dự án. Người quản lí sản phẩm phải thấu hiểu được những yêu cầu rất đa dạng của đội ngũ này.<br />
Một dự án XP không nhất thiết phải có đầy đủ các thành viên nói trên, hoặc  ngược lại có thể sử dụng thêm các thành viên khác nếu cần. Một thành viên trong dự án có thể đảm nhiệm nhiều vai trò cũng lúc. Chẳng hạn, người quản lí sản phẩm có thể đồng thời là chuyên gia nghiệp vụ hoặc quản lí dự án. Đại diện khách hàng có thể kiêm vai trò thiết kế giao diện. Các lập trình viên có thể làm công việc của tester.<br />
Một dự án XP thường có từ 4 đến 10 lập trình viên. Một dự án có 6 lập trình viên thường cần 4 đại diện khách hàng, 1 tester và 1 người quản lí sản phẩm, tổng cộng là 12 thành viên. Nếu số lập trình viên là 10, sẽ cần đến 6 đại diện khách hàng, 3 tester và một người quản lí sản phẩm, hợp thành một nhóm 20 người. Đây cũng là con số tối đa của một dự án XP thông thường.<br />
Kích thước nhóm lớn sẽ gây khó khăn cho việc giao tiếp giữa các thành viên. Bởi vậy, XP khuyến khích tuyển dụng các thành viên có kinh nghiệm thay vì tăng số lượng người.</p>
<p style="text-align: justify;"><strong>Tài liệu tham khảo</strong><br />
Sách: <a href="http://jamesshore.com/Agile-Book/" target="_blank">The Art of Agile Development</a> by James Shore and Shane Warden.<br />
Web: <a href="http://agilemanifesto.org/" target="_blank">http://agilemanifesto.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=88</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Các user ID của một tiến trình trong Unix</title>
		<link>http://www.openandfree.org/blog/?p=83</link>
		<comments>http://www.openandfree.org/blog/?p=83#comments</comments>
		<pubDate>Mon, 08 Jun 2009 16:57:47 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Unix/Linux/BSD]]></category>
		<category><![CDATA[effective user ID]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[setuid]]></category>
		<category><![CDATA[suid]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=83</guid>
		<description><![CDATA[Ba loại user ID của một tiến trình
Một tiến trình (process) trong Unix sở hữu 3 user ID sau đây:
Real user ID (user ID thật): Là user ID của người khởi động tiến trình.
Effective user ID (user ID hiệu dụng): Là một loại user ID được dùng trong những trường hợp sau đây:

 Khi tiến [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><strong>Ba loại user ID của một tiến trình</strong></p>
<p style="text-align: justify;">Một tiến trình (process) trong Unix sở hữu 3 user ID sau đây:</p>
<p>Real user ID (user ID thật): Là user ID của người khởi động tiến trình.<br />
Effective user ID (user ID hiệu dụng): Là một loại user ID được dùng trong những trường hợp sau đây:</p>
<ul>
<li> Khi tiến trình truy nhập một file, hệ điều hành kiểm tra xem effective user của tiến trình có quyền truy nhập file hay không.</li>
<li> Khi tiến trình tạo mới một file, hệ điều hành lấy effective user của tiến trình làm chủ sở hữu (owner) của file.</li>
<li> Khi tiến trình muốn gửi tín hiệu đến một tiến trình khác, hệ điều hành kiểm tra xem effective user của tiến trình gửi có quyền gửi tín hiệu hay không.</li>
</ul>
<p style="text-align: justify;">Saved user ID: Là giá trị của effective user ID được lưu trong bảng các tiến trình (process table). Mỗi tiến trình có một vùng dữ liệu tương ứng trong bảng các tiến trình. Saved user ID đóng vai trò như một bản backup cho effective user ID, được dùng khi tiến trình muốn quay lại effective user ID ban đầu.</p>
<p style="text-align: justify;">Tương ứng với 3 loại user ID này là ba loại group ID: real group ID, effective group ID và saved group ID.</p>
<p style="text-align: justify;"><strong>Vì sao cần effective user ID?</strong><br />
Effective user là một cơ chế quản lí truy nhập của Unix (access control hay authorization). Xem ví dụ sau đây: Alice là một kế toán và cô ta cần có quyền thay đổi file dữ liệu kế toán account_data của công ty. Tuy nhiên, để đảm bảo tính toàn vẹn dữ liệu, Alice không được phép thay đổi dữ liệu kế toán một cách thủ công mà phải thông qua một chương trình tên là account_program. Như vậy:</p>
<ul>
<li>Alice không có quyền ghi đối với account_data.</li>
<li>account_program có quyền ghi đối với account_data.</li>
<li>Alice có quyền chạy account_program.</li>
</ul>
<p style="text-align: justify;">Tuy nhiên, trong Unix chỉ có người dùng mới được coi là các chủ thể được cấp quyền sử dụng tài nguyên. Bởi vậy, giải pháp trong Unix là tạo ra một người dùng có quyền ghi đối với account_data, thiết lập effective user ID của account_program bằng ID của người dùng đó và trao cho Alice quyền chạy account_program.<span id="more-83"></span></p>
<p style="text-align: justify;"><strong>Effective user ID được thiết lập như thế nào?</strong><br />
Giá trị của effective user ID được thiết lập bằng hai cách:</p>
<p style="text-align: justify;">Thông qua bit suid: Mỗi một file chương trình có một thuộc tính gọi là suid. Nếu bit suid được thiết lập thì khi chạy file chương trình, tiến trình tương ứng sẽ có effective user và saved user là chủ sở hữu của file chương trình. Ngược lại nếu bit suid không được thiết lập, effective user và saved user của tiến trình sẽ là người khởi động tiến trình (chú ý rằng chủ sở hữu file và người chạy file thường là hai người dùng khác nhau).</p>
<p style="text-align: justify;">Thông qua hàm setuid(): Hàm setuid() dùng để thay đổi effective user ID của một tiến trình trong thời gian chạy (runtime).</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;sys/types.h&gt;</span>
<span style="color: #339933;">#include &lt;unistd.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> setuid<span style="color: #009900;">&#40;</span> uid_t uid <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Tham số uid là giá trị user ID mới. Kết quả thực hiện setuid() là như sau:</p>
<ul>
<li>Trường hợp 1: Nếu effective user hiện thời của tiến trình là root, cả ba giá trị real user ID, effective user ID và saved user ID đều được gán giá trị uid.</li>
<li>Trường hợp 2: Nếu effective user hiện thời của tiến trình không phải là root, effective user ID được gán giá trị uid nếu uid bằng real user ID hoặc saved user ID hiện thời của tiến trình. Nếu uid không bằng một trong hai giá trị này, setuid() trả về giá trị lỗi.</li>
</ul>
<p style="text-align: justify;">Hiểu một cách “nôm na” thì một tiến trình đang có effective user là root có thể “hoá thân” thành bất kì user nào. Trong khi đó một tiến trình “bình thường” chỉ có thể chuyển hoá qua lại giữa hai giá trị real user ID và effective user ID ban đầu mà thôi.</p>
<p style="text-align: justify;">Một tiến trình cần thay đổi effective user ID nhằm đảm bảo nguyên tắc “đặc quyền tối thiểu” (least privilege – một trong 8 nguyên tắc đảm bảo tính bảo mật của phần mềm [2]), theo đó một người dùng hay một tiến trình chỉ được cấp quyền tối thiểu để thực hiện một nhiệm vụ nào đó. Bởi vậy, một tiến trình chỉ sử dụng effective user là root khi thực sự cần thiết mà thôi. Theo trường hợp 2 ở trên, khi một tiến trình chuyển từ effective user root sang một effective user thông thường, nó sẽ không thể lấy lại trạng thái root bằng hàm setuid().</p>
<p style="text-align: justify;">Xem ví dụ minh họa sau đây (lấy từ [1]):<br />
user1 và user2 là hai người dùng trong hệ thống có user ID lần lượt là 501 và 502. user1 và user2 lần lượt là chủ sở hữu của các file fuser1 và fuser2, chỉ chủ sở hữu mới có quyền đọc hai file này. File chương trình testsuid.c sau khi dịch thuộc quyền sở hữu của user2 nhưng user1 có quyền chạy.</p>
<p style="text-align: justify;">Trước hết chúng ta kiểm tra giá trị của effective user ID trước khi gọi hàm setuid()</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* testsuid.c */</span>
<span style="color: #339933;">#include &lt;unistd.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">int</span> uid<span style="color: #339933;">,</span> euid<span style="color: #339933;">,</span> fuser1<span style="color: #339933;">,</span> fuser2<span style="color: #339933;">;</span>
&nbsp;
  uid  <span style="color: #339933;">=</span> getuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #808080; font-style: italic;">/* get real UID */</span>
  euid <span style="color: #339933;">=</span> geteuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* get effective UID */</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;uid: %d, euid: %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">,</span> euid <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Dịch chương trình và lưu file chạy vào một thư mục chung sao cho user1 và user2 đều truy nhập được. Khi bit suid chưa được thiết lập, effective user ID luôn bằng real user ID:</p>
<p style="text-align: justify;">Kết quả khi user1 chạy chương trình:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">testsuid
uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span></pre></div></div>

<p style="text-align: justify;">Kết quả khi user1 chạy chương trình:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">testsuid
uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span></pre></div></div>

<p style="text-align: justify;">Bây giờ chúng ta thiết lập bit suid cho testsuid như sau (thực hiện bởi user2):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">chmod</span> u+s testsuid
<span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> testsuid
<span style="color: #660033;">-rwsr-xr-x</span> <span style="color: #000000;">1</span> user2 <span style="color: #c20cb9; font-weight: bold;">users</span> <span style="color: #000000;">5404</span> Jun  <span style="color: #000000;">6</span> <span style="color: #000000;">21</span>:<span style="color: #000000;">28</span> testsuid</pre></div></div>

<p style="text-align: justify;">Chữ <strong>s </strong>trong phần quyền truy nhập file cho thấy testsuid là một chương trình suid. Kết quả là effective user ID của tiến trình luôn bằng user ID của user2:</p>
<p style="text-align: justify;">Kết quả khi user1 chạy chương trình:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">testsuid
uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span></pre></div></div>

<p style="text-align: justify;">Tiếp theo, hàm setuid() được đưa vào testsuid.c như sau:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;unistd.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;fcntl.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">int</span> uid<span style="color: #339933;">,</span> euid<span style="color: #339933;">,</span> fuser1<span style="color: #339933;">,</span> fuser2<span style="color: #339933;">;</span>
&nbsp;
  uid  <span style="color: #339933;">=</span> getuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* get real UID */</span>
  euid <span style="color: #339933;">=</span> geteuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* get effective UID */</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;uid: %d, euid: %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">,</span> euid <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  fuser1 <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;fuser1&quot;</span><span style="color: #339933;">,</span> O_RDONLY <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  fuser2 <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;fuser2&quot;</span><span style="color: #339933;">,</span> O_RDONLY <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;fuser1: %d, fuser2: %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> fuser1<span style="color: #339933;">,</span> fuser2 <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  setuid<span style="color: #009900;">&#40;</span> uid <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;after setuid(%d), uid: %d, euid: %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">,</span> getuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> geteuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  fuser1 <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;fuser1&quot;</span><span style="color: #339933;">,</span> O_RDONLY <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  fuser2 <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;fuser2&quot;</span><span style="color: #339933;">,</span> O_RDONLY <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;fuser1: %d, fuser2: %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> fuser1<span style="color: #339933;">,</span> fuser2 <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  setuid<span style="color: #009900;">&#40;</span> euid <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;after setuid(%d), uid: %d, euid: %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">,</span> getuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> geteuid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Kết quả khi user1 chạy chương trình:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">testsuid
uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span>
fuser1<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> fuser2<span style="color: #339933;">:</span> <span style="color: #0000dd;">3</span>
after setuid<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">501</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span>
fuser1<span style="color: #339933;">:</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> fuser2<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span>
after setuid<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">502</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">501</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span></pre></div></div>

<p style="text-align: justify;">Ban đầu real user ID của tiến trình bằng user ID của user1 (501) và effective user ID của tiến trình bằng user ID của user2 (502). Bởi vậy, tiến trình không đọc được fuser1 nhưng đọc được fuser2. Hàm setuid( uid ) gán effective user ID bằng real user ID (501). Do đó, sau lời gọi hàm, tiến trình đọc được fuser1 mà không đọc được fuser2. Lời gọi setuid( euid ) lấy lại giá trị ban đầu cho effective user ID (chú ý rằng euid đang được lưu trong saved user ID).</p>
<p style="text-align: justify;">Kết quả khi user2 chạy chương trình là:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">testsuid
uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span>
fuser1<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> fuser2<span style="color: #339933;">:</span> <span style="color: #0000dd;">3</span>
after setuid<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">502</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span>
fuser1<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> fuser2<span style="color: #339933;">:</span> <span style="color: #0000dd;">4</span>
after setuid<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">502</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> uid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span><span style="color: #339933;">,</span> euid<span style="color: #339933;">:</span> <span style="color: #0000dd;">502</span></pre></div></div>

<p style="text-align: justify;">Tiến trình không đọc được fuser1 vì effective user của nó luôn là user2.</p>
<p style="text-align: justify;"><strong>Các chương trình suid trên Unix</strong><br />
Một trong số các chương trình suid sẵn có trong Unix là passwd, được sử dụng để thay đổi password cho người dùng.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">passwd</span>
<span style="color: #660033;">-rwsr-xr-x</span> <span style="color: #000000;">1</span> root root <span style="color: #000000;">19876</span> Jul <span style="color: #000000;">17</span>  <span style="color: #000000;">2006</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">passwd</span></pre></div></div>

<p style="text-align: justify;">passwd thuộc sở hữu root, do vậy khi chạy sẽ có effective user là root. Người dùng không được phép ghi trực tiếp lên file password mà phải thông qua passwd.</p>
<p style="text-align: justify;"><strong>Nhược điểm của effective user ID</strong><br />
effective user là một lỗ hổng bảo mật của Unix. Các lập trình viên thường viết các chương trình có effective user là root kể cả khi không cần thiết và đó là điểm yếu cho những kẻ phá hoại khai thác. Một số lời khuyên khi thiết kế các chương trình suid được trình bày trong [3].</p>
<p style="text-align: justify;"><strong>Tài liệu tham khảo</strong><br />
[1] <a href="http://www.amazon.com/Design-Operating-System-Prentice-Software/dp/0132017997"><em>The Design of The UNIX Operating System</em></a> của Maurice J. Bach.<br />
[2] <em>The Protection of Information in Computer Systems</em> của Saltzer &amp; Schroeder.<br />
[3] <a href="http://docstore.mik.ua/orelly/networking/puis/index.htm"><em>Practical UNIX &amp; Internet Security</em> </a>của Simson Garfinkel &amp; Gene Spafford.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=83</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agile: Giới thiệu Extreme Programming</title>
		<link>http://www.openandfree.org/blog/?p=82</link>
		<comments>http://www.openandfree.org/blog/?p=82#comments</comments>
		<pubDate>Tue, 02 Jun 2009 15:46:28 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Công nghệ phần mềm]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[extreme programming]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=82</guid>
		<description><![CDATA[Nguồn: The Art of Agile Development của J Shore &#38; S Warden. Phần tiếp theo của: Agile Development: Giới thiệu chung
Extreme Programming (gọi tắt là XP, một số tài liệu tiếng Việt dịch là “lập trình cực hạn”) là một phương pháp phát triển phần mềm tuân thủ triết lí Agile. Trong số các phương [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Nguồn: <a href="http://jamesshore.com/Agile-Book/">The Art of Agile Development</a> của J Shore &amp; S Warden. Phần tiếp theo của: <a href="http://www.openandfree.org/blog/?p=80">Agile Development: Giới thiệu chung</a></p>
<p style="text-align: justify;">Extreme Programming (gọi tắt là XP, một số tài liệu tiếng Việt dịch là “lập trình cực hạn”) là một phương pháp phát triển phần mềm tuân thủ triết lí Agile. Trong số các phương pháp Agile thì XP là một trong các phương pháp hoàn thiện nhất và nhận được nhiều sự quan tâm nghiên cứu nhất. Một số phương pháp Agile khác là Scrum và Agile Unified Process (AUP).</p>
<p style="text-align: justify;"><strong>Vòng đời của một dự án XP </strong></p>
<p style="text-align: justify;">Các hoạt động cơ bản của một dự án phần mềm là:</p>
<ol>
<li>Lập kế hoạch (planning).</li>
<li> Phân tích yêu cầu (analysis).</li>
<li> Thiết kế (design).</li>
<li> Lập trình (programming).</li>
<li> Test.</li>
<li> Bàn giao sản phẩm (deploy).</li>
</ol>
<p style="text-align: justify;">Mô hình cổ điển thác nước (waterfall) sắp xếp các hoạt động này theo thứ tự tuyến tính, đầu ra của hoạt động này là đầu vào của hoạt động tiếp theo. Các mô hình lặp (iterative – chẳng hạn mô hình tăng trưởng hay mô hình tiến hóa) sắp xếp các hoạt động này xen kẽ lẫn nhau.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://farm4.static.flickr.com/3589/3588713493_d94e4fbfdb_o.jpg" alt="Vòng đời theo mô hình thác nước và mô hình lặp" /></p>
<p style="text-align: justify;">
<p style="margin-bottom: 0in; text-align: center;"><em>Hình 1: (a) Mô hình thác nước. (b) Mô hình lặp</em></p>
<p style="margin-bottom: 0in;">
<p style="text-align: justify;">
<p style="text-align: justify;">XP hoạt động theo mô hình lặp. Sản phẩm được chia ra thành các phần tăng trưởng nhỏ, mỗi phần được phát triển trong vòng một hoặc vài tuần gọi là một vòng lặp (iteration). Với mỗi phần tăng trưởng, đội dự án thực hiện tất cả các hoạt động: lập kế hoạch, phân tích, thiết kế, lập trình, test và bàn giao. Ưu điểm của mô hình này là đội dự án nhanh chóng nhận được phản hồi từ phía khách hàng. Những thay đổi cần thiết sẽ được áp dụng ngay trong lần lặp tiếp theo.<span id="more-82"></span></p>
<p style="text-align: center;"><img class="aligncenter" src="http://farm4.static.flickr.com/3368/3589519068_454b758b81_o.jpg" alt="Vòng đời theo XP" /></p>
<p style="margin-bottom: 0in; text-align: center;"><em>Hình 2: Vòng đời của một dự án XP</em></p>
<p style="text-align: justify;"><strong>Lập kế hoạch</strong></p>
<p style="text-align: justify;">Kế hoạch tổng thể của dự án được lập trong những tuần đầu tiên. Đại diện của khách hàng và các lập trình viên cùng nhau chia dự án thành các phần tăng trưởng nhỏ, ước lượng thời gian và công sức thực hiện chúng và vạch ra lịch trình phát triển cho từng phần tăng trưởng. Kế hoạch tổng thể sẽ được điều chỉnh tùy theo tình hình trong phần sau của dự án.<br />
Mỗi phần tăng trưởng có một kế hoạch thực hiện cụ thể được vạch ra vào đầu mỗi vòng lặp. Đội dự án sẽ họp mặt hàng ngày để cập nhật tình hình công việc.</p>
<p style="text-align: justify;"><strong>Phân tích</strong><br />
XP không dành riêng một khoảng thời gian cố định ban đầu cho việc phân tích yêu cầu. Trái lại, đại diện của khách hàng sẽ ngồi làm việc chung với đội dự án. Người đại diện này không nhất thiết phải là khách hàng thật, chỉ cần là người hiểu rõ nhất các yêu cầu cho sản phẩm. Khi cần thông tin, các lập trình viên chỉ việc đến trao đổi trực tiếp với người này.<br />
Đối với những yêu cầu khó hiểu, đại diện khách hàng cùng với các tester tạo ra những ví dụ chi tiết gọi là “customer test”. Đối với các giao diện đồ họa, đại diện khách hàng cùng đội dự án tạo ra các bản phác thảo trước khi bắt tay vào lập trình. Một số dự án thuê người thiết kế giao diện riêng.</p>
<p style="text-align: justify;"><strong>Thiết kế và lập trình</strong><br />
Trong một dự án XP, thiết kế của sản phẩm được cải tiến liên tục. Hoạt động này được thực hiện nhờ phương pháp phát triển dựa trên test (test-driven development hay TDD). TDD gắn kết chặt chẽ các công việc thiết kế, lập trình và test. Các lập trình viên phải làm việc theo cặp, một trong hai người viết các dòng lệnh cụ thể còn người kia suy nghĩ về thiết kế của chương trình.<br />
Các lập trình viên tích hợp code vài giờ một lần và đảm bảo rằng phiên bản mới đủ tiêu chuẩn về mặt kĩ thuật để bàn giao ngay cho khách hàng.<br />
Mã nguồn được coi là sở hữu tập thể. Mọi người được yêu cầu sửa lỗi bất kể lỗi đó do ai gây ra.</p>
<p style="text-align: justify;"><strong>Test</strong><br />
Tất cả các thành viên trong dự án XP đều có trách nhiệm đảm bảo chất lượng sản phẩm. Các lập trình viên thực hiện unit test và integration test. Đại diện khách hàng kiểm tra công việc của lập trình viên và  trợ giúp họ bằng các customer test. Khi các tester tìm ra lỗi, cả đội cùng nhau phân tích nguyên nhân và tìm cách cải tiến quy trình để ngăn ngừa lỗi tái diễn.<br />
Tất cả các regression test đều được thực hiện tự động (bởi code mới được tích hợp vào hệ thống một cách liên tục) và được chạy bởi các lập trình viên khi họ tích hợp code mới vào hệ thống.<br />
Lập trình theo cặp góp phần làm tăng chất lượng công việc.</p>
<p style="text-align: justify;"><strong>Bàn giao sản phẩm</strong><br />
Hệ thống được trình diễn nội bộ hàng tuần và được bàn giao cho khách hàng theo kế hoạch đã định trước hoặc theo nhu cầu của khách hàng.</p>
<p style="text-align: justify;"><strong>Tài liệu tham khảo</strong><br />
Sách: The Art of Agile Development của James Shore và Shane Warden: <a href="http://jamesshore.com/Agile-Book/">http://jamesshore.com/Agile-Book/</a><br />
Web: <a href="http://agilemanifesto.org/">http://agilemanifesto.org/</a></p>
<p style="text-align: justify;"><em>(còn tiếp&#8230;)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=82</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Software Engineering Radio</title>
		<link>http://www.openandfree.org/blog/?p=81</link>
		<comments>http://www.openandfree.org/blog/?p=81#comments</comments>
		<pubDate>Sat, 30 May 2009 22:42:49 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Công nghệ phần mềm]]></category>
		<category><![CDATA[radio]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=81</guid>
		<description><![CDATA[Link: http://www.se-radio.net/
Nội dung: Các bài nói chuyện về những chủ đề thú vị của Công nghệ phần mềm dưới dạng các chương trình phát thanh. Có transcript và có thể download dưới dạng file mp3.
Một số chủ đề đáng chú ý:
 Roles in Software Engineering
UML
The Semantic Web
Introduction to AOP
10 years of Agile Experiences
Software Components
Interview Erich [...]]]></description>
			<content:encoded><![CDATA[<p>Link: <a href="http://www.se-radio.net/">http://www.se-radio.net/</a><br />
Nội dung: Các bài nói chuyện về những chủ đề thú vị của Công nghệ phần mềm dưới dạng các chương trình phát thanh. Có transcript và có thể download dưới dạng file mp3.<br />
Một số chủ đề đáng chú ý:</p>
<ul> <a href="http://www.se-radio.net/podcast/2008-09/episode-110-roles-software-engineering-i">Roles in Software Engineering</a></p>
<p><a href="http://www.se-radio.net/podcast/2008-11/episode-117-bran-selic-uml">UML</a></p>
<p><a href="http://www.se-radio.net/podcast/2008-11/episode-116-semantic-web-jim-hendler">The Semantic Web</a></p>
<p><a href="http://www.se-radio.net/podcast/2008-08/episode-106-introduction-aop">Introduction to AOP</a></p>
<p><a href="http://www.se-radio.net/podcast/2008-07/episode-103-10-years-agile-experiences">10 years of Agile Experiences</a></p>
<p><a href="http://www.se-radio.net/podcast/2008-02/episode-87-software-components">Software Components</a></p>
<p><a href="http://www.se-radio.net/podcast/2007-12/episode-81-interview-erich-gamma">Interview Erich Gamma</a></p>
<p><a href="http://www.se-radio.net/podcast/2007-08/episode-65-introduction-embedded-systems">Introduction to Embedded Systems</a></p>
<p><a href="http://www.se-radio.net/podcast/2007-07/episode-61-internals-gcc">Internals of GCC</a></p>
<p><a href="http://www.se-radio.net/podcast/2006-11/episode-37-extreme-programming-pt-1"> eXtreme Programming</a></ul>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=81</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Agile: Giới thiệu chung</title>
		<link>http://www.openandfree.org/blog/?p=80</link>
		<comments>http://www.openandfree.org/blog/?p=80#comments</comments>
		<pubDate>Tue, 07 Apr 2009 17:40:53 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Công nghệ phần mềm]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=80</guid>
		<description><![CDATA[Nguồn: The Art of Agile Development by J Shore &#38; S Warden.
Agile là gì?
Agile là một triết lí (philosophy) cho việc phát triển phần mềm. Nói cách khác, đó là một cách “tư duy” về các dự án phần mềm. Các triết lí của Agile được cụ thể hóa bởi một số phương pháp phát [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0in; text-align: justify;">Nguồn: <a href="http://jamesshore.com/Agile-Book/">The Art of Agile Development</a> by J Shore &amp; S Warden.</p>
<p style="margin-bottom: 0in; text-align: justify;"><strong>Agile là gì?</strong></p>
<p style="margin-bottom: 0in; font-weight: normal; text-align: justify;">Agile là một triết lí (philosophy) cho việc phát triển phần mềm. Nói cách khác, đó là một cách “tư duy” về các dự án phần mềm. Các triết lí của Agile được cụ thể hóa bởi một số phương pháp phát triển phần mềm (method), chẳng hạn như Extreme Programming (XP) hay Scrum, gọi tắt là các phương pháp Agile.</p>
<p style="margin-bottom: 0in; font-weight: normal; text-align: justify;">Mỗi phương pháp Agile bao gồm một tập hợp các quy tắc (pratice), chẳng hạn quy tắc về sử dụng công cụ quản lí mã nguồn, quy tắc về các chuẩn lập trình hay quy tắc trình diễn sản phẩm hàng tuần cho khách hàng.</p>
<p style="margin-bottom: 0in; font-weight: normal; text-align: justify;">Triết lí Agile được đưa ra trong một bản tuyên ngôn (manifesto) gồm 4 điểm và được làm rõ hơn bởi 12 quy tắc.</p>
<p style="margin-bottom: 0in; text-align: justify;"><strong>Vì sao chúng ta cần Agile?</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Theo quan niệm truyền thống, một dự án phần mềm được coi là thành công khi sản phẩm được giao đúng hạn, trong ngân sách cho phép và làm đúng yêu cầu của khách hàng. Trên thực tế, nhiều dự án thỏa mãn tất cả các tiêu chí này nhưng rút cuộc vẫn bị coi là thất bại bởi phần mềm làm ra không được người dùng ưa thích, hoặc không mang lại nhiều lợi ích cho các cá nhân, tổ chức sử dụng chúng.</p>
<p style="margin-bottom: 0in; text-align: justify;">Ngoài các yếu tố truyền thống nói trên, một dự án phần mềm chỉ được coi là thành công khi thỏa mãn ba tiêu chí: Thành công ở mức cá nhân, thành công về mặt kĩ thuật và thành công ở mức công ty. Thành công ở mức cá nhân giúp kích thích các thành viên trong nhóm. Thành công về kĩ thuật đảm bảo khả năng bảo trì và tiến hóa của sản phẩm. Vị trí của nhóm sẽ được bảo đảm nhờ các thành công mà nhóm mang lại cho công ty. Các phương pháp Agile giúp cho dự án phần mềm đạt được ba thành công này.</p>
<p style="margin-bottom: 0in; text-align: justify;"><span id="more-80"></span></p>
<p style="margin-bottom: 0in; text-align: center;"><a href="http://farm4.static.flickr.com/3566/3421845742_45cf0615b5_o.jpg"><img class="alignnone" title="Ba tiêu chí đánh giá sự thành công của dự án phần mềm" src="http://farm4.static.flickr.com/3566/3421845742_45cf0615b5_o.jpg" alt="" width="417" height="541" /></a></p>
<p style="margin-bottom: 0in; text-align: center;"><em> Ba tiêu chí đánh giá thành công của một dự án phần mềm</em></p>
<p style="margin-bottom: 0in; text-align: justify;">
<p style="margin-bottom: 0in; text-align: justify;"><strong>Thành công ở mức công ty</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Agile nhắm đến việc tạo ra giá trị cho công ty trong khi làm giảm chi phí. Đồng thời, Agile giúp sớm xác định các kì vọng đối với sản phẩm đang được phát triển. Nhờ đó, những dự án không mang lại giá trị như mong đợi sẽ được phát hiện sớm, tiết kiệm chi phí cho công ty.</p>
<p style="margin-bottom: 0in; text-align: justify;">Theo phương pháp Agile, các chuyên gia về nghiệp vụ (business) sẽ làm việc trực tiếp cùng với đội dự án. Các chức năng quan trọng nhất của sản phẩm được tập trung phát triển trước và được đưa vào vận hành sớm nhất có thể. Các phiên bản mới với các tính năng mới sẽ lần lượt được đưa thêm vào.</p>
<p style="margin-bottom: 0in; text-align: justify;">Agile giúp tăng cường khả năng giao tiếp giữa các thành viên trong nhóm. Chất lượng mã nguồn được cải tiến liên tục. Tiến độ dự án cũng được xem xét và đánh giá một cách thường xuyên.</p>
<p style="margin-bottom: 0in; text-align: justify;"><strong>Thành công về mặt kĩ thuật</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Trong Extreme Programming, một phương pháp tuân theo triết lí Agile, các lập trình viên làm việc cùng nhau. Nhờ vậy, các chi tiết quan trọng sẽ không bị bỏ sót, mỗi đoạn code sẽ được kiểm tra bởi ít nhất hai người. Các lập trình viên liên tục tích hợp những đoạn code vừa viết vào hệ thống, cho phép một phiên bản mới của phần mềm được “ra lò” bất cứ khi nào nó góp thêm một giá trị đáng kể. Hơn nữa, toàn bộ đội dự án tập trung hoàn thành một chức năng trước khi chuyển sang chức năng tiếp theo. Bởi vậy, tiến độ công việc được kiểm soát tốt hơn và dự án có thể dễ dàng “chuyển hướng” khi có những thay đổi từ phía khách hàng.</p>
<p style="margin-bottom: 0in; text-align: justify;">Ngoài ra, Extreme Programming cũng đề xuất những quy tắc giúp tạo ra các thiết kế và các đọan mã tốt. Chẳng hạn, quy tắc “phát triển dựa trên kiểm thử” (test-driven development) trợ giúp lập trình viên viết các chương trình thực hiện đúng chức năng mong muốn.</p>
<p style="margin-bottom: 0in; text-align: justify;"><strong>Thành công về mặt cá nhân</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Mỗi thành viên trong dự án Agile, dù ở bất kì cương vị nào, cũng đều cảm nhận được một cách rõ ràng sự thành công của bản thân.</p>
<p style="margin-bottom: 0in; text-align: justify;">Các lập trình viên nhận thấy trình độ kĩ thuật cũng như tầm ảnh hưởng của mình đối với dự án được nâng cao, chẳng hạn trong việc ước lượng và lập kế hoạch. Quyền tự chủ của đội dự án cũng được tăng cường.</p>
<p style="margin-bottom: 0in; text-align: justify;">Các tester nhận thấy họ có ảnh hưởng lớn đến chất lượng sản phẩm, đồng thời giảm được các công việc lặp lại một cách nhàm chán.</p>
<p style="margin-bottom: 0in; text-align: justify;">Nhà quản lí dự án hài lòng vì kiểm soát được tiến độ công việc, dự án thực hiện đúng các cam kết và làm thỏa mãn khách hàng.</p>
<p style="margin-bottom: 0in; text-align: justify;">Khách hàng, người sử dụng, các chuyên gia nghiệp vụ cảm thấy  hài lòng vì điều kiển được hướng đi của dự án và các ý kiến được lắng nghe.</p>
<p style="margin-bottom: 0in; text-align: justify;">Các nhà lãnh đạo cao cấp sẽ cảm thấy hài lòng vì dự án mang lại lợi nhuận lớn cho công ty.</p>
<p style="margin-bottom: 0in; text-align: justify;"><strong>Bản tuyên ngôn 4 điểm cùng 12 quy tắc của Agile</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Tuyên ngôn 4 điểm của Agile là:</p>
<ol style="text-align: justify;">
<li>
<p style="margin-bottom: 0in;" align="justify">Cá nhân và các 	tương tác quan trọng hơn quy trình và công cụ.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Tập trung làm cho 	phần mềm chạy được thay vì viết tài liệu.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Cộng tác trực 	tiếp với khách hàng thay vì dựa trên hợp đồng.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Phản ứng với 	các thay đổi thay vì tuân theo một kế hoạch định sẵn.</p>
</li>
</ol>
<p style="margin-bottom: 0in; text-align: justify;">Bản tuyên ngôn được cụ thể hóa bằng 12 nguyên tắc sau:</p>
<ol style="text-align: justify;">
<li>
<p style="margin-bottom: 0in;" align="justify">Ưu tiên cao nhất 	của dự án là thỏa mãn khách hàng bằng việc bàn giao 	sản phẩm sớm và liên tục.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Hoan nghênh các 	thay đổi từ phía khách hàng, kể cả các thay đổi vào 	giai đoạn cuối.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Bàn giao sản phẩm 	theo chu kì từ vài tuần đến vài tháng. Chu kì ngắn tốt 	hơn chu kì dài.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Các nhân viên 	hiểu nghiệp vụ và các lập trình viên phải làm việc 	cùng nhau hàng ngày.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Tổ chức dự án 	xoay quanh những cá nhân tích cực. Hỗ trợ và tin tưởng 	họ.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Phương pháp giao 	tiếp tốt nhất trong đội dự án là gặp mặt trực 	tiếp.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Các chức năng đã 	họat động là thước đo chính cho tiến độ dự án.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Khuyến khích phát 	triển bền vững: Lập trình viên, người dùng, nhà quản 	lí&#8230;phải có khả năng tham gia dự án một cách liên 	tục.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Liên tục cải 	tiến chất lượng thiết kế và mã nguồn.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Tính đơn giản 	giữ vai trò cốt yếu. Làm càng ít càng tốt.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Những yêu cầu 	và thiết kế tốt nhất được nảy nở từ những nhóm 	làm việc tự chủ.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Sau những khoảng 	thời gian nhất định, đội dự án xem xét cách thức 	cải tiến hiệu quả công việc.</p>
<p style="margin-bottom: 0in;" align="justify">
</li>
</ol>
<p style="margin-bottom: 0in; text-align: justify;"><strong>Áp dụng Agile</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Không phải dự án nào cũng nên áp dụng Agile. Nếu mục tiêu của bạn là tăng năng suất lao động, làm cho các lập trình viên làm việc nhanh hơn thì Agile có thể không phù hợp bởi các quy tắc của nó không nhằm tăng năng suất của đội dự án.Trước khi quyết định áp dụng Agile cho dự án của mình, bạn phải trả lời được câu hỏi: liệu Agile có giúp bạn thành công hơn hay không?.</p>
<p style="margin-bottom: 0in; text-align: justify;">Các dự án có đặc điểm sau đây có thể phù hợp với Agile:</p>
<ul style="text-align: justify;">
<li>
<p style="margin-bottom: 0in;" align="justify">Mức độ rủi ro 	thấp.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Thành viên nhóm 	có kinh nghiệm.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Yêu cầu thay đổi 	thường xuyên.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Kích thước nhóm 	nhỏ. Các thành viên làm việc cùng một địa điểm.</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Văn hóa công ty 	ưa thích sự “không trật tự” (thrive on chaos).</p>
</li>
</ul>
<p style="margin-bottom: 0in; text-align: justify;">Trái lại, những điều kiện sau đây là vật cản cho việc áp dụng Agile:</p>
<ul style="text-align: justify;">
<li>
<p style="margin-bottom: 0in;" align="justify">Kích thước nhóm 	lớn ( hơn 20 thành viên bao gồm lập trình viên, tester,&#8230;).</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Các thành viên 	phân tán về mặt địa lí (ví dụ các dự án outsource).</p>
</li>
<li>
<p style="margin-bottom: 0in;" align="justify">Văn hóa làm việc 	theo mệnh lệnh.</p>
</li>
</ul>
<p style="margin-bottom: 0in; text-align: justify;">
<p style="margin-bottom: 0in; text-align: justify;"><strong>Tài liệu tham khảo:</strong></p>
<p style="margin-bottom: 0in; text-align: justify;">Sách: <a href="http://jamesshore.com/Agile-Book/">The Art of Agile Development</a> by James Shore and Shane Warden.</p>
<p style="margin-bottom: 0in; text-align: justify;">Web:<a href="http://agilemanifesto.org/"> Tuyên ngôn và các nguyên tắc của Agile</a></p>
<p style="margin-bottom: 0in; text-align: justify;">
<p style="margin-bottom: 0in; text-align: justify;">
<p style="margin-bottom: 0in; text-align: justify;"><em>(Còn tiếp&#8230;)</em></p>
<p style="margin-bottom: 0in; text-align: justify;">
<p style="margin-bottom: 0in; text-align: justify;">
<p style="margin-bottom: 0in; text-align: justify;">
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=80</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Gọi repaint() nhiều lần trong JFrame và JApplet</title>
		<link>http://www.openandfree.org/blog/?p=78</link>
		<comments>http://www.openandfree.org/blog/?p=78#comments</comments>
		<pubDate>Sat, 22 Nov 2008 00:47:09 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[frame]]></category>
		<category><![CDATA[repaint()]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=78</guid>
		<description><![CDATA[Khi học Java, chúng ta thường bắt gặp những chương trình đơn giản về animation trong các sách dạy AWT và Swing, chẳng hạn như chương trình sau đây:

import java.awt.*;
import javax.swing.*;
&#160;
public class Animation1 &#123;
&#160;
  public static void main&#40; String&#91;&#93; args &#41; &#123;
&#160;
     Animation1 gui = new Animation1&#40;&#41;;
    [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Khi học Java, chúng ta thường bắt gặp những chương trình đơn giản về animation trong các sách dạy AWT và Swing, chẳng hạn như chương trình sau đây:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.awt.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.*</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Animation1 <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
     Animation1 gui <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Animation1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     gui.<span style="color: #006633;">go</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> go<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
     <span style="color: #003399;">JFrame</span> frame <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JFrame</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     frame.<span style="color: #006633;">setDefaultCloseOperation</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">JFrame</span>.<span style="color: #006633;">EXIT_ON_CLOSE</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
     panel_ <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyPanel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     frame.<span style="color: #006633;">getContentPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span> panel_, <span style="color: #003399;">BorderLayout</span>.<span style="color: #006633;">CENTER</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
     frame.<span style="color: #006633;">setSize</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">500</span>, <span style="color: #cc66cc;">500</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     frame.<span style="color: #006633;">setVisible</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">400</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        x_<span style="color: #339933;">++;</span>
        y_<span style="color: #339933;">++;</span>
&nbsp;
        panel_.<span style="color: #006633;">repaint</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #003399;">Thread</span>.<span style="color: #006633;">sleep</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">10</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Exception</span> ex <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
     <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">class</span> MyPanel <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">JPanel</span> <span style="color: #009900;">&#123;</span>
&nbsp;
     <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> paintComponent<span style="color: #009900;">&#40;</span> <span style="color: #003399;">Graphics</span> g <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
         g.<span style="color: #006633;">setColor</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Color</span>.<span style="color: #006633;">white</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         g.<span style="color: #006633;">fillRect</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getWidth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getHeight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         g.<span style="color: #006633;">setColor</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Color</span>.<span style="color: #006633;">green</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         g.<span style="color: #006633;">fillOval</span><span style="color: #009900;">&#40;</span> x_, y_, <span style="color: #cc66cc;">40</span>, <span style="color: #cc66cc;">40</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
     <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JPanel</span> panel_<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> x_ <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> y_ <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Chương trình này vẽ ra một vòng tròn trên một panel, tính toán lại tọa độ của nó rồi gọi repaint() để vẽ lại vòng tròn. Phương thức repaint() yêu cầu các component trên frame tự vẽ lại.Thao tác vẽ lại liên tục với các vị trí khác nhau sẽ tạo ra cảm giác vòng tròn chạy trên panel. Câu lệnh Thread.sleep(10) làm giảm tốc độ di chuyển của vòng tròn giúp người dùng dễ theo dõi.</p>
<p style="text-align: justify;">Chúng ta thử sáng tạo thêm một chút bằng cách thêm vào frame một button dùng kể kích hoạt animation (học event handler và inner class luôn). Animation sẽ được kích hoạt khi người dùng ấn nút &#8220;Start animation&#8221;. Chương trình được cải tiến như sau:<span id="more-78"></span></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.awt.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.awt.event.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.*</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Animation2 <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	Animation2 gui <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Animation2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	gui.<span style="color: #006633;">go</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> go<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #003399;">JFrame</span> frame <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JFrame</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">setDefaultCloseOperation</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">JFrame</span>.<span style="color: #006633;">EXIT_ON_CLOSE</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	panel_ <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyPanel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">getContentPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span> panel_, <span style="color: #003399;">BorderLayout</span>.<span style="color: #006633;">CENTER</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	button_ <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JButton</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;start animation&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	button_.<span style="color: #006633;">addActionListener</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> StartAnimationAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">getContentPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span> button_, <span style="color: #003399;">BorderLayout</span>.<span style="color: #006633;">SOUTH</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	frame.<span style="color: #006633;">setSize</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">500</span>, <span style="color: #cc66cc;">500</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">setVisible</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">class</span> MyPanel <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">JPanel</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> paintComponent<span style="color: #009900;">&#40;</span> <span style="color: #003399;">Graphics</span> g <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	    g.<span style="color: #006633;">setColor</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Color</span>.<span style="color: #006633;">white</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    g.<span style="color: #006633;">fillRect</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getWidth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getHeight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	    g.<span style="color: #006633;">setColor</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Color</span>.<span style="color: #006633;">green</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    g.<span style="color: #006633;">fillOval</span><span style="color: #009900;">&#40;</span> x_, y_, <span style="color: #cc66cc;">40</span>, <span style="color: #cc66cc;">40</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">class</span> StartAnimationAction <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">ActionListener</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> actionPerformed<span style="color: #009900;">&#40;</span> <span style="color: #003399;">ActionEvent</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	    <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">400</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		x_<span style="color: #339933;">++;</span>
		y_<span style="color: #339933;">++;</span>
&nbsp;
		panel_.<span style="color: #006633;">repaint</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
		  <span style="color: #003399;">Thread</span>.<span style="color: #006633;">sleep</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">10</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Exception</span> ex <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
	    <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JPanel</span> panel_<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JButton</span> button_<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> x_ <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> y_ <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Phiên bản mới nhìn qua thì rất &#8220;đẹp&#8221;, nhưng thực ra nó không chạy đúng như chúng ta mong đợi!  Chúng ta không nhìn thấy vòng tròn di chuyển trên panel mà chỉ thấy nó nhảy  từ vị trí ban đầu đến vị trí cuối cùng, các trạng thái trung gian đã bị mất. Vậy đâu là nguyên nhân của hành vi kì lạ này?</p>
<p style="text-align: justify;">Thực ra, khi chúng ta đặt phương thức repaint() vào trong một vòng lặp, AWT sẽ trộn các lời gọi repaint() lại với nhau và chỉ có lời gọi repaint() cuối cùng được thực hiện. Bởi vậy chúng ta không thể nhìn thấy các trạng thái trung gian của vòng tròn trên panel.</p>
<p style="text-align: justify;">Vậy làm thế nào giải quyết vấn đề này? Một giải pháp là đưa các lời gọi repaint() sang một thread khác như sau:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.awt.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.awt.event.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.*</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Animation3 <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	Animation3 gui <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Animation3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	gui.<span style="color: #006633;">go</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> go<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #003399;">JFrame</span> frame <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JFrame</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">setDefaultCloseOperation</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">JFrame</span>.<span style="color: #006633;">EXIT_ON_CLOSE</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	panel_ <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyPanel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">getContentPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span> panel_, <span style="color: #003399;">BorderLayout</span>.<span style="color: #006633;">CENTER</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	button_ <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JButton</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;start animation&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	button_.<span style="color: #006633;">addActionListener</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> StartAnimationAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">getContentPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span> button_, <span style="color: #003399;">BorderLayout</span>.<span style="color: #006633;">SOUTH</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	frame.<span style="color: #006633;">setSize</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">500</span>, <span style="color: #cc66cc;">500</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	frame.<span style="color: #006633;">setVisible</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">class</span> MyPanel <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">JPanel</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> paintComponent<span style="color: #009900;">&#40;</span> <span style="color: #003399;">Graphics</span> g <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	    g.<span style="color: #006633;">setColor</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Color</span>.<span style="color: #006633;">white</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    g.<span style="color: #006633;">fillRect</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getWidth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getHeight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	    g.<span style="color: #006633;">setColor</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Color</span>.<span style="color: #006633;">green</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    g.<span style="color: #006633;">fillOval</span><span style="color: #009900;">&#40;</span> x_, y_, <span style="color: #cc66cc;">40</span>, <span style="color: #cc66cc;">40</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">class</span> StartAnimationAction <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">ActionListener</span>, <span style="color: #003399;">Runnable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> actionPerformed<span style="color: #009900;">&#40;</span> <span style="color: #003399;">ActionEvent</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	    <span style="color: #003399;">Thread</span> thread <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Thread</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    thread.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	    <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">400</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		x_<span style="color: #339933;">++;</span>
		y_<span style="color: #339933;">++;</span>
&nbsp;
		panel_.<span style="color: #006633;">repaint</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
		  <span style="color: #003399;">Thread</span>.<span style="color: #006633;">sleep</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">10</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Exception</span> ex <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
	    <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JPanel</span> panel_<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JButton</span> button_<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> x_ <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> y_ <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Bây giờ thì chương trình của chúng ta đã chạy ngon lành. Để giải thích cặn kẽ về vấn đề gọi repaint() nhiều lần có lẽ cần đến những hiểu biết nhất định về thread trong Java. Bởi vậy &#8220;tác giả&#8221;, với trình độ còn rất hạn chế, đành tạm thời hài lòng với giải pháp nói trên <img src='http://www.openandfree.org/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Tài liệu tham khảo: <a href="http://www.ryerson.ca/~dgrimsha/courses/cps840/repaint.html">The repaint() method and the GUI thread</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=78</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>vim plugin for NetBeans</title>
		<link>http://www.openandfree.org/blog/?p=77</link>
		<comments>http://www.openandfree.org/blog/?p=77#comments</comments>
		<pubDate>Thu, 20 Nov 2008 01:09:34 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[vim plugin]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=77</guid>
		<description><![CDATA[Khi đã quen viết code trên vi/vim rồi thì chuyển sang editor khác thật khó chịu. Phiền hà nhất là các thao tác di chuyển con trỏ (phải dùng các phím mũi tên lên xuống rất mất thời gian), xóa một từ hoặc một dòng (phải giữ Backspace mỏi cả tay), nhảy giữa các từ&#8230;Tóm [...]]]></description>
			<content:encoded><![CDATA[<p>Khi đã quen viết code trên vi/vim rồi thì chuyển sang editor khác thật khó chịu. Phiền hà nhất là các thao tác di chuyển con trỏ (phải dùng các phím mũi tên lên xuống rất mất thời gian), xóa một từ hoặc một dòng (phải giữ Backspace mỏi cả tay), nhảy giữa các từ&#8230;Tóm lại với những ai đã quen lập trình trên vi/vim thì việc phải chuyển sang các IDE khác sẽ không khác gì cực hình.</p>
<p>Giải pháp cho vấn đề này là cài đặt vim plugin cho IDE đang sử dụng. Một IDE đang được sử dụng rộng rãi là NetBeans. Để cài đặt vim plugin cho NetBeans, vào link dưới đây để tải về file cài đặt:</p>
<p><a href="http://sourceforge.net/projects/viex/">http://sourceforge.net/projects/viex/</a></p>
<p>Giải nén để nhận được file start-module-myvim.nbm. Từ menu của NetBeans, chọn Tools-&gt;Plugins-&gt;Downloaded-&gt;Add Plugins rồi chọn file start-module-myvim.nbm. Chúng ta sẽ thấy biểu tượng của vim nằm bên cạnh các icon khác như trong hình dưới đây. (Chú ý hình dáng của con trỏ, chúng ta đang ở chế độ lệnh của vim).</p>
<p><img class="alignnone" src="http://farm4.static.flickr.com/3173/3044058495_7b05091433_o.jpg" alt="" width="600" height="400" /></p>
<p>Bây giờ thì chúng ta đã có thể tận hưởng sự tiện lợi trong việc viết code bằng vim kết hợp với những tính năng phức tạp cung cấp bởi NetBeans. Tuy nhiên, plugin này vẫn chưa hỗ trợ một số thao tác edit trong vim như</p>
<p>- Không tự động indent khi xuống dòng bằng phím o.</p>
<p>- Không hỗ trợ shift-o</p>
<p>- Không hỗ trợ ctrl-r (redo).</p>
<p>- Không hỗ trợ xoá nhiều từ liền nhau (d 2 w, d 3 w, d $,&#8230;)</p>
<p>Tuy nhiên với những tính năng hiện có của plugin này thì công việc lập trình trên NetBeans đã trở nên thú vị hơn rất nhiều. Hi vọng những khiếm khuyết nói trên sẽ được khắc phục trong những phiên bản sau.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=77</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Các mô hình phát triển phần mềm</title>
		<link>http://www.openandfree.org/blog/?p=63</link>
		<comments>http://www.openandfree.org/blog/?p=63#comments</comments>
		<pubDate>Sun, 26 Oct 2008 12:51:27 +0000</pubDate>
		<dc:creator>kiennguyen</dc:creator>
				<category><![CDATA[Công nghệ phần mềm]]></category>
		<category><![CDATA[evolutionary]]></category>
		<category><![CDATA[incremental]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[software process models]]></category>
		<category><![CDATA[waterfall]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=63</guid>
		<description><![CDATA[Bài viết này trình bày những mô hình phát triển phần mềm cơ bản.
Một dự án phát triển phần mềm thường trải qua các hoạt động sau đây:
- Phân tích yêu cầu.
- Thiết kế và lập trình.
- Test.
- Bảo trì.
Mỗi mô hình phát triển phần mềm đưa ra một cách tổ chức sắp xếp khác [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="text-align: justify;">Bài viết này trình bày những mô hình phát triển phần mềm cơ bản.</p>
<p class="MsoNormal" style="text-align: justify;">Một dự án phát triển phần mềm thường trải qua các hoạt động sau đây:</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in; text-align: justify;"><!--[if !supportLists]--><span>-<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;"> </span></span><!--[endif]-->Phân tích yêu cầu.</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in; text-align: justify;"><!--[if !supportLists]--><span>-<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;"> </span></span><!--[endif]-->Thiết kế và lập trình.</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in; text-align: justify;"><!--[if !supportLists]--><span>-<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;"> </span></span><!--[endif]-->Test.</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in; text-align: justify;"><!--[if !supportLists]--><span>-<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;"> </span></span><!--[endif]-->Bảo trì.</p>
<p class="MsoNormal" style="text-align: justify;">Mỗi mô hình phát triển phần mềm đưa ra một cách tổ chức sắp xếp khác nhau của các hoạt động này.</p>
<h3 id="toc-1-mo-hinh-thac-nc-waterfall" class="MsoNormal" style="text-align: justify;"><strong>1. Mô hình thác nước (waterfall)</strong></h3>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Đây là mô hình phát triển phần mềm cổ điển nhất. Mô hình này đề nghị các hoạt động được tiến hành như các giai đoạn tách biệt, giai đoạn sau sẽ không bắt đầu chừng nào giai đoạn trước chưa hoàn thành. Sản phẩm đầu ra của giai đoạn trước trở thành đầu vào của giai đoạn sau.<img class="alignnone" src="http://farm4.static.flickr.com/3235/2974435882_02faa55749_o.jpg" alt="" width="512" height="384" /></p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><!--[if gte vml 1]><v:shapetype  id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"  path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:377.25pt;  height:260.25pt'> <v:imagedata src="file:///C:\DOCUME~1\knguye\LOCALS~1\Temp\msohtml1\03\clip_image001.emz" mce_src="file:///C:\DOCUME~1\knguye\LOCALS~1\Temp\msohtml1\03\clip_image001.emz"   o:title="" /> </v:shape><![endif]-->Những mũi tên ngược từ dưới lên trên cho thấy những sai lầm ở giai đoạn trước có thể được phát hiện ở giai đoạn sau và đòi hỏi việc quay ngược lên để làm lại giai đoạn trước. Tuy nhiên ,hoạt động quay lui này chỉ nên được coi là các ngoại lệ mà thôi.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình thác nước có ưu điểm là dễ quản lí. Đây chính là mô hình ưa thích của các nhà quản lí dự án. Thời gian hoàn thành dự án thường được dự báo với độ chính xác hơn so với các mô hình khác. Các tài liệu đầu ra của từng giai đoạn cũng được xây dựng đầy đủ và hệ thống hơn. Tuy nhiên mô hình này có một số nhược điểm lớn là:</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Mô hình đòi hòi một bản yêu cầu (requirement) đầy đủ và chính xác từ phía khách hàng.</b> Yêu cầu này hiếm khi đạt được bởi khách hàng ít khi xác định được chính xác họ muốn gì ở ngay giai đoạn đầu của dự án, sở thích của họ cũng thay đổi khá thường xuyên. Việc làm lại các giai đoạn ban đầu để đáp ứng sự thay đổi của khách hàng thường mất rất nhiều công sức và phá vỡ cấu trúc của phần mềm.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Khách hàng cần phải kiên nhẫn. </b>Họ chỉ được tham gia vào dự án ở giai đoạn phân tích yêu cầu và test mà thôi. Ngoài ra, sản phẩm sẽ chỉ được bàn giao khi tất cả các công việc liên quan đã được hoàn thành.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình thác nước chỉ nên được sử dụng khi đội dự án đã có kinh nghiệm, yêu cầu từ khách hàng được xác  định rõ ngay từ đầu và ít có khả năng thay đổi. Hiện nay, mô hình thác nước vẫn được sử dụng rộng rãi do tính gần gũi với các mô hình phát triển trong các ngành kĩ thuật khác.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><span id="more-63"></span></p>
<h3 id="toc-2-mo-hinh-tin-hoa-evolutionary" class="MsoNormal" style="text-align: justify;"><strong>2. Mô hình tiến hóa (Evolutionary)</strong></h3>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình tiến hóa được đưa ra nhằm giải quyết những khó khăn gây ra do yêu cầu của khách hàng không rõ ràng hoặc hay thay đổi. Ý tưởng của mô hình này là phát triển phẩn mềm qua nhiều phiên bản, mỗi phiên bản được đưa ra lấy ý kiến khách hàng, được sửa chữa, làm mịn cho đến khi đạt được phiên bản hoàn chỉnh.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><img class="alignnone" src="http://farm4.static.flickr.com/3137/2973583173_9659fbf42f_o.jpg" alt="" width="512" height="384" /></p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình tiến hóa: Các phiên bản 1, 2, 3 có thể rất khác nhau!</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><!--[if gte vml 1]><v:shape  id="_x0000_i1026" type="#_x0000_t75" style='width:251.25pt;height:153.75pt'> <v:imagedata src="file:///C:\DOCUME~1\knguye\LOCALS~1\Temp\msohtml1\03\clip_image003.emz" mce_src="file:///C:\DOCUME~1\knguye\LOCALS~1\Temp\msohtml1\03\clip_image003.emz"   o:title="" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]--></p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Hai kiểu mô hình tiến hóa cơ bản là:</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Khám phá và phát triển (exploratory development):</b> Đội dự án sẽ làm việc cùng khách hàng để khám phá các yêu cầu của họ. Dự án sẽ bắt đầu trước tiên với những yêu cầu đã rõ ràng. Các đặc tính khác sẽ được thêm vào dần dần dựa trên đề nghị của khách hàng.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Làm bản mẫu để “vứt đi” (throwaway prototyping):</b> Mô hình này được áp dụng cho giai đoạn phân tích yêu cầu. Theo đó, đội dự án sẽ làm các bản mẫu (prototype) để lấy ý kiến khách hàng nhằm kiểm chứng và làm rõ các yêu cầu chưa rõ ràng. Khi đã có một bản yêu cầu hoàn chỉnh, giai đoạn phát triển tiếp theo có thể sử dụng mô hình thác nước.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình tiến hóa cho phép khách hàng tham gia sâu hơn vào quá trình phát triển, nhờ đó sản phẩm cuối cùng thường phản ánh chính xác mong muốn của khách hàng. Tuy nhiên, mô hình này cũng có các nhược điểm là:</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Khó khăn trong việc thiết kế: </b>Việc phát triển qua nhiều phiên bản có thể phá vỡ kiến trúc tổng thể của phần mềm.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Khó khăn trong việc quản lí:</b> Các nhà quản lí thích nhìn thấy sản phẩm làm ra trong từng gian đoạn để tiện cho việc quản lí tiến độ. Ngoài ra, các tài liệu mô tả cho từng phiên bản thường không được lập đầy đủ.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">-<b> Khó khăn do khách hàng gây ra:</b> Khách hàng có thể nhầm tưởng rằng một bản mẫu có thể tốt gần như sản phẩm thật. Trong thực tế từ bản mẫu đến sản phẩm cuối cùng là một khảng cách xa. Ngoài ra khách hàng có xu hướng đưa thêm vào những yêu cầu không cần thiết.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Khó khăn về địa lý:</b> Mô hình tiến hóa đòi hỏi đội dự án phải ngồi gần khách hàng. Các dự án outsourcing khó có thể đáp ứng yêu cầu này.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Theo <a href="http://www.cs.st-andrews.ac.uk/~ifs/">Ian Sommerville</a> trong cuốn &#8220;<a href="http://www.cs.st-andrews.ac.uk/~ifs/Books/SE8/index.html">Software Engineering</a>&#8220;, mô hình tiến hóa là mô hình phù hợp nhất cho các dự án vừa và nhỏ (dưới 500 000 dòng code). Các dự án lớn và phức tạp nên sử dựng một mô hình kết hợp giữa mô hình thác nước và tiến hóa. Trong đó, các bản mẫu được dùng để làm rõ các yêu cầu của khách hàng. Các yêu cầu đã rõ ràng được tiếp tục phát triển theo mô hình thác nước. Các yêu cầu chưa rõ ràng có thể sử dụng mô hình khám phá và phát triển.</p>
<h3 id="toc-3-mo-hinh-tang-trng-incremental" class="MsoNormal" style="text-align: justify;"><strong>3. Mô hình tăng trưởng (Incremental)</strong></h3>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình tăng trưởng kết hợp những ưu điểm của mô hình thác nước và mô hình tiến hóa. Ý tưởng của mô hình này là phân chia phần mềm thành những phần tăng trưởng (được gọi là các increments) và phát triển, bàn giao chúng lần lượt cho khách hàng theo mức độ quan trọng. Phần tăng trưởng nào đến lượt được phát triển thì những yêu cầu tương ứng sẽ được phân tích. Chỉ những thay đổi từ phía khách hàng cho những phần chưa được phát triển mới được chấp nhận.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><img class="alignnone" src="http://farm4.static.flickr.com/3179/2973583211_51539da456_o.jpg" alt="" width="512" height="384" /></p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Theo Ian Sommerville, mỗi phần tăng trưởng không nên quá 20 000 dòng code và phải mang lại những lợi ích nhất định cho khách hàng. Còn theo Mike Cotterell và Bob Hughes trong “<a href="http://www.amazon.co.uk/Software-Management-Tutorial-computing-information/dp/1850321906/ref=sr_1_3/275-4622645-9975354?ie=UTF8&amp;s=books&amp;qid=1225023453&amp;sr=1-3">Software Project Management</a>”, mỗi phần tăng trưởng nên chiếm từ 1% đến 5% của toàn dự án và không nên kéo dài quá một tháng.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Mô hình tăng trưởng có những ưu điểm sau đây:</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Rút ngắn thời gian chờ đợi của khách hàng.</b> Khách hàng không phải đợi đến khi toàn bộ hệ thống hoàn thành mới được hưởng lợi. Những thành phần quan trọng nhất được bàn giao sớm và mang lại lợi ích sớm hơn cho khách hàng.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Tăng chất lượng phần mềm. </b>Thành phần quan trọng nhất của hệ thống được phát triển và đi vào hoạt động sớm nhất, bởi vậy nó được test nhiều nhất. Ngoài ra, những ý kiến của khách hàng cũng như kinh nghiệm phát triển các thành phần trước sẽ được áp dụng ngay lập tức cho các thành phần sau.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Giảm bớt những yêu cầu không cần thiết từ khách hàng.</b> Khi một tính năng chưa có mặt trong hệ thống, họ sẽ nghĩ rằng nó sẽ được tích hợp vào ở những lần bàn giao tiếp theo!</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;"><b>- Tăng năng suất lao động.</b> Nhiều lập trình viên làm việc tốt hơn trong các dự án nhỏ mà họ sớm nhìn thấy thành quả lao động của mình.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Tuy nhiên, mô hình tăng trưởng cũng có nhược điểm là không phải dự án nào cũng có thể được phân chia thành các phần tăng trưởng nhỏ có thể được phát triển và bàn giao tuần tự. Nếu làm không tốt giai đoạn lập kế hoạch và phân tách hệ thống, xung đột giữa các thành phần có thể nảy sinh.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Các biến thể của mô hình tăng trưởng là Agile Development và Extreme Programming.</p>
<p class="MsoNormal" style="margin-left: 0.25in; text-align: justify;">Ngoài các mô hình phát triển phần mềm cơ bản nói trên còn có các mô hình biến thể như mô hình chữ V (V-model), mô hình xoáy ốc (spiral) hay mô hình tái sử dụng CBSE (component-based software engineering).</p>
<h3 id="toc-tai-liu-tham-kho" class="MsoNormal" style="text-align: justify;">Tài liệu tham khảo:</h3>
<ul>
<li>&#8220;Software Engineering&#8221; của Ian Sommerville</li>
<li>&#8220;Software Engineering: A practitioner&#8217;s Approach&#8221; của Pressman</li>
<li>&#8220;Software Project Management&#8221; của Cotterell và Hughes</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=63</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Linked List (1) &#8211; Basic</title>
		<link>http://www.openandfree.org/blog/?p=51</link>
		<comments>http://www.openandfree.org/blog/?p=51#comments</comments>
		<pubDate>Fri, 25 Jul 2008 18:39:19 +0000</pubDate>
		<dc:creator>Hoang Tran</dc:creator>
				<category><![CDATA[C/C++]]></category>

		<guid isPermaLink="false">http://www.openandfree.org/blog/?p=51</guid>
		<description><![CDATA[Lấy từ tài liệu tuyệt vời này về linked list của trường Stanford mà tôi muốn khái lược lại bằng những đoạn mã trong đó. Danh sách liên kết (linked list) là  một kiến thức rất cơ bản của cấu trúc dữ liệu và giải thuật. Hiểu được những ưu và khuyết điểm của [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Lấy từ tài liệu tuyệt vời <a href="http://cslibrary.stanford.edu/103/LinkedListBasics.pdf">này</a> về linked list của trường Stanford mà tôi muốn khái lược lại bằng những đoạn mã trong đó. Danh sách liên kết (linked list) là  một kiến thức rất cơ bản của cấu trúc dữ liệu và giải thuật. Hiểu được những ưu và khuyết điểm của nó sẽ giúp chúng ta hiểu các vấn đề về thời gian, không gian bộ nhớ và cấu trúc dữ liệu nói chung. Hơn thế nữa học về linked list là một cách rất tốt để hiểu về pointer. Những bài toán về linked list là sự kết hợp rất &#8220;đẹp&#8221; giữa giải thuật (algorithms) và các phép toán với con trỏ (pointer manipulation). Linked list là cách các lập trình viên luyện tập để thực sự hiểu về pointer và bạn sẽ thấy ngôn ngữ C &#8220;đẹp&#8221; vô cùng <img src='http://www.openandfree.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Hãy tham khảo thêm tài liệu của Stanford để hiểu kỹ thêm (Highly recommend!)</p>
<div class="toc">
<ol>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-linked-list-basic">Linked list basic</a></p>
<ol>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-khai-bao-linked-list">Khai báo linked list:</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-ham-length-ly-s-phn-t-ca-danh-sach">Hàm length() lấy số phần tử của danh sách</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-duyt-danh-sach-s-dng-mt-con-tr-local">Duyệt danh sách sử dụng một con trỏ local</a></li>
</ol>
</li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-linked-list-building">Linked List Building</a>
<ol>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-3-bc-d-them-mt-node-vao-du-linked-list">3 bước để thêm một node vào đầu linked list</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-ham-push">Hàm Push()</a></li>
</ol>
</li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-techniques">Techniques</a>
<ol>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-duyt-xung-iterate-down">Duyệt xuống (Iterate down)</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-di-mt-pointer-bng-mt-tham-chiu-ti-pointer-reference-pointer">Đổi một pointer bằng một tham chiếu tới pointer (reference pointer)</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-build-list-s-dng-them-node-vao-du-bng-ham-push">Build list sử dụng thêm node vào đầu bằng hàm Push</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-build-list-s-dng-con-tr-tail">Build list sử dụng con trỏ tail</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-build-list-s-dng-con-tr-tail-co-x-ly-trng-hp-dc-bit">Build list sử dụng con trỏ tail có xử lý trường hợp đặc biệt</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-build-list-s-dng-dummy-node">Build list sử dụng dummy node</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-build-list-s-dng-tham-chiu-cc-b-local-references">Build list sử dụng tham chiếu cục bộ (local references)</a></li>
</ol>
</li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-cac-don-ma-vi-d">Các đoạn mã ví dụ</a>
<ol>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-appendnode">AppendNode()</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-appendnode-s-dng-push">AppendNode() sử dụng Push()</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-copylist">CopyList()</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-copylist-with-push">CopyList() with Push()</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-copylist-with-dummy-node">CopyList() With Dummy Node</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-copylist-with-local-references">CopyList() With Local References</a></li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-copylist-recursive">CopyList() Recursive</a></li>
</ol>
</li>
<li><a href="http://www.openandfree.org/blog/?p=51#toc-other-implementations">Other implementations</a></li>
</ol>
</div>
<p><span id="more-51"></span></p>
<h1 id="toc-linked-list-basic">Linked list basic</h1>
<h2 id="toc-khai-bao-linked-list">Khai báo linked list:</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node <span style="color: #008000;">&#123;</span>
     <span style="color: #0000ff;">int</span> data<span style="color: #008080;">;</span>
     <span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> next<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008080;">;</span></pre></div></div>

<h2 id="toc-ham-length-ly-s-phn-t-ca-danh-sach">Hàm length() lấy số phần tử của danh sách</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/*
 Given a linked list head pointer, compute
 and return the number of nodes in the list.
*/</span>
<span style="color: #0000ff;">int</span> Length<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> count <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        count<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
        current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> count<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-duyt-danh-sach-s-dng-mt-con-tr-local">Duyệt danh sách sử dụng một con trỏ local</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span>
<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// do something with *current node</span>
    current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h1 id="toc-linked-list-building">Linked List Building</h1>
<h2 id="toc-3-bc-d-them-mt-node-vao-du-linked-list">3 bước để thêm một node vào đầu linked list</h2>
<li>Cấp phát vùng nhớ cho node mới</li>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newNode<span style="color: #008080;">;</span>
newNode <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> data_client_wants_stored<span style="color: #008080;">;</span></pre></div></div>

<li>Kết nối trường next của node mới vào đầu danh sách</li>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span></pre></div></div>

<li>Đưa con trỏ head trỏ vào node mới</li>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">head <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span></pre></div></div>

<h2 id="toc-ham-push">Hàm Push()</h2>
<p style="text-align: justify;">Có vẻ từ 3 bước trên thì việc viết hàm Push() để thêm một node vào đầu danh sách rất dễ dàng. Hãy xem hàm sau và tìm chỗ sai trước khi xem lời giải.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> WrongPush<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head, <span style="color: #0000ff;">int</span> data<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
     <span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newNode <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
     newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> data<span style="color: #008080;">;</span>
     newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span>
     head <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Thực ra sai ở dòng</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">head <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span> <span style="color: #666666;">// NO this line does not work!</span></pre></div></div>

<p style="text-align: justify;">Hãy sửa lại hàm Push() trước khi xem tiếp.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/*
Takes a list and a data value.
Creates a new link with the given data and pushes
it onto the front of the list.
The list is not passed in by its head pointer.
Instead the list is passed in as a &quot;reference&quot; pointer
to the head pointer -- this allows us
to modify the caller's memory.
*/</span>
<span style="color: #0000ff;">void</span> Push<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">**</span> headRef, <span style="color: #0000ff;">int</span> data<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
     <span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newNode <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
     newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> data<span style="color: #008080;">;</span>
     newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> <span style="color: #000040;">*</span>headRef<span style="color: #008080;">;</span> <span style="color: #666666;">// The '*' to dereferences back to the real head</span>
     <span style="color: #000040;">*</span>headRef <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span>          
<span style="color: #008000;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Với C++ thì có hỗ trợ truyền tham chiếu (reference &amp;) vào hàm, nên hàm Push có thể viết như sau với C++</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/*
 Push() in C++ -- we just add a '&amp;' to the right hand
 side of the head parameter type, and the compiler makes
 that parameter work by reference. So this code changes
 the caller's memory, but no extra uses of '*' are necessary -- 
 we just access &quot;head&quot; directly, and the compiler makes that
 change reference back to the caller.
*/</span>
<span style="color: #0000ff;">void</span> Push<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span><span style="color: #000040;">&amp;</span> head, <span style="color: #0000ff;">int</span> data<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
     <span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newNode <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
     newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> data<span style="color: #008080;">;</span>
     newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span> <span style="color: #666666;">// No extra use of * necessary on head -- the compiler</span>
     head <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span> <span style="color: #666666;">// just takes care of it behind the scenes.</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h1 id="toc-techniques">Techniques</h1>
<h2 id="toc-duyt-xung-iterate-down">Duyệt xuống (Iterate down)</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span>
<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
     <span style="color: #ff0000; font-style: italic;">/* Do sth here */</span>
     current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Có thể thay vòng lặp bằng</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span> current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span></pre></div></div>

<h2 id="toc-di-mt-pointer-bng-mt-tham-chiu-ti-pointer-reference-pointer">Đổi một pointer bằng một tham chiếu tới pointer (reference pointer)</h2>
<p style="text-align: justify;">Nhiều hàm cần phải thay đổi con trỏ head mặc dù nó được truyền vào hàm số theo kiểu pass-by-value. Để làm điều này trong C thì hãy truyền một pointer đến head pointer thay vì chỉ truyền head pointer. Kiểu pointer chỉ đến một pointer khác thường được gọi là reference pointer.</p>
<p style="text-align: justify;">Hãy xem hàm ChangeToNull để cho con trỏ head trỏ vào NULL</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Change the passed in head pointer to be NULL</span>
<span style="color: #666666;">// Uses a reference pointer to access the caller's memory</span>
<span style="color: #0000ff;">void</span> ChangeToNull<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">**</span> headRef<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
     <span style="color: #666666;">// Takes a pointer to the value of interest</span>
     <span style="color: #000040;">*</span>headRef <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// use '*' to access the value of interest</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-build-list-s-dng-them-node-vao-du-bng-ham-push">Build list sử dụng thêm node vào đầu bằng hàm Push</h2>
<p style="text-align: justify;">Phương pháp này làm cho đoạn mã xây dựng list rất ngắn và chạy rất nhanh</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> AddAtHead<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">int</span> i<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">1</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">6</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>head, i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #666666;">// head == {5, 4, 3, 2, 1};</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>head<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-build-list-s-dng-con-tr-tail">Build list sử dụng con trỏ tail</h2>
<p style="text-align: justify;">Cũng có thể thêm một node mới vào cuối cùng của list. Chúng ta sẽ cần một con trỏ tail trỏ vào node cuối cùng của list và trường next của nó sẽ trỏ vào null. Khi thêm một node mới vào </p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span>
tail <span style="color: #000080;">=</span> tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span></pre></div></div>

<p style="text-align: justify;">Tuy nhiên thì có một trường hợp đặc biệt khi phần tử mới thêm vào danh sách là phần tử đầu tiên của list. Hãy xem xét tiếp các kỹ thuật sau.</p>
<h2 id="toc-build-list-s-dng-con-tr-tail-co-x-ly-trng-hp-dc-bit">Build list sử dụng con trỏ tail có xử lý trường hợp đặc biệt</h2>
<p style="text-align: justify;">Khi build một danh sách bằng cách thêm một node mới vào cuối danh sách thì điểm khó là node đầu tiên phải được thêm vào head pointer và các node khác thì được thêm vào sau node cuối cùng sử dụng tail pointer. Cách đơn giản nhất để xử lý cả điều này là viết hai đoạn code riêng rẽ xử lý chúng. Đầu tiên là đoạn mã thêm vào head pointer cho phần tử đầu tiên và tiếp đó là một vòng lặp sử dụng tail pointer để thêm tất cả các node khác. Trông nó có vẻ &#8220;xấu&#8221; nhưng đơn giản và chạy nhanh.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> BuildWithSpecialCase<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> tail<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">int</span> i<span style="color: #008080;">;</span>
	<span style="color: #666666;">// Deal with the head node here, and set the tail pointer</span>
	Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>head, <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>	
	tail <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #666666;">// Do all the other nodes using 'tail'</span>
	<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">2</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">6</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span>, i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// add node at tail-&gt;next</span>
		tail <span style="color: #000080;">=</span> tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span> <span style="color: #666666;">// advance tail to point to last node</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>head<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// head == {1, 2, 3, 4, 5};</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-build-list-s-dng-dummy-node">Build list sử dụng dummy node</h2>
<p style="text-align: justify;">Một giải pháp khác là sử dụng một dummy node tạm thời ở đầu danh sách. Dummy node sẽ đóng vai trò là phần tử đầu tiên và tất cả các node &#8220;thực sự&#8221; sẽ được thêm vào sau dummy node.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> BuildWithDummyNode<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node dummy<span style="color: #008080;">;</span> <span style="color: #666666;">// Dummy node is temporarily the first node</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> tail <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span>dummy<span style="color: #008080;">;</span> <span style="color: #666666;">// Start the tail at the dummy.</span>
	<span style="color: #666666;">// Build the list on dummy.next (aka tail-&gt;next)</span>
	<span style="color: #0000ff;">int</span> i<span style="color: #008080;">;</span>
	dummy.<span style="color: #007788;">next</span> <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">1</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">6</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span>, i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		tail <span style="color: #000080;">=</span> tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #666666;">// The real result list is now in dummy.next</span>
	<span style="color: #666666;">// dummy.next == {1, 2, 3, 4, 5};</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>dummy.<span style="color: #007788;">next</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Ở ví dụ trên ta thấy dummy node sẽ không ở trong list khi ra khỏi hàm. Nhưng có một vài cách thể hiện linked list luôn giữ lại dummy node trong suốt quá trình sử dụng nó. Với cách tiếp cận đó thì sẽ không bao giờ có một danh sách rỗng (empty list). Thay vì đó thì danh sách luôn có một dummy node ở đầu. Tuy nhiên thì tôi không khuyến khích phương pháp tiếp cận đó. Phương án sử dụng dummy node tạm thời nên được sử dụng hơn.</p>
<h2 id="toc-build-list-s-dng-tham-chiu-cc-b-local-references">Build list sử dụng tham chiếu cục bộ (local references)</h2>
<p style="text-align: justify;">Cuối cùng đây là một giải pháp rất &#8220;mẹo mực&#8221; mà không phải sự dụng dummy node. Đó là sử dụng một local &#8220;reference pointer&#8221; mà luôn trỏ vào pointer cuối cùng của list chứ không phải node cuối cùng.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> BuildWithLocalRef<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">**</span> lastPtrRef<span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span>head<span style="color: #008080;">;</span> <span style="color: #666666;">// Start out pointing to the head pointer</span>
	<span style="color: #0000ff;">int</span> i<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000080;">=</span><span style="color: #0000dd;">1</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">6</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span>lastPtrRef, i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Add node at the last pointer in the list</span>
		lastPtrRef<span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>lastPtrRef<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Advance to point to the</span>
							<span style="color: #666666;">// new last pointer</span>
	<span style="color: #008000;">&#125;</span>		
	<span style="color: #666666;">// head == {1, 2, 3, 4, 5};</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>head<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Kỹ thuật này rất ngắn nhưng bên trong vòng lặp thật &#8220;kinh hoàng&#8221;.</p>
<p style="text-align: justify;">Cả hai giải pháp sử dụng temporary-dummy và reference pointer có hơi chút &#8220;không bình thường&#8221; nhưng nó rất tốt để chắc chắn rằng chúng ta hiểu về pointer bởi vì chúng sử dụng pointer theo cách &#8220;không bình thường&#8221;.</p>
<h1 id="toc-cac-don-ma-vi-d">Các đoạn mã ví dụ</h1>
<h2 id="toc-appendnode">AppendNode()</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> AppendNode<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">**</span> headRef, <span style="color: #0000ff;">int</span> data<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> <span style="color: #000040;">*</span>headRef<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newNode<span style="color: #008080;">;</span>
	newNode <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> data<span style="color: #008080;">;</span>
	newNode<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #666666;">// special case for length 0</span>
	<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #000040;">*</span>headRef <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #666666;">// Locate the last node</span>
		<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
			current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> newNode<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-appendnode-s-dng-push">AppendNode() sử dụng Push()</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> AppendNode<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">**</span> headRef, <span style="color: #0000ff;">int</span> data<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> <span style="color: #000040;">*</span>headRef<span style="color: #008080;">;</span>
	<span style="color: #666666;">// special case for the empty list</span>
	<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span>headRef, data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #666666;">// Locate the last node</span>
		<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
			current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		<span style="color: #666666;">// Build the node after the last node</span>
		Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span>, data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-copylist">CopyList()</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> CopyList<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span> <span style="color: #666666;">// used to iterate over the original list</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newList <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// head of the new list</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> tail <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// kept pointing to the last node in the new list</span>
	<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>newList <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// special case for the first new node</span>
			newList <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
			newList<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008080;">;</span>
			newList<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
			tail <span style="color: #000080;">=</span> newList<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
			tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
			tail <span style="color: #000080;">=</span> tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
			tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008080;">;</span>
			tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>newList<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-copylist-with-push">CopyList() with Push()</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Variant of CopyList() that uses Push()</span>
<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> CopyList2<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span> <span style="color: #666666;">// used to iterate over the original list</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newList <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// head of the new list</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> tail <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// kept pointing to the last node in the new list</span>
	<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>newList <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// special case for the first new node</span>
			Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>newList, current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
			tail <span style="color: #000080;">=</span> newList<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
			Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span>, current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// add each node at the tail</span>
			tail <span style="color: #000080;">=</span> tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span> <span style="color: #666666;">// advance the tail to the new last node</span>
		<span style="color: #008000;">&#125;</span>
		current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>newList<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-copylist-with-dummy-node">CopyList() With Dummy Node</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Dummy node variant</span>
<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> CopyList<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span> <span style="color: #666666;">// used to iterate over the original list</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> tail<span style="color: #008080;">;</span> <span style="color: #666666;">// kept pointing to the last node in the new list</span>
	<span style="color: #0000ff;">struct</span> node dummy<span style="color: #008080;">;</span> <span style="color: #666666;">// build the new list off this dummy node</span>
	dummy.<span style="color: #007788;">next</span> <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	tail <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span>dummy<span style="color: #008080;">;</span> <span style="color: #666666;">// start the tail pointing at the dummy</span>
	<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span>, current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// add each node at the tail</span>
		tail <span style="color: #000080;">=</span> tail<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span> <span style="color: #666666;">// advance the tail to the new last node</span>
		current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>dummy.<span style="color: #007788;">next</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-copylist-with-local-references">CopyList() With Local References</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Local reference variant</span>
<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> CopyList<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> current <span style="color: #000080;">=</span> head<span style="color: #008080;">;</span> <span style="color: #666666;">// used to iterate over the original list</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newList <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">**</span> lastPtr<span style="color: #008080;">;</span>
	lastPtr <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span>newList<span style="color: #008080;">;</span> <span style="color: #666666;">// start off pointing to the head itself</span>
	<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>current <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		Push<span style="color: #008000;">&#40;</span>lastPtr, current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// add each node at the lastPtr</span>
		lastPtr <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>lastPtr<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// advance lastPtr</span>
		current <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>newList<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2 id="toc-copylist-recursive">CopyList() Recursive</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Recursive variant</span>
<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> CopyList<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> head<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>head <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">struct</span> node<span style="color: #000040;">*</span> newList <span style="color: #000080;">=</span> <span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> node<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// make the one node</span>
		newList<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data <span style="color: #000080;">=</span> current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>data<span style="color: #008080;">;</span>
		newList<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next <span style="color: #000080;">=</span> CopyList<span style="color: #008000;">&#40;</span>current<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>next<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// recur for the rest</span>
		<span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>newList<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h1 id="toc-other-implementations">Other implementations</h1>
<p style="text-align: justify;">Hãy tham khảo thêm trong tài liệu</p>
<li>Dummy header</li>
<li>Circular</li>
<li>Tail pointer</li>
<li>Head struct</li>
<li>Doubly-linked</li>
<li>Chunk list</li>
<li>Dynamic array</li>
]]></content:encoded>
			<wfw:commentRss>http://www.openandfree.org/blog/?feed=rss2&amp;p=51</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
