Archive from June, 2012
Jun 30, 2012 -

16/2/2009 – 29/6/2012 – Kết thúc một chặng đường

Mới đó mà đã hơn 3 năm. 3 năm làm việc là chính, ăn chơi là chủ yếu, trải qua bao sóng gió thăng trầm của lịch sử, chứng kiến sự ra đi và trở lại của không biết bao nhiêu con người. Và rồi ngày ấy cũng đã đến, ngày mà mình chính thức bị xếp vào hàng ngũ “cựu nhân viên”.

Ấy là vào cuối năm 2008. Lúc đó mình cũng kinh qua một vài công việc part time nhưng không được nhận lương. Ham muốn làm một cái gì đó ra tiền đã lên đến đỉnh điểm. Vì vậy, khi Hưng Bưởng nói Cazoodle đang cần tuyển thêm part time, mình đã không do dự viết CV và nộp luôn. Mức lương hồi đó có thể coi là trong mơ, $250 một tháng, tuần làm việc 20 giờ (còn nhớ lúc đó lương khởi điểm cho full time của Fsoft chỉ có 4 triệu đồng). Sau 2 vòng phỏng vấn, mình nhận được job offer của Kevin và bắt đầu làm việc từ ngày 16/2/2009.

Thú thực là hồi đó lập trình đối với mình còn mơ hồ lắm. Mặc dù các kiến thức về toán rời rạc, cấu trúc dữ liệu và giải thuật, thuật toán đã được thầy Nghĩa nhồi nhét từ những năm đầu đại học, nhưng kinh nghiệm thực tế của mình gần như là con số 0. Năm 2008, mình còn định đi theo hướng mạng, làm CTV, học CCNA và ra trường làm cho Cisco (cũng chỉ bởi vì nghe nói thực tập ở Cisco lương $200/tháng). Anh Lâm chính là người dìu dắt mình những bước đi đầu tiên. Bắt đầu với Landlord Console prototype mà anh Lâm xây dựng trong vòng 2 tuần, dựa trên mootools và Javascript MVC. Từ đó, mình hiểu thế nào là MVC, viết Javascript theo class, lập trình PHP có connect với cơ sở dữ liệu MySQL. Trong vòng gần 4 tháng, Landlord Console đã được phát triển qua nhiều giai đoạn, chức năng ngày càng được hoàn thiện. Landlord Console là tiền thân của Data Console bây giờ. Tiếc là sau đó anh Lâm chuyển sang Shopping Search, Landlord Console được Paul takeover và rồi không còn được tiếp tục thực hiện nữa.

Nghỉ ôn thi gần 1 tháng, mình trở lại với một công việc hoàn toàn mới: Viết Shopping Caddy, một Firefox Addons. Thực ra sau gần 4 tháng làm việc, mình đã quá quen với Javascript, nhưng Firefox Addons lại là một thứ hoàn toàn khác hẳn. Đặc biệt là trong giai đoạn này, mình làm việc trực tiếp với Garima, một bạn người Ấn Độ rất giỏi. Mình bắt đầu làm quen với XUL, XBL, XPCOM và các công nghệ khác của Mozilla. Ban đầu, công việc khá mệt mỏi và vất vả vì không có ai để hỏi. Garima cũng chỉ là người supervise chứ không giúp đỡ được gì nhiều. Đây có thể coi là independent project đầu tiên của mình. Mình làm Shopping Caddy khoảng một năm rưỡi, trải qua vài lần revamping. Javascript chuyển từ plain sang class, XUL chuyển thành XBL, nghiên cứu thêm về JSM và XPCOM C++. Cuối cùng vì data coverage mà dự án bị ngừng hoạt động. Làm việc với Shopping Caddy giúp mình tĩch lũy được khá nhiều thứ như khả năng nghiên cứu và làm việc độc lập, nghe/nói tiếng Anh và khả năng thuyết trình. Gần đây, dự án Shopping Caddy được hoạt động trở lại, hy vọng là sẽ không bị ngừng hoạt động một lần nữa.

Đến đầu năm 2011, mình toàn tâm toàn ý làm việc cho Agent Platform. Agent Platform lúc này đang trong quá trình xây dựng một phiên bản hoàn toàn mới. Mình (và Đạt) được phụ trách phần giao diện người dùng. Tạm gác PHP, MySQL, Python, CSS, XUL, Javascript sang một bên, mình bắt tay vào C# và MSSQL. Gần như là học lại từ đầu mặc dù trước kia mình có từng làm qua một vài chương trình C# nhưng cũng chỉ là học lỏm, sửa code này nọ cho nó chạy theo đúng ý. Còn bây giờ là một project, một hệ thống hoàn toàn mới. Chị Bình là người giúp đỡ mình rất nhiều trong quá trình làm quen với C#. Team mình lúc đó chỉ có 4 người. Anh Quốc lo phần engine chạy agent trên Java. Chị Bình lo phần browser để duyệt và xử lý trang web. Mình và Đạt lo phần constructor cho AB sử dụng. AP team mất đúng 1 năm (kể từ khi bắt đầu viết Specifications) đến lúc đưa vào sử dụng phiên bản mới.

AP version 2 ra mắt cũng là lúc mình tiếp tục nhận một công việc mới: Agent Execution (không hổ danh là AP Innovator). Quay trở lại với PHP, Python, Java, mình như cá gặp nước. Trong gần 9 tháng, AE đã thực sự thay đổi. Từ một chương trình lập lịch và chạy agent nghèo nàn, giao diện thô sơ khó sử dụng đã trở thành một chương trình mạnh mẽ hơn, tự động tối đa công việc lập lịch, cho phép chạy những agent nhiều steps, giao diện bắt mắt, dễ sử dụng và đặc biệt là càng ngày càng ổn định hơn.

Ra đi trong lúc này là một thời điểm thích hợp cho AE (vì task không còn nhiều và độ ổn định đã tăng lên) nhưng lại không phải là thời điểm thích hợp cho AP. Lực lượng hiện tại của AP khá mỏng nhưng phải làm khá nhiều việc, hầu như mỗi người phải take care ít nhất một project. Nhưng mình tin tưởng AP team sẽ vượt qua giai đoạn khó khăn này, các thành viên ngày một cứng cáp hơn và đảm nhiệm được những nhiệm vụ khó khăn hơn.

PS: Bài viết chủ yếu đề cập đến công việc nên có thể sẽ gây thất vọng cho một số bạn. Mình sẽ viết về cái sự ăn chơi của Cazoodle ngay tiếp sau bài này.

Jun 26, 2012 -

Có quá nhiều lựa chọn

Không có lựa chọn nào đã khổ, có quá nhiều lựa chọn đôi khi còn khổ hơn.

Hôm nay nhìn lịch mới biết còn có đúng 53 ngày nữa là mình lên đường sang US. Bao nhiêu kế hoạch, dự định, không biết có thực hiện được hết hay không. Này nhé, ngay trong tuần này có một vụ giải ngân của AP, chia tay công ty, đưa em gái đi xem phim và tụ tập với VEF. Tiếp theo là mấy ngày ở miền trung, 1 tuần ở SG và có thể là 4 tuần ở Úc. Vậy thì lấy đâu ra thời gian dành cho những việc khác.

Giờ chỉ ước 1 tháng có 8 tuần, mỗi tuần có 14 ngày. Càng đến trước lúc đi tại sao lại càng có nhiều cám dỗ như vậy chứ.

Jun 18, 2012 -

Sợ ???!

Đêm qua mình mơ một giấc mơ kỳ lạ. Sang Mỹ, ở Vietnam Town (chứ không phải China Town), nhà ngói lụp xụp, ông chủ nhà còn bảo xây dựng theo đúng phong cách Việt Nam, chúng mày đến là được ở nhà mới. Đạp xe đi học, học về ra chợ mua đồ về nấu cơm, tối còn bị mất điện. Cuộc sống nói chung là bí bức cực khổ lắm. Tỉnh dậy mà toát hết mồ hôi hột.

Gần đây mình luôn có những suy nghĩ miên man. Cuộc sống hiện tại đang tốt đẹp là thế, không hiểu tháng 8 này sang bên ấy sẽ thế nào. Cũng không giống như hồi năm lớp 6 đi học xa, có chuyện gì chỉ gần gọi điện về là bố mẹ sẽ lên, muốn về cũng không khó khăn gì. Sang Mỹ có nghĩa là dù muốn hay không cũng phải ít nhất 1 năm sau mới được về nhà. Cuộc sống dù có vất vả khó khăn đến đâu, học hành dù có mệt mỏi stress đến đâu cũng phải cố gắng vượt qua, không được phép dừng lại. Dừng lại tức là bao cố gắng bấy lâu nay sẽ đổ xuống sông xuống biển hết.

Kỳ lạ, trong khi các bạn khác đang rất háo hức về bước ngoặt sắp tới, đặt vé máy bay rõ sớm (ngay trong tháng 7) thì tự dưng mình lại có những suy nghĩ trái chiều. Bao nhiêu năm cố gắng, cuối cùng sắp đến ngày đi tự dưng lại thấy chùn bước. Mình có lẽ sẽ là người xuất phát muộn nhất trong nhóm. Đi rồi, biết bao giờ mới được trở lại đây?

Jun 14, 2012 -

Thử một bài viết có rất nhiều tiếng Việt

Bài viết này lẽ ra đã không được publish. Mục đích của mình chỉ là kiểm tra xem WordPress 3.4 xử lý tiếng Việt trong Permalink như thế nào. Trước 3.4, WordPress xử lý việc này không tốt, cụ thể là với tiêu đề như trên, WordPress sẽ xử lý thành “thử-một-bai-viết-co-rất-nhiều-tiếng-việt”. WordPress 3.4 đã xử lý việc này rất tốt, URL trở thành “thu-mot-bai-viet-co-rat-nhieu-tieng-viet”.

Dưới đây là đoạn code được mình viết và đặt trong file wp-includes/formatting.php để xử lý tiếng Việt trong Permalink. WordPress 3.4 cũng có một đoạn xử lý tương tự nhưng đã tối ưu và loại bỏ các ký tự trùng với các phần sẵn có trong WordPress.

// Decompositions for Vietnamese
chr(65) => 'A',chr(97) => 'a',
chr(196).chr(130) => 'A',chr(196).chr(131) => 'a',
chr(195).chr(130) => 'A',chr(195).chr(162) => 'a',
chr(195).chr(128) => 'A',chr(195).chr(160) => 'a',
chr(225).chr(186).chr(176) => 'A',chr(225).chr(186).chr(177) => 'a',
chr(225).chr(186).chr(166) => 'A',chr(225).chr(186).chr(167) => 'a',
chr(195).chr(129) => 'A',chr(195).chr(161) => 'a',
chr(225).chr(186).chr(174) => 'A',chr(225).chr(186).chr(175) => 'a',
chr(225).chr(186).chr(164) => 'A',chr(225).chr(186).chr(165) => 'a',
chr(225).chr(186).chr(162) => 'A',chr(225).chr(186).chr(163) => 'a',
chr(225).chr(186).chr(178) => 'A',chr(225).chr(186).chr(179) => 'a',
chr(225).chr(186).chr(168) => 'A',chr(225).chr(186).chr(169) => 'a',
chr(195).chr(131) => 'A',chr(195).chr(163) => 'a',
chr(225).chr(186).chr(180) => 'A',chr(225).chr(186).chr(181) => 'a',
chr(225).chr(186).chr(170) => 'A',chr(225).chr(186).chr(171) => 'a',
chr(225).chr(186).chr(160) => 'A',chr(225).chr(186).chr(161) => 'a',
chr(225).chr(186).chr(182) => 'A',chr(225).chr(186).chr(183) => 'a',
chr(225).chr(186).chr(172) => 'A',chr(225).chr(186).chr(173) => 'a',
chr(69) => 'E',chr(101) => 'e',
chr(195).chr(138) => 'E',chr(195).chr(170) => 'e',
chr(195).chr(136) => 'E',chr(195).chr(168) => 'e',
chr(225).chr(187).chr(128) => 'E',chr(225).chr(187).chr(129) => 'e',
chr(195).chr(137) => 'E',chr(195).chr(169) => 'e',
chr(225).chr(186).chr(190) => 'E',chr(225).chr(186).chr(191) => 'e',
chr(225).chr(186).chr(186) => 'E',chr(225).chr(186).chr(187) => 'e',
chr(225).chr(187).chr(130) => 'E',chr(225).chr(187).chr(131) => 'e',
chr(225).chr(186).chr(188) => 'E',chr(225).chr(186).chr(189) => 'e',
chr(225).chr(187).chr(132) => 'E',chr(225).chr(187).chr(133) => 'e',
chr(225).chr(186).chr(184) => 'E',chr(225).chr(186).chr(185) => 'e',
chr(225).chr(187).chr(134) => 'E',chr(225).chr(187).chr(135) => 'e',
chr(73) => 'I',chr(105) => 'i',
chr(195).chr(140) => 'I',chr(195).chr(172) => 'i',
chr(195).chr(141) => 'I',chr(195).chr(173) => 'i',
chr(225).chr(187).chr(136) => 'I',chr(225).chr(187).chr(137) => 'i',
chr(225).chr(187).chr(138) => 'I',chr(225).chr(187).chr(139) => 'i',
chr(79) => 'O',chr(111) => 'o',
chr(195).chr(148) => 'O',chr(195).chr(180) => 'o',
chr(198).chr(160) => 'O',chr(198).chr(161) => 'o',
chr(195).chr(146) => 'O',chr(195).chr(178) => 'o',
chr(225).chr(187).chr(146) => 'O',chr(225).chr(187).chr(147) => 'o',
chr(225).chr(187).chr(156) => 'O',chr(225).chr(187).chr(157) => 'o',
chr(195).chr(147) => 'O',chr(195).chr(179) => 'o',
chr(225).chr(187).chr(144) => 'O',chr(225).chr(187).chr(145) => 'o',
chr(225).chr(187).chr(154) => 'O',chr(225).chr(187).chr(155) => 'o',
chr(225).chr(187).chr(142) => 'O',chr(225).chr(187).chr(143) => 'o',
chr(225).chr(187).chr(148) => 'O',chr(225).chr(187).chr(149) => 'o',
chr(225).chr(187).chr(158) => 'O',chr(225).chr(187).chr(159) => 'o',
chr(195).chr(149) => 'O',chr(195).chr(181) => 'o',
chr(225).chr(187).chr(150) => 'O',chr(225).chr(187).chr(151) => 'o',
chr(225).chr(187).chr(160) => 'O',chr(225).chr(187).chr(161) => 'o',
chr(225).chr(187).chr(140) => 'O',chr(225).chr(187).chr(141) => 'o',
chr(225).chr(187).chr(152) => 'O',chr(225).chr(187).chr(153) => 'o',
chr(225).chr(187).chr(162) => 'O',chr(225).chr(187).chr(163) => 'o',
chr(85) => 'U',chr(117) => 'u',
chr(198).chr(175) => 'U',chr(198).chr(176) => 'u',
chr(195).chr(153) => 'U',chr(195).chr(185) => 'u',
chr(225).chr(187).chr(170) => 'U',chr(225).chr(187).chr(171) => 'u',
chr(195).chr(154) => 'U',chr(195).chr(186) => 'u',
chr(225).chr(187).chr(168) => 'U',chr(225).chr(187).chr(169) => 'u',
chr(225).chr(187).chr(166) => 'U',chr(225).chr(187).chr(167) => 'u',
chr(225).chr(187).chr(172) => 'U',chr(225).chr(187).chr(173) => 'u',
chr(196).chr(168) => 'U',chr(196).chr(169) => 'u',
chr(197).chr(168) => 'U',chr(197).chr(169) => 'u',
chr(225).chr(187).chr(174) => 'U',chr(225).chr(187).chr(175) => 'u',
chr(225).chr(187).chr(164) => 'U',chr(225).chr(187).chr(165) => 'u',
chr(225).chr(187).chr(176) => 'U',chr(225).chr(187).chr(177) => 'u',
chr(89) => 'Y',chr(121) => 'y',
chr(225).chr(187).chr(178) => 'Y',chr(225).chr(187).chr(179) => 'y',
chr(195).chr(157) => 'Y',chr(195).chr(189) => 'y',
chr(225).chr(187).chr(182) => 'Y',chr(225).chr(187).chr(183) => 'y',
chr(225).chr(187).chr(184) => 'Y',chr(225).chr(187).chr(185) => 'y',
chr(225).chr(187).chr(180) => 'Y',chr(225).chr(187).chr(181) => 'y',
chr(68) => 'D',chr(100) => 'd',
chr(196).chr(144) => 'D',chr(196).chr(145) => 'd',

Đây là đoạn code của WordPress

// Vowels with diacritic (Vietnamese)
// unmarked
chr(198).chr(160) => 'O', chr(198).chr(161) => 'o',
chr(198).chr(175) => 'U', chr(198).chr(176) => 'u',
// grave accent
chr(225).chr(186).chr(166) => 'A', chr(225).chr(186).chr(167) => 'a',
chr(225).chr(186).chr(176) => 'A', chr(225).chr(186).chr(177) => 'a',
chr(225).chr(187).chr(128) => 'E', chr(225).chr(187).chr(129) => 'e',
chr(225).chr(187).chr(146) => 'O', chr(225).chr(187).chr(147) => 'o',
chr(225).chr(187).chr(156) => 'O', chr(225).chr(187).chr(157) => 'o',
chr(225).chr(187).chr(170) => 'U', chr(225).chr(187).chr(171) => 'u',
chr(225).chr(187).chr(178) => 'Y', chr(225).chr(187).chr(179) => 'y',
// hook
chr(225).chr(186).chr(162) => 'A', chr(225).chr(186).chr(163) => 'a',
chr(225).chr(186).chr(168) => 'A', chr(225).chr(186).chr(169) => 'a',
chr(225).chr(186).chr(178) => 'A', chr(225).chr(186).chr(179) => 'a',
chr(225).chr(186).chr(186) => 'E', chr(225).chr(186).chr(187) => 'e',
chr(225).chr(187).chr(130) => 'E', chr(225).chr(187).chr(131) => 'e',
chr(225).chr(187).chr(136) => 'I', chr(225).chr(187).chr(137) => 'i',
chr(225).chr(187).chr(142) => 'O', chr(225).chr(187).chr(143) => 'o',
chr(225).chr(187).chr(148) => 'O', chr(225).chr(187).chr(149) => 'o',
chr(225).chr(187).chr(158) => 'O', chr(225).chr(187).chr(159) => 'o',
chr(225).chr(187).chr(166) => 'U', chr(225).chr(187).chr(167) => 'u',
chr(225).chr(187).chr(172) => 'U', chr(225).chr(187).chr(173) => 'u',
chr(225).chr(187).chr(182) => 'Y', chr(225).chr(187).chr(183) => 'y',
// tilde
chr(225).chr(186).chr(170) => 'A', chr(225).chr(186).chr(171) => 'a',
chr(225).chr(186).chr(180) => 'A', chr(225).chr(186).chr(181) => 'a',
chr(225).chr(186).chr(188) => 'E', chr(225).chr(186).chr(189) => 'e',
chr(225).chr(187).chr(132) => 'E', chr(225).chr(187).chr(133) => 'e',
chr(225).chr(187).chr(150) => 'O', chr(225).chr(187).chr(151) => 'o',
chr(225).chr(187).chr(160) => 'O', chr(225).chr(187).chr(161) => 'o',
chr(225).chr(187).chr(174) => 'U', chr(225).chr(187).chr(175) => 'u',
chr(225).chr(187).chr(184) => 'Y', chr(225).chr(187).chr(185) => 'y',
// acute accent
chr(225).chr(186).chr(164) => 'A', chr(225).chr(186).chr(165) => 'a',
chr(225).chr(186).chr(174) => 'A', chr(225).chr(186).chr(175) => 'a',
chr(225).chr(186).chr(190) => 'E', chr(225).chr(186).chr(191) => 'e',
chr(225).chr(187).chr(144) => 'O', chr(225).chr(187).chr(145) => 'o',
chr(225).chr(187).chr(154) => 'O', chr(225).chr(187).chr(155) => 'o',
chr(225).chr(187).chr(168) => 'U', chr(225).chr(187).chr(169) => 'u',
// dot below
chr(225).chr(186).chr(160) => 'A', chr(225).chr(186).chr(161) => 'a',
chr(225).chr(186).chr(172) => 'A', chr(225).chr(186).chr(173) => 'a',
chr(225).chr(186).chr(182) => 'A', chr(225).chr(186).chr(183) => 'a',
chr(225).chr(186).chr(184) => 'E', chr(225).chr(186).chr(185) => 'e',
chr(225).chr(187).chr(134) => 'E', chr(225).chr(187).chr(135) => 'e',
chr(225).chr(187).chr(138) => 'I', chr(225).chr(187).chr(139) => 'i',
chr(225).chr(187).chr(140) => 'O', chr(225).chr(187).chr(141) => 'o',
chr(225).chr(187).chr(152) => 'O', chr(225).chr(187).chr(153) => 'o',
chr(225).chr(187).chr(162) => 'O', chr(225).chr(187).chr(163) => 'o',
chr(225).chr(187).chr(164) => 'U', chr(225).chr(187).chr(165) => 'u',
chr(225).chr(187).chr(176) => 'U', chr(225).chr(187).chr(177) => 'u',
chr(225).chr(187).chr(180) => 'Y', chr(225).chr(187).chr(181) => 'y',

Nhìn lại thì xem ra cũng không tối ưu được nhiều lắm, chỉ là tổ chức tốt hơn, chia thành nhiều nhóm nhỏ.

Pages:123»