Wednesday, August 26, 2015

Một góc nhìn thực tế từ việc tăng hạng tripavisor

Tăng thứ hạng tripadvisor


Tripadvisor hiện nay gần như là một "bản đánh giá chuẩn" cho các dịch vụ của các công ty liên quan đến các dịch vụ về du lịch, ăn uống và một số dịch vụ liên quan.

Qua Tripadvisor, khách hàng sẽ biết được, các "khách hàng" trước đó đã đánh giá về chất lượng dịch vụ của bên bạn như thế nào. Dựa vào các đánh giá đó mà khách hàng mới sẽ quyết định xem có đặt dịch vụ bên bạn hay không.




Tuy nhiên, hiện nay có một tình trạng chung mà các công ty thường gặp phải đó là các khách hàng tốt có cảm nhận tốt thì lại ít có thời gian lên tripadvisor để viết review cho bạn, các các khách hàng không có cảm nhận tốt thì lại lên tripadvisor phàn nàn về dịch vụ của bạn.

Để giải quyết một phần nào đó vấn đề gặp phải này, công ty TNHH Giá Trị Thực Việt Nam cung cấp cho các bạn một giải pháp tăng lượng review của khách hàng đối với dịch vụ của bên bạn.

Nhưng ...

Một câu hỏi đặt ra là, tăng bao nhiêu reviews cho đủ, và tăng như vậy sẽ giải quyết được vấn đề gì cho các bạn?

Chúng tôi xin khẳng định là chúng tôi không giải quyết vấn đề thay các bạn được, nếu dịch vụ của các bạn không tốt thì chúng tôi có hỗ trợ các bạn bao nhiêu cũng không đủ, mà song song với việc "đánh bóng" trên tripadvisor, các bạn cần phải cải thiện lại các dịch vụ của bên bạn.

Đó là lý do tại sao chúng tôi chỉ đưa ra các gói hữu hạn và số lượng không quá lớn các review khách hàng có thể đặt chúng tôi hàng tháng, đồng thời, trong quá trình tiếp xúc với khách hàng, chúng tôi sẽ tư vấn cho khách hàng các phương án để cải thiện lại hình ảnh, các giải pháp marketing cũng như tăng chất lượng dịch vụ cho khách hàng.

Một lần nữa, chúng tôi khẳng định là chúng tôi không thể giải quyết được các vấn đề về chất lượng dịch vụ của các bạn mà để có được các review thực sự của khách hàng, các bạn phải nâng được chất lượng dịch vụ của mình lên.

Bài viết được viết bởi: Công ty TNHH Giá Trị Thực Việt Nam

Friday, July 27, 2007

ClickOnce Deployment in .NET Framework 2.0

ClickOnce Deployment in .NET Framework 2.0
By Thiru Thangarathinam
Rating: 4.2 out of 5
Rate this article

It is very common among the developers of previous generations to choose web applications over rich Windows UIs because of the deployment challenges associated with deploying a Smart Client Windows Forms application. However with the release of Visual Studio 2005, Microsoft has released a new technology named ClickOnce that is designed to solve the deployment issues for a windows forms application. This new technology not only provides an easy application installation mechanism but also enables easy deployment of upgrades to existing applications. This article will demonstrate how to take advantage of the excellent features of the ClickOnce deployment technology by discussing examples on how to utilize this new feature.

Introduction

Since the introduction of the powerful server side web technologies such as ASP, JSP, ASP.NET, developers have shown more interest in building web applications rather than in windows applications. The factors that attracted the developers toward web applications can be summarized as follows:

  • A web application is ubiquitous, making it accessible in all the places where an internet connection is available.
  • The second and most important factor is the deployment. With web applications, there is no need to deploy any software on the client side. All the client application needs is just the browser. This makes it possible for the developers to easily deploy updates to the existing web application without impacting the client machines.

If you talk to the developers, you will find that the main reason for preference for web applications over windows applications is the second point in the above list. Even though this is true with traditional applications, Microsoft is making every attempt to ensuring that windows applications can be deployed and updated with the same ease as the web applications. You can see proofs of this in the initial release of .NET Framework when Microsoft introduced the deployment of windows forms application through HTTP. Using this approach, you could simply use HREF HTML element to point to a managed executable (.exe). Then when you click on the HREF link, Internet Explorer can automatically download and install the executable on the client machine. Even though this approach sounds very promising, it also presents some interesting challenges. One of the most important challenges is the downloading of the updated code through the HTTP. Since this process was not transacted, it was possible for the application to be left in an inconsistent state. Moreover there was no way for you to specify if the application could work in offline mode apart from the traditional online mode. Combined with the operational mode issue, this approach also did not provide the ability to create shortcuts that can be used to launch the application. Even though this approach presented itself with a lot of issues, it could still be used in controlled environments. However for complex multi-assembly dependant windows forms applications, you needed a transacted and easily updateable way of deployment. This is exactly what the ClickOnce technology introduced with .NET Framework 2.0 provides. In this article, we will see how to effectively use this technology to deploy a windows form application.

How does ClickOnce Deployment Technology Work?

Before we look at an example, let us understand how this technology works.

  • You create a Windows forms application and use the Publish option to deploy the application onto any of the following locations: File System, Local Web Server, FTP Site, or a Remote Web Site.
  • Once the application is deployed onto the target location, the users of the application can browse to the publish.htm file and install the application onto their machine. Note that publish.htm file is the entry point for installing the application and this will be discussed in the later part of this article.
  • Once the user has installed the application, a shortcut icon will be added to the desktop and the application will also be listed in the Control Panel/Add Remove Programs.
  • When the user launches the application again, the manifest will contain all the information to decide if the application should go to the source location and check for updates to the original application. Let us say, for instance, a newer version of the application is available, it will be automatically downloaded and made available to the user. Note that when the new version is downloaded, it is performed in a transacted manner meaning that either the entire update is downloaded or nothing is downloaded. This will ensure that the application integrity is preserved.

Let us look at an example to understand this.

A Simple ClickOnce Deployment Example

Let us start by creating a simple Visual C# Windows forms application named ClickOnceDemo using Visual Studio 2005. Once the project is created, place a command button on the form and double click on the command button and modify its code to look like the following.

private void btnClick_Click(object sender, EventArgs e)
{
MessageBox.Show(System.Reflection.Assembly.
GetExecutingAssembly().Location);
}

If you run the ClickOnceDemo application and click on the button, you will see an output that is somewhat similar to the following depending on the location of your project folder.

Now that we have created the application, let us publish it. But before we do that, let us look at some of the properties associated with publishing of the forms application. Right click on the ClickOnceDemo project from the solution explorer and select Properties from the context menu. You should see the following dialog box being displayed.

The Publish tab in the Project Properties dialog box shown in the above screenshot provides a number of options for configuring publish related settings. Let us look at each one of these options in detail.

At the top of the properties page is the Publishing Location dropdown box that allows you to specify the location in which the application will be published. When you click on the ... button right next to the dropdown, it brings up the following window wherein you can specify the target virtual directory for publishing.

Using the Publish properties dialog box, you can also specify if the application is available only in online mode or in both online and offline modes. This option is available in the Install Mode and Settings panel. This panel also contains options that let you specify the prerequisites for your windows forms application. To specify this, click on the Prerequisites... command button and you will see the following dialog box.

By default, the .NET Framework 2.0 option will be checked and you can choose any of the remaining options depending on your application requirements.

Right below the Prerequisities option, there is a command button named Updates... that lets you configure the manner and timing in which the updates to the application will be delivered to the client machine. Clicking on the Updates... button will result in the following dialog box.

As you can see from the above dialog box, you have a number of options that allow you to exercise finer level of control over the application updates.

Right below the Updates button is the Options... button that brings up the following dialog box when clicked.

Using the Publish options, you can not only indicate the language in which the application will be published but also specify the Start menu shortcut name. Once you publish this application to the target location, the root directory of the application install will contain a file called publish.htm, which you can use to launch the application on the client machine. By default, the name of the file is set to publish.htm and can be modified using the above dialog box.

Now that we have a understanding of the properties in a general sense, let us see how to publish the application.

Publishing the Application

To publish the application, start by selecting Publish ClickOnceDemo from the Publish menu. This will bring up the first step in the publish wizard, which is shown below.

In the above dialog box, you can specify the location where you want to publish the application. The locations to which you can deploy the application are: File System, Local IIS, FTP Sites, and Remote Sites. For the purposes of this example, let us leave the default value of http://localhost/ClickOnceDemo. Clicking Next in the above dialog box will result in the following dialog box, which allows you to specify the modes in which the application will be available.

The default value in the above screen is dependant on the value set in the Install Mode Settings panel of the Publish properties dialog box. Then click Next and you will be asked to specify the key file used for strongly signing the application. Since we haven't created a key file yet, select the option that says "" as shown in the following screenshot.

Clicking Next in the above dialog box will bring up the Confirm dialog box, wherein you can hit Finish to complete the publishing.

If you hit Finish in the above dialog box, Visual Studio will build the project, publish the application to the ClickOnceDemo folder under the default web site, and then automatically bring up the publish.htm file in the browser. Before we look at the publish.htm file, let us examine the files generated by the wizard. Navigate to the ClickOnceDemo folder in the default web site through the Windows explorer. You will see the following screenshot.

The ClickOnceDemo_1.0.0.0 folder is the one that contains the .exe file and the corresponding manifest files. Since we mentioned that the prerequisites (specified through the Publish properties dialog box in the earlier section) for this application is .NET Framework 2.0, Visual Studio automatically created a folder named dotnetfx that contained the executable for installing the .NET Framework 2.0. Now that we have had a look at the files created by the wizard, let us turn our focus to the publish.htm that provides a means for launching the application.

As you can see from the above screenshot, this html page enables you to install the ClickOnceDemo application through a hyperlink. Click the Install ClickOnceDemo hyperlink to install the application. You will be presented with the following dialog box, wherein you can just hit Install to continue the installation.

Once the application is installed, it will automatically execute the application and bring up the form. Click on the command and you will see an output that is somewhat similar to the following.

As you can see, now the path displayed the message box is different than the previously generated message box. This is because of the fact that the application is now downloaded and locally cached in the folder shown in the above message box. If you navigate to that folder from windows explorer, you will see folders as listed in the following screenshot. These folders contain files such as manifests, and the actual executable itself and so on.

You will also notice the following changes as a result of the installation.

  • An icon is added to the Start menu
  • An entry is added in Control Panel -> Add/Remove Programs.

From this point onwards, you can launch the application through the shortcut in the Start -> Programs menu. From Add/Remove Programs, you can either completely uninstall the application or revert to the previous version, if there was one.

Conclusion

The features of ClickOnce we have seen in this article are only the tip of the iceberg and it offers many more benefits. However, the key motivation for using ClickOnce is the ease of deployment, installation, and versioning for your Windows Forms applications.

Paging in SQL Server 2005

15 Seconds : Paging in SQL Server 2005
David Beahm
06/28 / 2007

Introduction

Developers and database administrators have long debated methods for paging recordset results from Microsoft SQL Server, trying to balance ease of use with performance. The simplest methods were less efficient because they retrieved entire datasets from SQL Server before eliminating records which were not to be included, while the best-performing methods handled all paging on the server with more complex scripting. The ROW_NUMBER() function introduced in SQL Server 2005 provides an efficient way to limit results relatively easily.

Paging Efficiency

In order to scale well, most applications only work with a portion of the available data at a given time. Web-based data maintenance applications are the most common example of this, and several data-bindable ASP.NET classes (such as GridView and Datagrid) have built-in support for paging results. While it is possible to handle paging within the web page code, this may require transferring all of the data from the database server to the web server every time the control is updated. To improve performance and efficiency, data which will not be used should be eliminated from processing as early as possible.

Paging Methods

Many popular databases offer functions allowing you to limit which rows are returned for a given query based upon their position within the record set. For example, MySQL provides the LIMIT qualifier, which takes two parameters. The first LIMIT parameter specifies which (zero-based) row number will be the first record returned, and the second parameter specifies the maximum number of records returned. The query:

SELECT * FROM table LIMIT 20,13

...will return the 20th through the 32nd records -- assuming at least 33 records are available to return. If fewer than 33 records are available, the query will return all records from record 20 on. If fewer than 20 records are available, none will be returned.

SQL Server does not have this functionality, however the 2005 release does have a number of other new tricks. For instance, support for CLR procedures means it is possible to use existing paging methods to write VB.NET or C# code that would execute within the SQL Server environment. Unfortunately, CLR procedures are not as efficient as native Transact SQL. To ensure best performance, queries should still be written in TSQL whenever practical.

Using ROW_NUMBER()

TSQL in the 2005 release includes the ROW_NUMBER() function, which adds an integer field to each record with the record's ordinal result set number. Stated more simply, it adds the record's position within the result set as an additional field so that the first record has a 1, the second a 2, etc. This may appear to be of little value, however by using nested queries we can use this to our advantage.

To demonstrate ROW_NUMBER() and to explore how the paging solution works, create a simple salary table and populate it with random data using the following commands:

CREATE TABLE [dbo].[Salaries](
[person] [nvarchar](50) NOT NULL,
[income] [money] NOT NULL,
CONSTRAINT [PK_salaries] PRIMARY KEY CLUSTERED(
[person] ASC
)) ON [PRIMARY]
GO

INSERT INTO Salaries VALUES ('Joe', '28000')
INSERT INTO Salaries VALUES ('Sue', '96000')
INSERT INTO Salaries VALUES ('Michael', '45000')
INSERT INTO Salaries VALUES ('John', '67000')
INSERT INTO Salaries VALUES ('Ralph', '18000')
INSERT INTO Salaries VALUES ('Karen', '73000')
INSERT INTO Salaries VALUES ('Waldo', '47000')
INSERT INTO Salaries VALUES ('Eva', '51000')
INSERT INTO Salaries VALUES ('Emerson', '84000')
INSERT INTO Salaries VALUES ('Stanley', '59000')
INSERT INTO Salaries VALUES ('Jorge', '48000')
INSERT INTO Salaries VALUES ('Constance', '51000')
INSERT INTO Salaries VALUES ('Amelia', '36000')
INSERT INTO Salaries VALUES ('Anna', '49000')
INSERT INTO Salaries VALUES ('Danielle', '68000')
INSERT INTO Salaries VALUES ('Stephanie', '47000')
INSERT INTO Salaries VALUES ('Elizabeth', '23000')

The ROW_NUMBER() function has no parameters - it simply adds the row number to each record in the result set. To ensure the numbering is consistent, however, SQL Server needs to know how to sort the data. Because of this, ROW_NUMBER() must immediately be followed by the OVER() function. OVER() has one required parameter, which is an ORDER BY clause. The basic syntax for querying the Salaries table is:

SELECT ROW_NUMBER() OVER(ORDER BY person), person, income
FROM Salaries

This returns the following result:

(No column name)personincome
1Amelia36000.00
2Anna49000.00
3Constance51000.00
4Danielle68000.00
5Elizabeth23000.00
6Emerson84000.00
7Eva51000.00
8Joe28000.00
9John67000.00
10Jorge48000.00
11Karen73000.00
12Michael45000.00
13Ralph18000.00
14Stanley59000.00
15Stephanie47000.00
16Sue96000.00
17Waldo47000.00

The Salaries data now appears sorted by person, and it has an extra column indicating each record's position within the results.

If for any reason you wanted the results to display in a different order than they were numbered in, you can include a different ORDER BY clause as part of the normal SELECT syntax:

SELECT ROW_NUMBER() OVER(ORDER BY person), person, income
FROM Salaries
ORDER BY income

This returns the following result:

(No column name)personincome
13Ralph18000.00
5Elizabeth23000.00
8Joe28000.00
1Amelia36000.00
12Michael45000.00
15Stephanie47000.00
17Waldo47000.00
10Jorge48000.00
2Anna49000.00
3Constance51000.00
7Eva51000.00
14Stanley59000.00
9John67000.00
4Danielle68000.00
11Karen73000.00
6Emerson84000.00
16Sue96000.00

If we want to limit the results displayed to a certain range, we need to nest this SELECT inside another one and provide a name for the ROW_NUMBER() column. To limit our results to records 5 through 9, we can use the following query:

SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY person) AS
rownum, person, income FROM Salaries) AS Salaries1
WHERE rownum >= 5 AND rownum <= 9

This returns the following result:

rownumpersonincome
5Elizabeth23000.00
6Emerson84000.00
7Eva51000.00
8Joe28000.00
9John67000.00

Again, we can change the sort order by adding an ORDER BY clause. This is most easily accomplished by using the outer SELECT statement:

SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY person) AS
rownum, person, income FROM Salaries) AS Salaries1
WHERE rownum >= 5 AND rownum <= 9
ORDER BY income

This returns the following result:

rownumpersonincome
5Elizabeth23000.00
8Joe28000.00
7Eva51000.00
9John67000.00
6Emerson84000.00

If we want to support the same type of arguments that MySQL's LIMIT() supports, we can create a stored procedure that accepts a beginning point and a maximum number of records to return. ROW_NUMBER requires that the data be sorted, so we will also have a required parameter for the ORDER BY clause. Execute the following statement to create a new stored procedure:

CREATE PROCEDURE [dbo].[pageSalaries]
@start int = 1
,@maxct int = 5
,@sort nvarchar(200)
AS
SET NOCOUNT ON
DECLARE
@STMT nvarchar(max), -- SQL statement to execute
@ubound int

IF @start < 1 SET @start = 1
IF @maxct < 1 SET @maxct = 1
SET @ubound = @start + @maxct
SET @STMT = ' SELECT person, income
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ' + @sort + ') AS row, *
FROM Salaries
) AS tbl
WHERE row >= ' + CONVERT(varchar(9), @start) + ' AND
row < ' + CONVERT(varchar(9), @ubound)
EXEC (@STMT) -- return requested records

The pageSalaries procedure begins with SET NOCOUNT ON to disable the record count message (a common step for optimizing query performance). We then declare two necessary variables, @STMT and @ubound. Because we want to be able to change what ORDER BY argument is used, we need to dynamically generate our query statement by storing it in @STMT. The next lines ensure that only positive numbers are used for the starting position and maximum size, then calculate the range of ROW_NUMBER() values being requested. (If we wanted to be zero-based like MySQL's LIMIT, we could do so with a few minor tweaks.) Once the dynamic SQL command has been strung together, it is executed so that the results are returned.

Execute the following statement to test the stored procedure:

pageSalaries 4, 7, 'income'

This returns the following result:

personincome
Amelia36000.00
Michael45000.00
Stephanie47000.00
Waldo47000.00
Jorge48000.00
Anna49000.00
Constance51000.00

If we execute:

pageSalaries 13, 7, 'income'

we receive back:

personincome
John67000.00
Danielle68000.00
Karen73000.00
Emerson84000.00
Sue96000.00

... because the query goes beyond the number of records available.

Taking this one step further, we can make a stored procedure that does a more general form of paging. In fact, it can be generalized to the point that it can be used to return any collection of fields, in any order, with any filtering clause. To create this wunderkind marvel, execute the following command:

CREATE PROCEDURE [dbo].[utilPAGE]
@datasrc nvarchar(200)
,@orderBy nvarchar(200)
,@fieldlist nvarchar(200) = '*'
,@filter nvarchar(200) = ''
,@pageNum int = 1
,@pageSize int = NULL
AS
SET NOCOUNT ON
DECLARE
@STMT nvarchar(max) -- SQL to execute
,@recct int -- total # of records (for GridView paging interface)

IF LTRIM(RTRIM(@filter)) = '' SET @filter = '1 = 1'
IF @pageSize IS NULL BEGIN
SET @STMT = 'SELECT ' + @fieldlist +
'FROM ' + @datasrc +
'WHERE ' + @filter +
'ORDER BY ' + @orderBy
EXEC (@STMT) -- return requested records
END ELSE BEGIN
SET @STMT = 'SELECT @recct = COUNT(*)
FROM ' + @datasrc + '
WHERE ' + @filter
EXEC sp_executeSQL @STMT, @params = N'@recct INT OUTPUT', @recct = @recct OUTPUT
SELECT @recct AS recct -- return the total # of records

DECLARE
@lbound int,
@ubound int

SET @pageNum = ABS(@pageNum)
SET @pageSize = ABS(@pageSize)
IF @pageNum < 1 SET @pageNum = 1
IF @pageSize < 1 SET @pageSize = 1
SET @lbound = ((@pageNum - 1) * @pageSize)
SET @ubound = @lbound + @pageSize + 1
IF @lbound >= @recct BEGIN
SET @ubound = @recct + 1
SET @lbound = @ubound - (@pageSize + 1) -- return the last page of records if -- no records would be on the
-- specified page
END
SET @STMT = 'SELECT ' + @fieldlist + '
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ' + @orderBy + ') AS row, *
FROM ' + @datasrc + '
WHERE ' + @filter + '
) AS tbl
WHERE
row > ' + CONVERT(varchar(9), @lbound) + ' AND
row < ' + CONVERT(varchar(9), @ubound)
EXEC (@STMT) -- return requested records
END

You may receive the following error message from SQL Server, which you can confidently ignore:

Cannot add rows to sys.sql_dependencies for the stored procedure because it depends on the missing table 'sp_executeSQL'. The stored procedure will still be created; however, it cannot be successfully executed until the table exists.

The utilPage procedure accepts 6 parameters:

@datasrc - the table (or stored procedure, etc.) name
@orderBy- the ORDER BY clause
@fieldlis- the fields to return (including calculated expressions)
@filter- the WHERE clause
@pageNum- the page to return (must be greater than or equal to one)
@pageSize- the number of records per page

The stored procedure needs the name of a data source to query against (such as a table) and one or more fields to sort by (since OVER() requires an ORDER BY clause). If @filter is blank (the default), it will be set to "1 = 1" as a simple way to select all records. If @pageSize is not supplied, the query will run without paging and will not return a record count.

If, however, @pageSize is supplied, a version of the query is executed to get the total number of records. In order to have this record count available within the procedure and as a returned value, we use sp_executeSQL to support executing the statement while returning an output parameter. The record count is used to prevent returning empty results when possible, and to support paging interfaces that calculate the number of pages available (such as GridView). If we were calling this stored procedure to populate a GridView, we would return @recct as a ReturnValue parameter instead of using a result set, but we will use a result set for demonstration purposes.

The procedure calculates what the actual record positions will be for the requested page. Rather than allow the query to fail, there are safety checks ensuring that @pageSize and @pageNum are greater than zero, and that the result set will not be empty. If the specified page is out of range, this procedure will return the last possible page of records. This is helpful if a user changes more than one setting before refreshing their data, or if a significant amount of data is deleted between requests.

The remainder of the procedure is virtually identical to the pageSalaries procedure. To test the utilPAGE stored procedure, execute the following statement:

utilPAGE 'Salaries', 'person', '*', 'income > 1000', 2, 4

This returns the following two result sets:

recct
17

rowpersonincome
5Elizabeth23000
6Emerson84000
7Eva51000
8Joe28000

If we execute:

utilPAGE 'Salaries', 'person', 'person, income', '', 13, 3

...we receive back:

recct
17

personincome
Stephanie47000
Sue96000
Waldo47000

Even though the request should be for records 36 through 38 - far outside of what is available - the procedure returns the last available page of records. In contrast, requesting the third page with seven records per page using:

utilPAGE 'Salaries', 'person', 'person, income', '', 3, 7

...returns the last three records, as the page is not completely out of bounds:

personincome
Stephanie47000
Sue96000
Waldo47000

All of these examples are based on simple single-table queries, which may not reflect what you need in the real world. While the utilPAGE procedure does not support ad-hoc JOINs, it does work with SQL Views. If you want paging support for multi-table queries, you should create a View (with all of the necessary JOINs) to use as the data source. Using a View follows good design practices as it ensures that your Joins are performed consistently, allows easier ad-hoc querying from the command line, and is much easier to troubleshoot than a stored procedure's dynamic SELECT statement logic.

Conclusion

While SQL Server does not have as simple a method for paging results as some other databases, features introduced in the 2005 release have made it possible to page results efficiently more easily than ever before. In the next article in this series, we will go a step further and integrate this paging logic with a GridView through a Data Access Layer.

Sunday, April 01, 2007

Bill Gates của Ấn Độ

Trong danh sách những doanh nhân thành đạt ở lĩnh vực công nghệ thông tin của thế giới nếu có Bill Gates ở Mỹ, Masayoshin Son ở Nhật thì người ta cũng không thể quên được Narayana Murthy. Ông là nhân vật có vai trò lớn trong việc phát triển công nghệ thông tin và tạo việc làm tại Ấn Độ.

Không chỉ là người sáng lập, điều hành và phát triển Infosys Technologies Limited từ một công ty nhỏ thành một trong những công ty lớn quy mô thế giới. Cùng với những thành công đã đạt được, Narayana Murthy cũng tự đưa mình lên vị trí một trong những doanh nhân giầu nhất Ấn Độ với tổng tài sản cá nhân 1,3 tỷ USD. Từ số tiền ít ỏi 10.000 Rupee (tương đương với 250 USD), năm 1981, Công ty Infosys Technologies Limited được thành lập và bắt đầu từ những hoạt động nhập và phân phối máy tính nhỏ lẻ.

Theo thời gian, nhờ liên tục đạt được những kỷ lục kinh doanh, Infosys Technologies Limited đã dần tạo dựng được chỗ đứng, tiến tới chiếm lĩnh được thị trường công nghệ thông tin Ấn Độ rộng lớn. Sau hơn 20 năm không ngừng phát triển, Infosys Technologies Limited đã có được nguồn tài chính khổng lồ lên tới hàng chục tỷ USD, mở rộng được mạng lưới kinh doanh với hơn 600 chi nhánh, sử dụng 200.000 kỹ sư điện tử, tin học và là một trong những thế lực hùng mạnh hàng đầu trong lĩnh vực công nghệ thông tin tại Ấn Độ.

Khởi nghiệp từ 10.000 Rupee

Narayana Murthy là người gốc Ấn Độ, sinh ngày 20 tháng 8 năm 1946 tại Karnataka - một tỉnh nhỏ của Ấn Độ. Bố của Narayana Murthy là một thầy giáo dạy toán tại trường học ở huyện Kolar, Karnataka.

Nổi tiếng là một học sinh thông minh, chăm chỉ, đặc biệt say mê môn toán và những môn học tự nhiên, ngay từ khi còn học trung học Narayana Murthy luôn là học sinh đứng đầu trong lớp. Năm 1967, sau khi kết thúc chương trình đào tạo kỹ sư điện tử của trường University of Mysore, ông tiếp tục dành thời gian và tâm huyết theo học chương trình thạc sĩ công nghệ thông tin tại trường Indian Institute of Technology ở Kanpur. Năm 1969, sau 2 năm miệt mài với các đề tài nghiên cứu, Narayana Murthy đã tốt nghiệp với tấm bằng thạc sĩ công nghệ thông tin.

Trong những năm mới ra trường, với ước mơ tạo dựng sự nghiệp từ những gì đã được học, Narayana Murthy quyết định sang Pháp để thử sức mình. Tại Paris, ông xin vào làm việc tại một công ty thiết kế đồ họa. Cùng với một số thành viên khác, ông được giao phác thảo sơ đồ thời gian bốc dỡ hàng hóa cho sân bay Charles de Gaulle trên máy tính.

Sau hơn 3 năm làm việc ở Pháp, Narayana Murthy quay trở lại Ấn Độ và xin vào làm việc tại Công ty Patni Computer Systems tại Pune với công việc xuất nhập khẩu máy tính. Qua một thời gian làm việc thực tế tại đây, ông học được những kiến thức kinh doanh cơ bản và bắt đầu nghĩ tới việc làm sao thành lập công ty riêng chuyên kinh doanh máy tính.

Năm 1981, sau một thời gian chuẩn bị, Narayana Murthy đã thành lập Công ty Infosys Technologies Limited và đặt trụ sở tại Bangalore. Bằng khả năng phân tích nhanh nhạy của mình, ông đã hiểu được tầm quan trọng của công nghệ thông tin đối với sự phát triển của đất nước trong thời kỳ công nghệ thông tin bắt đầu bùng nổ, việc Chính phủ khuyến khích và tiến hành các dự án đầu tư phát triển công nghệ thông tin là điều sẽ diễn ra. Thêm vào đó, các doanh nghiệp muốn phát triển sẽ phải cần đến sự trợ giúp của hệ thống công nghệ thông tin. Để chớp lấy cơ hội ngàn năm có một này, Narayana Murthy đã nhanh chóng đầu tư hầu như toàn bộ nguồn vốn của Infosys Technologies Limited vào nhập và phân phối lẻ các loại máy tính. Nhờ đó, công ty đã bắt đầu có được tên tuổi và vị trí tại một số thị trường công nghệ thông tin Ấn Độ.

Biến khó khăn thành cơ hội bứt phá

Là một chuyên gia công nghệ thông tin từng trải qua 3 năm làm việc thực tiễn ở Pháp, Narayana Murthy đã hiểu được tầm quan trọng của đội ngũ nhân viên có trình độ cao, đặc biệt là khả năng làm việc tập thể - điều mà rất nhiều các doanh nghiệp châu Á chưa có được. Do vậy, ông luôn công bằng, rộng lượng, ngoài những chế độ lương bổng và những khoản thưởng cho nhân viên. Narayana Murthy cũng đặc biệt ưu đãi những nhân tài trẻ tuổi, những nhóm nhân viên kết hợp làm việc thực sự hiệu quả trong công ty.

Vào thời điểm những năm 80 và 90, công nghệ thông tin của Ấn Độ bắt đầu bùng nổ, mạng Internet bắt đầu có những bước chuyển mình, các công ty mọc lên như nấm để khai thác thị trường béo bở này. Đó cũng là thời điểm mức độ cạnh tranh ngày càng nóng, không ít người đã cảm thấy lo lắng vì một số công ty do không chịu được sức ép của thị trường đã phải sập tiệm. Tuy nhiên, đối với Narayana Murthy, mọi việc vẫn bình thường và chẳng có gì đáng lo ngại vì những khó khăn đó, ông dự đoán được từ trước và đã có những phương sách ứng phó.

Khi thị trường công nghệ thông tin trở nên sôi động, Narayana Murthy liên tục đầu tư ứng dụng kỹ thuật tiên tiến hàng đầu thế giới từ thung lũng Silicon vào chương trình nâng cao chất lượng các sản phẩm máy tính, phần mềm, cơ sở dữ liệu của Infosys Technologies Limited. Điều này đã giúp các sản phẩm của công ty vượt trội về chất lượng cũng như hình thức so với các sản phẩm khác. Mặt khác, Narayana Murthy chủ động hướng Infosys Technologies Limited tập trung vào khai thác và phát triển chi nhánh tại các vùng nông thôn nghèo của Ấn Độ, tránh những khu vực có sức ép cạnh tranh quá nóng.

Vì vậy, trong cuộc cạnh tranh khốc liệt, các sản phẩm công nghệ thông tin, máy tính, phần mềm, dịch vụ... do công ty cung cấp vẫn là sự lựa chọn hàng đầu của người tiêu dùng. Infosys Technologies Limited không bị suy yếu đi mà càng mạnh hơn, thị trường của công ty ngày càng được mở rộng từ thành thị tới các vùng nông thôn và chính thức từ hạng trung vươn lên vị trí một trong những công ty đầu đàn tầm cỡ quốc tế trong lĩnh vực công nghệ thông tin tại Ấn Độ.

Với nguồn tài chính hùng mạnh hàng chục tỷ đôla, Infosys Technologies Limited chính là công ty công nghệ thông tin đầu tiên của Ấn Độ tham gia vào thị trường chứng khoán Nasdaq của Mỹ.
Từ những chương trình đầu tư vào phát triển mạng công nghệ thông tin ở các vùng nông thôn Ấn Độ cho tới việc thiết lập các mối quan hệ hợp tác với các công ty, tập đoàn công nghệ thông tin của Mỹ, châu Âu do chính Narayana Murthy tiến hành đã góp phần giúp cho lĩnh vực công nghệ thông tin của Ấn Độ tiếp thu và phát triển được những công nghệ tiên tiến hàng đầu thế giới, bắt kịp được với sự phát triển công nghệ thông tin của toàn cầu hiện nay.

Thông qua mạng lưới hơn 600 chi nhánh của Infosys Technologies Limited hoạt động rộng khắp ở Ấn Độ, Narayana Murthy còn góp phần giải quyết cho xã hội hàng nghìn việc làm mỗi năm.

Monday, March 19, 2007

10 công cụ miễn phí tốt nhất cho .NET

Không thể có ứng dụng tốt nếu không có công cụ phát triển tốt, dù là phát triển với bất kỳ ngôn ngữ (lập trình) nào, ngay cả với các ngôn ngữ ‘mạnh’ của nền tảng .NET hiện đang ‘nổi đình nổi đám’. Ngoài công cụ phát triển ứng dụng ‘chính thống’ và ‘đồ sộ’ như Visual Studio .NET (VS.NET) của Microsoft, cộng đồng phát triển .NET hiện nay có thêm nhiều lựa chọn với các công cụ gọn nhẹ hơn và đặc biệt là có mã nguồn mở hay miễn phí.

Bài viết này giới thiệu 10 công cụ miễn phí tốt nhất dành cho các nhà phát triển .NET, trong số đó có những công cụ giúp phát triển ứng dụng nhanh hơn và có những công cụ có thể làm thay đổi hẳn cách thức bạn viết mã lệnh (code).

SNIPPET COMPILER

Snippet Compiler (http://www.sliver.com/dotnet/SnippetCompiler) là công cụ dùng để viết code, biên dịch và chạy, nó đặc biệt có ích đối với những đoạn code nhỏ (khi bạn không muốn tạo toàn bộ project VS.NET cùng với các tập tin đi kèm).

Ví dụ, đoạn code dưới đây gọi chạy một ứng dụng khác (Notepad) từ .NET. Bạn có thể thực thi (chạy) đoạn code này ngay trong Snippet Compiler (chỉ việc nhấn nút Play).

using System;

using System.Collections;

public class MyClass {

public static void Main() {

System.Diagnostics.Process proc = new System.Diagnostics.Process();

proc.StartInfo.FileName= ‘notepad.exe’;

proc.Start();

proc.WaitForExit();

}

}

REGULATOR

Regulator (http://royo.is-a-geek.com/regulator) là công cụ hoàn chỉnh dùng để biên dịch và kiểm tra biểu thức chuỗi, đây là vấn đề hiện được quan tâm vì được ứng dụng nhiều trong .NET. Biểu thức chuỗi được dùng để định nghĩa các chuỗi ký tự và số, thường được dùng để so trùng dữ liệu người dùng nhập vào hay để tìm chuỗi ký tự trong một chuỗi lớn hơn.

Regulator cho phép bạn nhập vào một biểu thức chuỗi và dữ liệu đầu vào để kiểm tra. Bằng cách này bạn có thể thấy cách thức làm việc của biểu thức và kết quả trả về trước khi thực hiện trong ứng dụng.

Một trong những đặc tính hấp dẫn nhất của Regulator là khả năng tìm thư viện biểu thức trực tuyến ở regexlib.com. Ví dụ, nếu nhập vào chuỗi ‘phone’ trong ô tìm kiếm, bạn sẽ tìm thấy hơn 20 biểu thức khác nhau so khớp số điện thoại, bao gồm các biểu thức áp dụng cho số điện thoại ở Anh, Úc…

CODESMITH

CodeSmith (http://ericjsmith.net/codesmith) là công cụ sinh mã dựa trên template (mẫu có sẵn) dùng cú pháp tương tự như ASP.NET để sinh ra dạng code hay text bất kỳ, từ tập hàm đơn giản đến toàn bộ ứng dụng. Không giống như nhiều công cụ sinh mã khác, CodeSmith không yêu cầu bạn mô tả thiết kế hay kiến trúc ứng dụng.

Khi xây dựng ứng dụng, bạn nhận thấy thường phải lặp đi lặp lại một số công việc, ví dụ như viết code truy cập dữ liệu hay xây dựng hàm. CodeSmith đặc biệt hữu dụng trong những tình huống như vậy, vì nó cho phép bạn tạo các template để thực hiện tự động các công việc này, không chỉ cải thiện hiệu suất làm việc mà còn tránh cho bạn sự nhàm chán.

CodeSmith có sẵn một số template, bao gồm các kiểu tập hợp .NET cũng như thủ tục, nhưng sức mạnh thực sự của công cụ này chính là khả năng tạo template riêng.

Template của CodeSmith là tập tin văn bản đơn thuần và bạn có thể tạo bằng công cụ soạn thảo văn bản bất kỳ, chỉ với yêu cầu là lưu lại với đuôi .cst. Đầu tiên, bạn tạo phần đầu khai báo ngôn ngữ dùng cho template, ngôn ngữ kết quả và mô tả vắn tắt template.

<%@ CodeTemplate Language=’C#’
TargetLanguage=’C#’
Description=’Car Template’ %>

Phần kế tiếp của template khai báo các thuộc tính sẽ được xác định khi template chạy. Ví dụ dưới đây khai báo một thuộc tính chuỗi (string).

<%@ Property Name=’ClassName’ Type=’String’ Category=’Context’
Description=’Class Name’ %>

Bước tiếp theo xây dựng phần thân template với mã lệnh tương tự ASP.NET, bạn có thể dùng bất kỳ lệnh .NET nào.

CodeSmith khá dễ dùng và có thể cho ra những kết quả tuyệt vời nếu được sử dụng đúng đắn. Một trong những phần phổ biến nhất của ứng dụng thích hợp cho việc sinh mã là truy cập dữ liệu. CodeSmith có tích hợp thành phần đặc biệt gọi là SchemaExplorer có thể dùng để sinh các template cho bảng dữ liệu (table), thủ tục lưu trữ (stored procedure) và gần như bất kỳ đối tượng SQL Server.

NUNIT

NUnit (hhtp://www.nunit.org) là khung kiểm tra đơn vị chương trình (như lớp, hàm hay module) có mã nguồn mở. Được phát triển theo mô hình JUnit (công cụ kiểm tra nổi tiếng dùng cho Java), nhưng NUnit được viết bằng C# và khai thác được ưu điểm của các ngôn ngữ .NET.

NUnit cho phép bạn viết hàm kiểm tra lỗi (unit test) theo ngôn ngữ lựa chọn để kiểm tra một chức năng cụ thể của chương trình. Unit test là cách thức tốt để kiểm tra hoạt động của đoạn code viết mới, và cũng là một phương thức kiểm tra hồi quy ứng dụng. Các unit test có thể lưu lại và chạy lại mỗi khi bạn sửa đổi code, điều này giúp phát hiện lỗi dễ dàng hơn và đảm bảo phát triển ứng dụng tốt hơn.

NUnit cung cấp khung để viết các unit test, và còn có giao diện đồ họa để chạy các unit test và xem kết quả. Ví dụ, chúng ta sẽ kiểm tra hoạt động của lớp Hashtable trong .NET với việc thêm vào và lấy ra 2 đối tượng. Bước đầu tiên là tham chiếu đến NUnit.Framework để có thể dùng các thuộc tính và hàm của NUnit; kế tiếp, tạo một lớp và đánh dấu nó với thuộc tính [TestFixture] để NUnit biết lớp này có hàm kiểm tra.

using System;

using System.Collections;

using NUnit.Framework;

namespace NunitExample {

[TestFixture]

public class HashtableTest {

public HashtableTest() { }

}

}
Kế tiếp, chúng ta tạo một hàm và đánh dấu với thuộc tính [Test] để NUnit biết đây là hàm kiểm tra. Trong hàm này chúng ta sẽ thiết lập Hashtable và đưa vào 2 giá trị, sau đó dùng hàm Assert.AreEqual để truy xuất 2 giá trị này.

[Test]

public void HashtableAddTest(){

Hashtable ht = new Hashtable();

ht.Add(’Key1′, ‘Value1′);

ht.Add(’Key2′, ‘Value2′);

Assert.AreEqual(’Value1′, ht[’Key1′], ‘Wrong object returned!’);

Assert.AreEqual(’Value2′, ht[’Key2′], ‘Wrong object returned!’);

}

Để chạy thủ tục kiểm tra, bạn cần xây dựng project, mở nó trong NUnit và nhấn nút Run. Bạn cũng có thể tải về NUnit Visual Studio .NET add-in (http://sourceforge.net/project/nunitaddin) để chạy kiểm tra trực tiếp trong Visual Studio.

FXCOP

FxCop (http://www.gotdotnet.com/team/fxcop) là công cụ kiểm tra gói chương trình đảm bảo tính tương thích với những quy tắc của .NET Framework (http://msdn.microsoft.com/library/de...l=/library/en-
us/cpgenref/html/cpconnetframeworkdesignguidelines.asp): Thiết kế thư viện, vấn đề bản địa, quy cách đặt tên, hiệu suất, bảo mật. FxCop do Microsoft phát triển và kèm theo tập các quy tắc do Mircosoft đưa ra, tuy nhiên bạn có thể tạo thêm những quy tắc riêng.

Ví dụ, chúng ta hãy xem FxCop kiểm tra và phát hiện lỗi trong gói NUnitExample ở trên. Trước hết, bạn cần tạo một project FxCop và đưa vào gói mà bạn muốn kiểm tra, sau đó nhấn Analyze và FxCop sẽ kiểm tra và đưa ra thông báo lỗi (Hình 3).

FxCop có thể giúp bạn viết code tốt hơn nhưng nó không thể sửa chữa thiết kế tồi hay lập trình kém. FxCop cũng không thể thay thế việc kiểm tra code nhưng nó cho phép bạn dành nhiều thời gian hơn cho những vấn đề quan trọng hơn là quy ước đặt tên.

.NET REFLECTOR

.NET Reflector (http://aisto.com/roeder/dotnet) là công cụ ‘dịch ngược’ (decompiler) và duyệt danh sách lớp, có thể giúp bạn khám phá tất cả ‘bí mật’ bên trong một gói. .NET Framework đưa ra reflection dùng để xem code .NET bất kỳ, dù là lớp đơn hay toàn bộ gói chương trình (’reflection’ là tính năng cho phép ứng dụng truy vấn siêu dữ liệu của chính nó). Reflection cũng có thể dùng để truy xuất thông tin từ các lớp, hàm và thuộc tính khác nhau trong một gói nào đó. .NET Reflector cho phép bạn duyệt danh sách các lớp và hàm trong một gói, bạn có thể xem xét ngôn ngữ trung gian của Microsoft (MSIL) được sinh ra từ các lớp và hàm này, và có thể dịch ngược các lớp và hàm sang C# hay VB.NET.

Ví dụ, chúng ta dùng .NET Reflector xem xét gói NUnitExample ở trên, hình 4 thể hiện gói này khi được nạp. Để xem MSIL của một hàm, bạn nhấn chọn hàm và chọn menu Disassembler, hay chọn menu Decompiler để xem ở dạng ngôn ngữ C#. Bạn cũng có thể dịch ngược hàm sang VB.NET hay Delphi bằng cách thay đổi tùy chọn trong menu Language.

.NET Reflector đặc biệt có ích để tìm hiểu các hàm và gói trong .NET Framework. Ví dụ, dùng .NET Reflector bạn có thể biết được cách thức mà Microsoft dùng với hàm ReadXml. .NET Reflector cũng rất có ích để tìm hiểu cách thức tạo các đối tượng như HttpHandlers, và qua đó biết được cách thức mà nhóm phát triển của Microsoft đã xây dựng các đối tượng trong Framework.

NDOC

Việc lập tài liệu chương trình luôn là công việc khó gây hứng thú. Ở đây không nói về tài liệu thiết kế mà là tài liệu hàm và thuộc tính của lớp. Công cụ NDoc (http://ndoc.sourceforge.net) sẽ tự động sinh tài liệu cho chương trình của bạn bằng cách dùng reflection để truy vấn thư viện và dùng XML được sinh từ chú thích XML C#. Chú thích XML chỉ có hiệu lực cho C#, tuy nhiên công cụ VB.DOC (http://vb-doc.sourceforge.net) và VBCommenter của VS.NET Power Toy có thể thực hiện tương tự cho VB.NET. Ngoài ra, phiên bản kế tiếp của Visual Studio sẽ hỗ trợ nhiều ngôn ngữ hơn.

Đầu tiên, bạn dùng NDoc để sinh chú thích XML cho gói chương trình. Nhấn phải project và chọn Properties.Configuration Properties.Build, sau đó nhập vào đường dẫn nơi lưu tập tin XML trong tùy chọn XML Documentation File. Dưới đây là tài liệu của hàm trong ví dụ NUnit.

///

/// This test adds a number of values to the Hashtable collection

/// and then retrieves those values and checks if they match.

///


[Test]

public void HashtableAddTest(){

//Method Body Here

}

Tài liệu XML của hàm này sẽ được trích xuất ra và lưu lại trong tập tin XML.



This test adds a number of values to the Hashtable collection
and then retrieves those values and checks if they match.




Sau khi sinh ra tập tin XML, bước kế tiếp nạp gói chương trình và tập tin XML vào NDoc để xử lý. Việc này được thực hiện đơn giản bằng cách mở NDoc và nhấn nút Add. Sau khi khai báo thuộc tính đầu ra, nhấn nút Generate để bắt đầu quá trình sinh tài liệu.

NANT

NAnt (http://nant.sourceforge.net), phiên bản .NET của Ant được hỗ trợ với dự án Jakarta (khá phổ tiếng trong cộng đồng phát triển Java), là công cụ cho phép dễ dàng tạo qui trình build (biên dịch và tích hợp ứng dụng) dựa trên XML. Khi có nhiều nhà phát triển cùng làm việc trên một dự án, bạn không thể phó thác việc build cho từng người, và chắc bạn cũng không muốn thực hiện build thủ công nhiều lần mỗi ngày. NAnt cho phép bạn build tự động toàn bộ ứng dụng, chép các tập tin, chạy các kiểm tra NUnit, gửi email và nhiều chức năng khác. NAnt dùng các tập tin XML để khai báo những tác vụ cần thực hiện trong quá trình build. Lưu ý là MSBuild, thành phần trong phiên bản mới Visual Studio 2005, có tính năng tương tự và có thể thay thế NAnt.

Ví dụ dưới đây là tập tin XML (có phần đuôi là .build) để biên dịch ứng dụng NUnitExample với NAnt.





The NUnit Example Project





debug=’${debug}’>



program files\NUnit

V2.1\bin\NUnit.Framework.dll’ />













Tập tin XML này được lưu ở thư mục gốc của project NUnitExample. Bạn đến thư mục này và chạy nant.exe để biên dịch ứng dụng.

Tuy không dễ dàng như việc nhấn Build trong Visual Studio, nhưng NAnt là công cụ rất mạnh dùng để xây dựng qui trình build chạy tự động theo lịch biểu.

Công cụ chuyển đổi

Cuối cùng là 2 công cụ đơn giản nhưng rất hữu dụng. Đầu tiên là ASP.NET Version Switcher (http://www.denisbauer.com/NETTools/A...Switcher.aspx), công cụ này dùng để chuyển đổi phiên bản (version) ASP.NET của một website đang hoạt động. Công cụ thứ hai là Visual Studio Converter (http://www.codeproject.com/macro/vsconvert.asp) dùng để chuyển đổi tập tin project từ VS.NET 2002 sang VS.NET 2003 hay ngược lại.

IIS sử dụng cơ chế ánh xạ phần mở rộng (extension) để xử lý yêu cầu một website. Khi cài ASP.NET 1.1, cơ chế này được nâng cấp phiên bản mới và gây lỗi khi chạy ứng dụng được xây dựng trên ASP.NET 1.0. Để giải quyết vấn đề này, bạn có thể chuyển tất cả ánh xạ phần mở rộng của website về phiên bản 1.0, tuy nhiên, thực hiện thủ công việc này rất vất vả và đây chính là nơi ‘dụng võ’ của ASP.NET Version Switcher. Tiện ích nhỏ này có thể dùng để chuyển version .NET của bất kỳ ứng dụng ASP.NET nào. Công cụ này càng có ích khi tương lai có thêm các phiên bản mới ASP.NET và .NET Framework.

Visual Studio Converter tương tự như ASP.NET Version Switcher, ngoại trừ việc nó được dùng để chuyển đổi version của tập tin project Visual Studio. Mặc dù chỉ có một ít khác biệt giữa .NET Framework version 1.0 và 1.1, một khi tập tin project được chuyển từ VS.NET 2002 sang VS.NET 2003 thì không thể chuyển ngược lại. Tuy nhiên, đôi khi việc chuyển ngược lại cần thiết. Công cụ Converter này cho phép chuyển bất kỳ tập tin solution hay project từ Visual Studio 7.1 (VS.NET 2003) về Visual Studio 7.0 (VS.NET 2002) và ngược lại.

Kết luận


Vậy là chúng ta đã ‘cưỡi ngựa xem hoa’ một số công cụ miễn phí tuyệt vời hỗ trợ cho việc phát triển trên nền .NET. Hy vọng trong số này có những công cụ đáp ứng nhu cầu của bạn và có thể giúp bạn cải thiện hiệu suất. Hãy trang bị đầy đủ các công cụ cần thiết, đó có thể là máy tính mạnh, Visual Studio phiên bản mới nhất hay tiện ích miễn phí vì chúng sẽ giúp tạo nên sự khác biệt cho bạn.

Source : PCWorld

Thursday, February 23, 2006

love...

Yêu là không biết hối tiếc
Có lỗ tai mà như điếc
Yêu là luôn chịu thiệt
Xài tiền mà không biết tiếc
Yêu là phải biết cương quyết
Nồng nàn và kịch liệt
Yêu cho tới sức tàn lực kiệt
Tới khi tứ chi bại liệt
Yêu vậy mới là yêu thiệt...
Lãng mạn thì bảo...tào lao
Đứng đắn lại bảo...người sao hững hờ
Khù khờ thì bảo...giai tơ
Khôn lanh thì bảo...hái mơ bao lần
Cả đời cứ mãi phân vân
Tơ lòng con gái biết mần sao đây ...???

Tuesday, February 21, 2006

Default ....

Em vội bước ra đi quên Logoff
Chẳng một lời dù chỉ tiếng Standby
Em quên hết kỷ niệm xưa đã Add
Quẳng tình anh vào khoảng trống Recyclebin
Anh vẫn đợi trên nền xanh Desktop
Bóng em vừa Refresh hồn anh
Từng cú Click em đi vào nỗi nhớ
Trong tim anh... Harddisk .. dần đầy
Anh ghét quá, muốn Clean đi tất cả
Nhưng phải làm sao khi .. chẳng biết Username
Hay mình sẽ một lần Full Format ..
Em đã change .. Password cũ còn đâu!
Anh sẽ cố một lần anh sẽ cố
Sẽ Retry cho đến lúc Error
Nhưng em hỡi làm sao anh có thể ..
Khi Soft anh dùng... đã hết Free Trial !
Hình bóng em vẫn mãi Default ....

Sunday, November 13, 2005

sad valentin - 2006

Anh yêu em mà em chẳng Open
Mở cửa trái tim và Save anh vào đó
Cửa nhà em, mẹ đã gài Password
Anh suýt rách quần vì cố vượt FireWall
Nhớ lần đầu khi đưa em về Home
Anh kiss trộm liền xơi ngay một Tab
Anh bàng hoàng quay xe BackSpace
Ngoái nhìn em mà chẳng thể Ctrl
Anh tức giận khi thấy một thằng Alt
Cứ Insert mỗi khi mình nói chuyện
Có nhiều khi muốn thẳng tay Delete
Nhưng vì em, anh nuốt giận Cancel
Anh biết anh chỉ là IT nghèo
Còn hắn có @ và Esc
Em thích hắn làm lòng anh Space
Bước thẫn thờ chìm xuống vực PageDown