16 thg 8, 2016

12 công cụ marketing miễn phí mọi startup nên biết

Nếu bạn đang phân vân giữa hàng trăm công cụ marketing trên thị trường hiện nay thì hãy tham khảo danh sách các sản phẩm tốt nhất dưới đây.


Nếu đang khởi nghiệp kinh doanh riêng bằng đồng vốn cá nhân, chắc chắn bạn sẽ hiểu được giá trị của từng đồng tiền tiết kiệm được.
Ai cũng hiểu tầm quan trọng của các hoạt động marketing đối với mỗi công ty. Nếu bạn đang phân vân giữa hàng trăm công cụ marketing trên thị trường hiện nay thì hãy tham khảo danh sách các sản phẩm tốt nhất dưới đây.
1. Quản lý các kênh truyền thông xã hội bằng Buffer hoặc Hootsuite
Buffer là công cụ quản lý đắc lực cho các kênh truyền thông xã hội như Facebook, Twitter, Instagram,… Buffer có khả năng kết nối nhiều tài khoản mạng xã hội vào một bảng điều khiển duy nhất, giúp bạn không phải lăn lộn đăng bài khắp nơi nữa. Một số tính năng thú vị khác bao gồm schedule (lên lịch trước) bài đăng, tạo các chiến dịch cũng như phân tích độ hiệu quả các post của bạn. Gói miễn phí của Buffer đã là khá đủ cho các startup.
 
Bảng điều khiển của Buffer
Tương tự như vậy, Hootsuite cũng là một công cụ tuyệt vời giúp bạn quản lý các tài khoản mạng xã hội. Điểm mạnh của Hootsuite là cho phép bạn nhanh chóng đăng tải các bài viết cũng như phản hồi trên các tài khoản mạng xã hội khác nhau ngay trên một bảng điều khiển duy nhất.
2. Thiết kế logo với “chợ” logo miễn phí của Spaces
 
Branding là một trong những bước bắt buộc trong các hoạt động marketing của doanh nghiệp, và logo là phần quan trọng hàng đầu trong bước này.
Với Spaces , bạn có thể dễ dàng lựa chọn hình dáng và các icon xuất hiện trong logo trong kho hình miễn phí sẵn có mà không cần phải quá nhiều tiền vào thuê một designer chuyển thể các ý tưởng của bạn thành hình vẽ nữa.
3. Thiết kế ấn phẩm truyền thông dễ dàng với Canva
 
Ấn phẩm truyền thông đẹp mắt đang ngày càng trở nên quan trọng hơn trong marketing. Từ những hình ảnh minh họa bài viết cho đến những infographic nâng cao ý thức người dùng, những catalogue sản phẩm cho đến poster quảng bá đều cần tới bàn tay của những người biết thiết kế. Thế nhưng nếu bạn chưa có đủ vốn hay khả năng thuê được một designer riêng thì sao? Hiện nay có rất nhiều công cụ design miễn phí trên thị trường, thế nhưng tốt và dễ sử dụng hàng đầu phải kể đến Canva . Với kho hình ảnh mẫu phong phú cực nhiều poster, banner Facebook hay brochure, ảnh minh họa và cho phép người dùng sử dụng kiểu kéo thả chữ vào, Canva xứng đáng là người bạn thân của tất cả các marketer.
4. Sử dụng Piktochart để tạo infographic nhanh chóng
 
Infographic cũng là một phương pháp tuyệt vời trong content marketing, và điều cản trở các marketer nhiều nhất từ trước đến nay chính là thiếu người có khả năng thiết kế. Vấn đề đó nay không còn nữa với Piktochart . Kho infographic mẫu của Piktochart có rất nhiều infographic các loại cho bạn lựa chọn, từ loại về tiểu sử cuộc đời cho đến loại về hướng dẫn hay nêu thống kê cho người xem được trình bày một cách hết sức sáng tạo. Bạn chỉ cần kéo thả thêm các yếu tố mình cần rồi save ảnh về máy là xong.
5. Tổ chức thông tin bằng Evernote và Mindmeister
Việc tổ chức, sắp xếp thông tin cho các chiến dịch marketing là hết sức quan trọng. Bạn có thể nảy ra ý tưởng vào bất cứ lúc nào trong ngày và chắc chắn cần một nơi hệ thống lại tất cả. Evernote là công cụ ghi chú đã quá phổ biến, cho phép bạn không chỉ ghi chép, scan từ notebook mà còn cho save cả những bài báo, thư mục quan tâm về đọc offline.
 
Trong khi đó, Mindmeister là công cụ vẽ bản đồ tư duy đắc lực cho phép bạn chia sẻ cả với các cộng sự nữa. Việc cùng nhau brainstorm ý tưởng cho các chiến dịch marketing sẽ trở nên đơn giản hơn rất nhiều.
6. Lấy phản hồi khách hàng bằng SurveyMonkey
 
SurveyMonkey là một trong số các công cụ khảo sát online miễn phí tốt nhất. Khảo sát khách hàng là hoạt động hữu ích giúp các marketer lấy insight, cảm nhạn của người dùng và khám phá các xu hướng sử dụng đương thời. Chỉ mất vài phút bạn đã có thể thiết kế các nên một mẫu khảo sát chuyên nghiệp. SurveyMonkey cũng cho phép bạn phân tích kết quả một cách chi tiết.
7. Email marketing qua Mailchimp
 
Theo dõi hiệu quả các chiến dịch qua MailChimp
Email marketing nay đã trở thành một kênh không thể thiếu với các doanh nghiệp. Xây dựng hình ảnh trên các mạng xã hội như Facebook, Youtube, Instagram,… là quan trọng nhưng cũng đi kèm với những hạn chế của các nền tảng này là khó đưa khách hàng vào “sales funnel” và theo dõi quá trình mua sắm của họ.
Trái lại, email lại cho phép bạn kiểm soát chặt chẽ hơn sự tương tác giữa thương hiệu và khách hàng cũng như “nuôi” khách hàng từ giai đoạn bắt đầu tiếp cận thương hiệu cho đến khi quyết định mua sản phẩm. Mailchimp là công cụ email marketing miễn phí cho phép bạn dễ dàng đo lường các chiến dịch truyền thông qua mail.
8. Growth hacking bằng Sniply
Là một marketer có lẽ bạn không còn quá xa lạ với thuật ngữ “growth hacking” – các chiến lược tăng lượng người dùng tức thì một cách sáng tạo và ít tốn kém.
Một trong những thủ thuật growth hacking hiệu quả là share lại các post từ những chuyên gia nổi tiếng trong ngành để xây dựng sự tin tưởng cho người dùng, Thế nhưng những nội dung bạn share lại thường nằm ở các website khác mà bạn không có quyền kiểm soát nên thường người đọc sẽ “ngó lơ” luôn website/page của bạn khi được dẫn sang nguồn khác. Hiểu điều này, Sniply cho phép bạn gắn nút kêu gọi hành động (Call to action) vào bất cứ nội dung gì bạn chia sẻ. Nó giúp bạn gắn một nút quay lại/kêu gọi hành động vào một hộp thoại bên góc trái màn hình để người đọc có thể quay trở lại website của bạn.
 
Ví dụ về sử dụng Sniply để kêu gọi khách hàng quay lại trang
9. Lấy nội dung từ các website bằng Scraper
 

Scraper (Data Miner) là một tiện ích Chrome cho phép lấy hết dữ liệu trên một website nào đó rồi xuất nó ra file Excel để tiện theo dõi. Đây là một cách tuyệt vời để lấy thông tin khách hàng từ các đối thủ. Một khi đã có được những danh sách khách hàng đáng giá này, bạn có thể sử dụng cold email hay cold call để thu phục họ.
10. Tìm kiếm thông tin chính xác bằng Rapportive
 

Sẽ thế nào nếu bạn nhận được email từ một khách hàng tiềm năng và muốn biết thêm thông tin chi tiết của họ? Rapportive sẽ giúp bạn dựa vào email để tra ra ngay ảnh chân dung, nơi sống, nghề nghiệp, công ty, hồ sơ cá nhân trên LinkedIn,…và hiển thị tất cả ngay trên giao diện Gmail, rất tuyệt phải không?
Nguồn: ictnews.vn

30 thg 1, 2015

Học, học nữa, học mãi

25 thg 12, 2012

Khái niệm Thread trong Java

Có một định nghĩa về Thread như sau : Thread là một dòng các điều khiển trong một process hay một ứng dụng. Nguyên văn là : Threads are multiple flows of control within a single program or process. Với cơ chế Multithreading ứng dụng của bạn có thể thực thi đồng thời nhiều dòng lệnh cùng lúc. Có nghĩa là bạn có thể làm nhiều công việc đồng thời trong cùng một ứng dụng của bạn. Có thể hiểu một cách hết sức đơn giản : hệ điều hành với cơ chế đa nhiệm cho phép nhiều ứng dụng chạy cùng lúc. Thì với cơ chế đa luồng, mỗi ứng dụng của bạn có thể thực hiện được nhiều công việc đồng thời. Bạn sẽ hỏi tại sao không dùng nhiều processes , sao không là Multiprocessing mà lại cần đến Multithreading ? Câu trả lời đơn giản nhất là : Việc tạo ra và quản lý các process đòi hỏi nhiều tài nguyên của hệ thống (cả RAM và CPU) nhiều hơn rất nhiều so với việc tạo ra một Thread. Trong khi đó bạn có thể chỉ cần tạo ra một thread để thực hiện song song một công việc hết sức đơn giản cùng với một công việc chính. Bạn viết một ứng dụng Java trên bất kỳ nền tảng nào. Khi ứng dụng bạn chạy thì thực sự đã có một bản sao của JVM khởi động và ứng dụng của bạn là một Thread nếu bạn không dùng Multithreading hoặc là nhiều Threads nếu bạn dùng Multithreading. Tạo một Thread Như đã nói, mỗi khi chạy một ứng dụng trong Java thì bạn đã có một Thread. Đây là Thread chính, nó thực thi các dòng lệnh trong phương thức: public static void main . Đây là một điểm nhập bắt buộc cho mọi ứng dụng độc lập. Để tạo ra một Thread khác ngoài Thread chính trên, Java cung cấp cho chúng ta hai cách : - Tạo ra một lớp con của lớp Thread (java.lang.Thread) - Tạo ra một lớp hiện thực interface Runnable Chúng ta sẽ tìm hiểu lần lược hai cách trên. Tạo một lớp con của lớp java.lang.Thread Bạn khai báo như sau : class A extends Thread { public void run() { ... // code for the new thread to execute } } ... A a = new A(); // create the thread object a.start(); // start the new thread executing ... Với cách này các dòng lệnh của bạn sẽ được đặt trong method run(). Method này được override method nguyên thuỷ của lớp Thread. Sau đó bạn sẽ tạo ra một đối tượng từ lớp của bạn. Bạn gọi phương thức start() từ đối tượng đó. Lúc này Thread của bạn chính thức được tạo ra và phương thức start sẽ tự gọi method run của bạn và thực thi các dòng lệnh mà bạn đã đặc tả. Chú ý rằng : method start() là method của hệ thống, nó có nhiệu vụ cấp phát bộ nhớ, tạo ra một Thread và gọi hàm run() của bạn. Vì thế bạn không nên override phương thức này. Điều này có thể dẫn đến không tạo được Thread. Hiện thực interface Runnable Bạn khai báo như sau : class B extends … implements Runnable { public void run() { ... // code for the new thread to execute } } ... B b = new B(); // create the Runnable object Thread t = new Thread(b); // create a thread object t.start(); // start the new thread ... Cũng giống như cách trên, dòng lệnh của bạn đặt trong method run() (có thể gọi đến các phương thức khác, nhưng phải bắt đầu trong phương thức này) Sau đó bạn tạo một đối tượng B từ lớp đã hiện thực interface Runnable, tạo thêm một đối tượng t của lớp Thread với thông số cho constructor là đối tượng B. Sau đó khi bạn gọi phương thức t.start() thì chính thức Thread được tạo ra và phương thức run() của bạn sẽ được triệu gọi một cách tự động. Bạn sẽ hỏi tại cách thứ hai vẫn phải tạo ra một đối tượng Thread. Vậy tại sao lại đưa ra hai cách hiện thực làm gì ? Câu trả lời là : - Bản thân ngôn ngữ Java không hỗ trợ đa thừa kế . Bạn chỉ có thể extends từ một lớp duy nhất. Nhưng bạn lại có thể implements cùng lúc nhiều interface. Khi mà lớp của bạn đã [extends] một lớp nào đó rồi (vd : Applet), thì bạn chỉ có thể implements Runnable để tạo ra Thread. - Việc extends lớp Thread có thể dẫn đến rủi ro là bạn override các method start(), stop(), ... thì có thể làm cho việc tạo Thread là không thể. Một lời khuyên là nên tạo ra một lớp hiện thực interface Runnable (cách thứ hai) khi muốn tạo ra một Thread. Chương trình của bạn sẽ trong sáng và dễ tìm lỗi hơn. Các constructor cho lớp Thread public Thread() - Tạo ra một đối tượng lớp Thread. - Constructor này có tác dụng giống như Thread(null, null, gname) với gname là một tên được phát sinh tự động bởi JVM (máy ảo java) ở dạng Thread-n , với n là một số nguyên. public Thread(Runnable target) - Tạo ra một đối tượng lớp Thread. - Constructor này có tác dụng giống như Thread(null, target, gname) với gname là tên được phát sinh tự động bởi JVM (máy ảo java) ở dạng Thread-n , với n là một số nguyên. public Thread(ThreadGroup group, Runnable target) - Tạo ra một đối tượng lớp Thread. - Constructor này có tác dụng giống như Thread(group, target, gname) với gname là tên được phát sinh tự động bởi JVM (máy ảo java) ở dạng Thread-n , với n là một số nguyên. - Constructor này có thể phát sinh một ngoại lệ SecurityException nếu như Thread hiện tại không có quyền tạo một Thread mới trong nhóm group. public Thread(String name) - Tạo ra một đối tượng lớp Thread. - Constructor này có tác dụng giống như Thread(null, null, name). public Thread(ThreadGroup group, String name) - Tạo ra một đối tượng lớp Thread. - Constructor này có tác dụng giống như Thread(group, null, name). - Constructor này có thể phát sinh một ngoại lệ SecurityException nếu như Thread hiện tại không có quyền tạo một Thread mới trong nhóm group. public Thread(Runnable target, String name) - Tạo ra một đối tượng lớp Thread. - Constructor này có tác dụng giống như Thread(null, target, name). public Thread(ThreadGroup group, Runnable target, String name) - Tạo ra một đối tượng lớp Thread. - group là nhóm các Thread mà Thread được tạo mới này sẽ được thêm vào. - target là đối tượng cần chạy. Tức là trong đối tượng này có method run, chứa các dòng lệnh cần thực thi của chúng ta. - name là tên của thread. - Nếu group là null và có một bộ quản lý bảo mật security manager (ta thiết lập cho JVM, mặc định thì không có) thì gruop được xác định bởi method getThreadGroup của security manager. Nếu group null và không có security manager hay phương thức getThreadGroup trả về null thì group là nhóm mà Thread đang hoạt động thuộc về. - Nếu target là null thì sau khi được khởi hoạt, method run của lớp Thread sẽ được gọi. Nếu target không null thì sau khi được khởi hoạt thì method run của target sẽ được gọi. - Độ ưu tiên (priority) của Thread mới sẽ được thiết lập bằng với độ ưu tiên của Thread tạo ra nó. - Constructor này có thể phát sinh một ngoại lệ SecurityException nếu như Thread hiện tại không có quyền tạo một Thread mới trong nhóm group. Một số phương thức chính của lớp Thread public static Thread currentThread() - Phương thức này là một phương thức tĩnh. Có nghĩa là bạn có thể gọi nó ở bất đâu mà không cần phải tạo một đối tượng của lớp Thread. - Cú pháp để gọi phương thức này là : Thread.currentThread() - Phương thức này trả về một đối tượng của lớp Thread. Đối tượng này thể hiện cho Thread mà đang thực thi dòng lệnh này. public long getId() - Phương thức này trả về một số nguyên là định danh của Thread. - Con số này là do máy ảo Java (JVM) tạo ra. public final String getName() - Phương thức này trả về tên của Thread. public final void setName(String name) - Thay đổi tên của thread bằng tên name. public Thread.State getState() - Trả về trạng thái hiện tại của thread. - Là một hằng của lớp Thread. - Các giá trị có thể là : + NEW : thread chưa được khởi hoạt. + RUNNABLE : thread đang hoạt động trong JVM. + BLOCKED : thread chờ một monitor để unlock một đối tượng mà nó cần. + WAITING : thread chờ không giới hạn cho đến khi một thread khác đánh thức nó. + TIMED_WAITING : thread chờ trong một thời gian nhất định, hoặc là có một thread khác đánh thức nó. + TERMINATED : thread đã kết thúc công việc của nó. public static void yield() - Đây là một phương thức tĩnh. - Phương thức này sẽ làm cho Thread hiện thời tạm ngưng hoạt động để nhường cho một Thread khác hoạt động. public static void sleep(long millis) throws InterruptedException public static void sleep(long millis, int nanos) throws InterruptedException - Đây là một phương thức tĩnh. - Phương thức này làm cho Thread hiện tại ngừng hoạt động trong một thời gian millis milliseconds. - Phương thức này có thể phát sinh một ngoại lệ InterruptedException nếu có một Thread nào đó làm ngưng hoạt động Thread này. (Nhưng không hợp lệ, tức là không dùng các phương thức được cho phép). public void start() - Phương thức này chính thức tạo ra một đối tượng Thread. Và JVM sẽ tự động gọi phương thức run của đối tượng này nếu nhưng target là null. Hoặc sẽ gọi phương thức run của target nếu như target khác null. - Tuyến được bắt đầu hoạt động sau khi phương thức này được gọi thành công. - Phương thức này có thể phát sinh một ngoại lệ IllegalThreadStateException nếu Thread này đã được khởi hoạt. public final boolean isAlive() - Phương thức này kiểm tra xem Thread có còn hiệu lực hay không (còn sống). - Một Thread còn sống khi mà nó đã From: http://sinhvienit.net/@tut/lap-trinh-phan-mem/java/152-khai-niem-thread-trong-java-!.html

4 thg 5, 2011

Kinh doanh với SIM FLAME

SIM đa năng Flame bắn tiền 7 mạng,nạp phí 4 game:
* Thao tác đơn giản, không cú pháp nhắn tin.
* Bắn tiền trực tiếp cho 7 mạng điện thoại: Viettel, Vinaphone, MobiFone (cả trả trước và trả sau), Sfone, Vietnamobile, EVN.
* Nạp phí 4 game: Vinagame (zing xu), VTV Online (.....), FPT Online (Bac) và Oncash đa năng (Oncash, Silk).

- HÌNH THỨC KINH DOANH:
Khi gia nhập bạn sẽ mua 1 SIM 550.000 VNĐ trong đó có:
- Phí gia nhập 220.000 VNĐ.
- Tài khoản nghe gọi 130.000 VNĐ, SIM đầu số 0120, gói cước 365, bạn có 365 ngày nghe, gọi miễn phí cước thuê bao.
- Tài khoản kinh doanh: Có sẵn 200.000 VNĐ trong tài khoản bán hàng:

Từ 1 SIM Flame bạn mua, bạn sẽ phát triển những người bạn quen cửa hàng bán tạp hóa,… sẽ có cơ hội phát triển thành điểm kinh doanh của bạn.
* Hoa hồng hấp dẫn từ việc phát triển sim: 
Khi bạn giới thiệu trực tiếp 1 SIM bạn sẽ được thưởng 50.000 VNĐ ngay lập tức cộng vào tài khoản kinh doanh của bạn, gián tiếp (tức tầng 2 của bạn) bạn sẽ được thưởng 25.000 VNĐ, tầng 3 thưởng 15.000 VNĐ, tầng 4 thưởng 10.000 VNĐ, tầng 5 thưởng 5.000 VNĐ.
* Chiết khấu bán hàng hưởng từ 5.6 - 9.5% tùy theo mạng điện thoại bạn bắn tiền.
VD: Bạn bán mệnh giá 100.000 VNĐ cho mạng MobiFone bạn sẽ thu của khách hàng 100.000 VNĐ nhưng trong tài khoản kinh doanh của bạn bị trừ đi 93,800 VNĐ tức là bạn đã được 6,2% hưởng ngay lập tức. (Thuê bao nhận tiền vẫn được hưởng các khuyến mại của nhà mạng như khi nạp tiền bằng thẻ cứng).
* Thưởng phát triển hệ thống: 
Khi hệ thống của bạn phát triển đc 100 sim thưởng 3 triệu đồng (Lĩnh 1 lần vào ngaỳ 05 của tháng tiếp theo) và hưởng 0.5% doanh số bán hàng của SIM có giao dịch với điều kiện hệ thống của bạn phải có > hoặc= 100 SIM có giao dịch.
Trong hệ thống của bạn có nhóm nào đạt 100 sim tách ra thì bạn sẽ được thưởng 2 triệu đồng và hưởng 0.1% doanh số bán hàng của nhóm đó và nhóm đó sẽ được hưởng quyền lợi giống như trên.
Và bạn sẽ được hưởng doanh số bán hàng hết tầng 3.
Mức thưởng hệ thống khi không có nhóm tách:
+ 100 SIM thưởng 3 triệu đồng.
+ 300 SIM thưởng 5 triệu đồng.
+ 500 SIM thưởng 10 triệu đồng.
+ 1000 SIM thưởng 20 triệu đồng.

Liên hệ: Y!M: handsomeboyltv
SDT: 01207 4004 66
Chúc các bạn thành công!

12 thg 5, 2010

Mô hình MVP

Trong Quá trình xử lí quá trình tách biệt các thành phần xử lí khỏi hệ thống UI là rất cần thiết, tạo ra khả năng xử lí độc lập cho UI.

Việc tách rời dữ liệu khỏi UI sẻ tạo ra được nhiều UI khác nhau cho các cách thể hiện khác nhau.

Code xử lý đặt trong UI gây khó khăn cho việc kiểm tra và gây phức tạp và trùng lập code. Việc kiểm tra các UI thường hoặc phải chạy ứng dụng thủ công hoặc sử dụng kịch bản (script) để thực hiện việc tương tác tự động lên các UI, do đó sẽ tốn nhiều chi phí và thời gian hơn để kiểm tra các xử lý bên trong thành phần này.

Việc tách các xử lý này ra ngoài ra còn tăng tính tái sử dụng code và dễ bảo trì hơn.

Phương pháp để giải quyết là dùng kiến trúc MVC (Model-View-Controller) và một mẫu kiến trúc thừa kế là MVP, hiện được ứng dụng rộng rãi trong môi trường .NET.
Mẫu kiến trúc Model-View-Controller chia nhỏ các thành phần dữ liệu, thể hiện (output) và dữ liệu nhập từ người dùng (input) thành những thành phần riêng biệt.
Model chứa dữ liệu và các tính toán xử lý logic để giải quyết vấn đề mà phần mềm hướng tới (business logic). Thành phần model thường được trình bày ở dạng Domain Model.
View là thành phần đảm nhận việc thể hiện những dữ liệu của Model. View bao gồm những gì thể hiện trên màn hình như các control, form... Trên cùng một Model, có thể có nhiều View.
Controller là thành phần đảm nhận việc xử lý đáp trả lại các dữ liệu được đưa vào từ người dùng như các sự kiện chuột, bàn phím, các tương tác lên các control... Controller là cầu nối giữa người dùng và ứng dụng.
Sự phụ thuộc của Model vào các thành phần khác và tại một thời điểm khó xác định điều gì sẽ xảy ra khi đọc code và việc kiểm tra cũng khó khăn hơn.
Kiến trúc MVP dựa trên tư tưởng cơ bản của MVC nhưng với cách tiếp cận khác nhằm khắc phục các hạn chế của MVC cổ điển.

Các thành phần của MVP
Model chứa dữ liệu và các tính toán xử lý logic để giải quyết vấn đề mà phần mềm hướng tới.
View là thành phần đảm nhận việc thể hiện những dữ liệu của Model và là tổng hợp của các form, control được sử dụng.
Presenter là thành phần đảm nhận các xử lý thể hiện cũng như tương tác đến dữ liệu bên dưới và có thể tương tác để thay đổi View trong quá trình xử lý.
Phối hợp các thành phần
Mẫu kiến trúc MVP của Microsoft tương tự như Passive View nhưng có bổ sung ràng buộc là Presenter chỉ có thể truy cập đến View thông qua interface IView. Điều này giúp Presenter không phụ thuộc đến cài đặt cụ thể của View và có thể dễ dàng kiểm tra Presenter một cách độc lập.
Mối quan hệ giữa Presenter và Model là quan hệ một chiều (chiều còn lại là gián tiếp). Hệ quả là chúng ta có một mô hình đa lớp như cấu trúc ở trên theo ý nghĩa các thành phần ở một lớp chỉ phụ thuộc và sử dụng các thành phần ở lớp ngay bên dưới nó.
Với MVP, một View gắn liền với một interface IView. Khi View được tạo ra, nó tạo ra một đối tượng private Presenter và gắn nó vào đối tượng này thông qua IView. Khi một sự kiện xảy ra, View bắt lấy và sau đó kích hoạt một phương thức của Presenter mà sau đó có thể tương tác với Model. Một số sự kiện như bắt đầu hiển thị và đóng của View cũng được gửi tới để Presenter kích hoạt một số phương thức tương ứng, điều này giúp cho một số công việc như khởi tạo và giải phóng dữ liệu cho View được dễ dàng hơn. Model được tổ chức bổ sung một lớp Service nằm bên trên để tương tác với Presenter.

11 thg 4, 2010

Exception trong java - Ngoại lệ trong java

1.1 Khái niệm và mục đích sử dụng
Exception là một đối tượng được tạo ra khi chương trình gặp lỗi được java trả về nhằm mục đích dò tìm và sửa lỗi chương trình
1.2 Các kiểu exception
Có ba kiểu exception trong java là checked exception, error và unchecked exception (runtime exception)
Checked exception là loại ngoại lệ phổ biến sử dụng để kiểm tra những lỗi phổ biến trong lúc biên dịch ví dụ bạn truy xuất một tập tin không tồn tại trên ổ đĩa thì bạn sẽ nhận được một java.io.FileNotFoundException. Checked exception kế thừa từ java.lang.Exception và chúng được dùng trong try-catch-finally.
Error là một loại lỗi nằm ngoài phạm vi ứng dụng, được java trả về trong đối tượng java.io.IOError. Ví dụ ứng dụng mở một tập tin thành công nhưng khi đọc dữ liệu lại không đọc được do ổ cứng bị hỏng một vài sector vật lý, …
Unchecked exception thường được hiểu là những exception được sinh ra do lỗi logic khi lập trình và được trả về lúc runtime. Unchecked exception kế thừa từ java.lang.RuntimeException
1.3 Bắt giữ và xử lý các exception
Để xử lý một exception ta dùng lệnh try-catch-finally, throw hoặc throws
Try chứa các dòng lệnh thực hiện một chức năng nào đó mà có thể gây ra exception
Catch chứa các dòng lệnh để xử lý kết quả khi nhận được một exception từ java sau khi khối try tạo ra exception.
Finally các dòng lệnh trong khối này luôn luôn được thưc thi khi thoát khối try
Ví dụ:
int a = 0;
int b = 1;
int c;

try {
c = b/a;
}
catch (ArithmeticException e)
{
System.out.println("Arithmetic Exception");
}
finally {
System.out.println("Finally");
}
Với đoạn code trên ta sẽ có kết quả in ra màn hình là:
Arithmetic Exception
Finally
throws
Ví dụ:
public static int getEndMember(int[] a) throws ArrayIndexOutOfBoundsException {
return a[a.length];
}
public static void main(String[] args) {
int[] a = {1, 2, 3};
try {
getEndMember(a);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException");
}
}
Đoạn code trên sẽ in ra ArrayIndexOutOfBoundsException bởi vì hàm getEndMember đã truy xuất phần tử a[3] không có trong mảng.
throw
Chúng ta cũng có thể dùng throw để quăng ra một exception Object
Ví dụ:
public static int getEndMember(int[] a) throws ArrayIndexOutOfBoundsException {
return a[a.length-1];
}
public static void main(String[] args) {
int[] a = {1, 2, 0};
int j;

try {
int i = getEndMember(a);
if (i == 0) {
throw new ArithmeticException();
}
else{
j = 10/i;
}
}
catch(ArithmeticException e) {
System.out.println("ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsExceptionkkkk");
}
}
Đoạn code trên sẽ in ra ArithmeticException bởi vì giá trị nhận được i = 0

1.4 Exception tự định nghĩa
Chúng ta có thể tự định nghĩa ra những lớp ngoại lệ riêng nếu chúng ta thấy java cung cấp chưa đủ thông tin ngoại lệ như chúng ta mong muốn.
Ví dụ về cách sử dụng exception tự định nghĩa:
class MyException extends Exception {
MyException() {

}
}

public class ExceptionDemo {
public static void executeHasException() throws MyException {
throw new MyException();
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
executeHasException();
} catch (MyException e) {
e.printStackTrace();
}
}
}
Và kết quả in ra màn hình sẽ là
exception_2.MyException
at exception_2.ExceptionDemo.executeHasException(ExceptionDemo.java:18)
at exception_2.ExceptionDemo.main(ExceptionDemo.java:27)

1.5 Một số exception đơn giản
a. NullPointerException (java.lang)
Xảy ra khi chúng ta tham khảo đến một đối tượng rỗng
Ví dụ:
• Gọi phương thức instance của một đối tượng rỗng
• Truy cập thuộc tính của một đối tượng rỗng
• …
int[] a = null;
int b;

try {
b = a[10];
}
catch (NullPointerException e)
{
System.out.println("NullPointerException"); //In ra NullPointerException
}
Đoạn code trên sinh ra một exception NullPointerException bởi vì đối tượng a là rỗng mà chúng ta vẫn truy cập thuộc tính của nó.

b. NumberFormatException (java.lang)
Một exception cũng khá thường gặp là khi biến đổi string sang số
Ví dụ:
String s = "Luvina";

try {
int i = Integer.parseInt(s);
}
catch (NumberFormatException e)
{
System.out.println("NumberFormatException"); //In ra NumberFormatException
}
Đoạn code trên sẽ xảy ra exception vì chuỗi s không thể biến đổi thành số nguyên i được

c. ArayIndexOutOfBoundsException (java.lang)
Truy xuất phần tử ngoài phạm vi của mảng
int[] a = {1, 2, 3};
int b;

try {
b = a[10];
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("ArrayIndexOutOfBoundsException");
}

d. ArithmeticException (java.lang)
Lỗi do các biểu thức toán học, thường là do chia cho 0
Ví dụ:
int a = 0;
int b = 1;
int c;

try {
c = b/a;
}
catch (ArithmeticException e)
{
System.out.println("Arithmetic Exception");
}

Lập trình java và kỹ năng căn bản

1.1 Giới thiệu
Java là một ngôn ngữ lập trình hướng đối tượng, là một ngôn ngữ vừa biên dịch và thông dịch. Mã nguồn java được biên dịch ra dạng ByteCode (tập tin với phần mở rộng .class) bằng trình biên dịch ví dụ javac. Sau đó sẽ đem đi thực thi trên từng platform khác nhau bằng một cộng cụ thông dịch thường gọi là JVM

1.2 Môi trường java
JDK (java development kit) là bộ công cụ phát triển phần mềm cho java, nó bao gồm nhiều công cụ tiện ích như trình biên dịch (javac), chương trình phát sinh tài liệu (javadoc), đóng gói dữ liệu (jar), chương trình tìm lỗi (jdb),…
JVM (Java Virtual Machine) là một phần mềm dùng để biên dịch các mã ByteCode java sang mã máy. Máy ảo java giống như một kênh liên kết phần cứng thiết bị, hệ điều hành và chương trình java để làm sao có thể chuyển chương trình java thành mã thực thi trên thiết bị đó.
Java API (Java Application Programming Interface) là một thư viện chứa các tiện ích giúp hỗ trợ việc lập trình bằng ngôn ngữ java, các tiện ích thường được đóng thành các gói (package). Java API thường được chia thành 2 phần Core API và Extension API. Core API thường gồm các package như java.lang, java.io, java.apple, java. awt, java.net, java.sql… Extension API chứa các gói dữ liệu tiện ích để bổ sung cho Java Core API như javax.crypto… Chú ý tùy từng phiên bản jdk mà có hỗ trợ gói extension API đó hay không.
Java compiler là compiler dùng để biên dịch mã nguồn java sang dạng bytecode (.class file). Những file này muốn thực thi thì cần dùng bộ JRE (Java Runtime Environment) trong JVM

Ví dụ cách thực thi một file java từ dòng lệnh dùng trình biên dịch có sẵn trong bộ jdk là javac.exe



1.3 Các kiểu dữ liệu cơ bản
Java cung cấp các kiểu dữ liệu cơ bản nguyên thủy (primitive) như:
Kiểu dữ liệu Độ dài theo số bit Phạm vi Mô tả
byte 8 -128 đến 127 Chúng được sử dụng rộng rãi khi xử lý một file văn bản
Char 16 ‘\uoooo’ to ’u\ffff ’ Kiểu Char sử dụng để lưu tên hoặc các dữ liệu ký tự
Boolean 1 “True” hoặc “False” Dữ liệu boolean dùng để lưu các giá trị “Đúng” hoặc “sai”
short 16 -32768 đến 32767 Kiểu short dùng để lưu các số nguyên có giá trị nhỏ.
Int 32 -2,147,483,648 đến +2,147,483,648 Kiểu int dùng để lưu một số nguyên có giá trị lớn đến 2,147,483,648
Long 64 -9,223,372,036’854,775,808 đến +9,223,372,036’854,775,808 Kiểu này dùng để lưu các số nguyên có giá trị cực lớn
Float 32 -3.40292347E+38 đến +3.40292347E+38 Kiểu float dùng để lưu các số thập phân đến 3.40292347E+38 Ví dụ : giá thành sản phẩm
double 64 -1,79769313486231570E+308 đến +1,79769313486231570E+308 Kiểu double dùng để lưu các số thập phân có giá trị lớn đến
1,79769313486231570E+308 Ví dụ giá trị tín dụng của ngân hàng nhà nước.

Ngoài ra java còn có 3 kiểu dữ liệu khác gọi là kiểu dữ liệu tham chiếu (reference)
Kiểu dữ liệu Giải thích
Mảng (Array) Tập hợp các dữ liệu cùng loại. Ví dụ : tên sinh viên
Lớp (Class) Tập hợp các biến và các phương thức.Ví dụ: lớp “Sinhviên” chứa toàn bộ các chi tiết của một sinh viên và các phương thức thực thi trên các chi tiết đó.
Giao diện (Interface) Là một lớp trừu tượng được tạo ra để bổ sung cho các kế thừa đa lớp trong Java.


1.4 Biến và toán tử
a. Biến
Như các ngôn ngữ lập trình khác, java sử dụng các biến để lưu dữ liệu cần thiết trong lúc chương trình thực thi. Các biên luôn đươc phân biệt bằng tên và phạm vi tác động. Khai báo biến: Kiểu dữ liệu, tên biến, giá trị ban đầu (không bắt buộc)
Datatype indentifier [=value] [, indentifier[=value]… ];
Ví dụ:
int count=0;
float salary;

Java định nghĩa hai loại biến:
• Biến không có từ khóa static: tức là biến khai báo bình thường như ví dụ trên. Và muốn truy xuất biến thì bạn cần tạo ra một đối tượng của class chứa biến đó là truy xuất biến bình thường
• Biến có từ khóa static: Trong khai báo biến bạn thêm từ khóa static ở đầu lệnh khai báo. Bạn có thể truy xuất biến này bằng cách như biến không có từ khóa static hoặc bằng cách dùng tên lớp gọi (.) biến.
VD:
class MyStaticVariables {
static int count = 10;
}
Truy cập
int mySVCount = MyStaticVariables.count; //Se tra ve gia tri la 10

Phân biệt giữa biến static và non-static: biến non-static chỉ có thể truy cập khi bạn có đối của lớp và mỗi đối tượng sẽ có những vùng nhớ khác nhau để lưu giữ biến. Biến static không bắt buộc phải tạo ra đối tượng mới có thể truy cập vào biến và sẽ chỉ có một vùng nhớ duy nhất cho biến trong chương trình cho dù bạn tao nhiều đối tượng.

Trong java các biến cũng sẽ được phân biệt phạm vi như các ngôn ngữ lập trình khác đó là khai báo phạm vi nào thì dùng trong phạm vi đó. Ví dụ bạn khai báo biến trong hàm f thì chỉ sử dụng được trong hàm f

b. Toán tử
Java hỗ trợ rất nhiều toán tử phổ biến như các ngôn ngữ lập trình khác:
Gán Giải thích
= Gán bằng
+= Cộng rồi gán
-= Trừ rồi gán
*= Nhân rồi gán
/= Chia rồi gán
%= Lấy dư rồi gán
<<= Dịch trái rồi gán
>>= Dịch phải rồi gán
>>>= Dịch phải rồi gán (không dấu)
&= AND bằng
^= XOR bằng
|= OR bằng
Số học căn bản
+ Cộng
- Trừ
* Nhân
/ Chia
% Lấy phần dư
Quan hệ
== So sánh bằng
> Lớn hơn
>= Lớn hơn hoặc bằng
< Nhỏ hơn
<= Nhỏ hơn hoặc bằng
!= So sánh khác
instanceof Kiểm tra loại dữ liệu
Logic và điều kiện
&& AND
|| OR
?: Kiểm tra và lấy giá trị
Đơn nhất
+ Giá trị dương
- Giá trị âm
! Giá trị phủ định
++ Tăng 1 đơn vị
-- Giảm một đơn vị
Dịch bit
~ Phủ định
<< Dịch trái 1 bit
>> Dịch phải 1 bit
>>> Dịch phải 1 bit (không dấu)
& AND
^ XOR
| OR
Khác
[] Truy cập phần tử mảng
. Truy cập vào thành viên lớp
new Tạo ra một đối tượng mới

Và thứ tự ưu tiên giữa các toán tử như sau:
Thứ tự Toán tử
1 Các toán tử đơn nhất như +,-,++,--
2 Các toán tử số học và các toán tử dịch bit như *,/,+,-,<<,>>
3 Các toán tử quan hệ như >,<,>=,<=,= =,!=
4 Các toán tử logic và Bit như &&,II,&,I,^
5 Các toán tử gán như =,*=,/=,+=,-=



1.5 Cấu trúc điều khiển
Trong java sử dụng các cấu trúc điều khiển sau:

Điều khiển rẽ nhánh
• if-else
/*Print i < j*/
int i = 0;
int j = 1;
if (i < j)
{
System.out.println("i < j");
}
else
{
System.out.println("i > j");
}

• switch-case
/*Print Thursday*/
int day =4;
switch(day) {
case 0 :
System.out.println("Sunday");
break;

case 1 :
System.out.println("Monday");
break;

case 2 :
System.out.println("Tuesday");
break;

case 3 :
System.out.println("Wednesday");
break;

case 4 :
System.out.println("Thursday");
break;

case 5 :
System.out.println("Friday");
break;

case 6 :
System.out.println("Satuday");
break;

case 7 :
System.out.println("Saturday");
break;

default :
System.out.println("Invalid day of week");
break;
}
Vòng lặp
• while
VD:
int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int i = 0;
while(i < 10) {
System.out.println(a);
i++;
}

• do-while
int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int i = 0;
do {
System.out.println(a);
i++;
} while (i < 10);

• for
VD1:
int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for(int i = 0; i < 10; i++){
System.out.println(a);
}

VD2:
int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for(int i : a){
System.out.println(i);
}

1.6 Các hàm toán học cơ bản
Package java.lang chứa những phương thức cơ bản nhất trong lập trình java và các hàm toán học cơ bản được đặt trong package java.lang.Math
• abs()
Trả về giá trị tuyệt đối của một số
int num = -1;
Math.abs(num); //Tra ve 1
• ceil()
Trả về số nguyên lớn hơn tham số truyền vào
Math.ceil(10.009); //Tra ve 11
• floor
Trả về số nguyên nhỏ hơn tham số truyền vào
Math.abs(num); //Tra ve 1
• pow(a, b)
Trả về một số double có giá trị là ab
Math.pow(2, 3); //Tra ve 8.0
• max()
Tìm giá trị lớn nhất trong hai giá trị được truyền vào
int a = -1;
int b = 1;
Math.max(a, b); //Tra ve 1
• min
Tìm giá trị nhỏ nhất trong hai giá trị được truyền vào
int a = -1;
int b = 1;
Math.min(a, b); //Tra ve -1
• round()
Làm tròn số có dấy chấm động và trả về một số kiểu long
double a = 1.2;
Math.round(a); //Tra ve 1

• random()
Trả về một số ngẫu nhiên có kiểu double trong khoảng 0.0-1.0
• sqrt()
Trả về căn bậc 2 của một số
double a = 1.44;
Math.sqrt(a); //Tra ve 1.2
• sin()
Trả về sine của một số

Math.sin(Math.PI/2); //Tra ve 1.0

• cos()
Trả về cosin của một số

Math.cos(Math.PI/2); //Tra ve 0.0

• tan()
Trả về tang của một số

Math.tab(-Math.PI); //Tra ve 0.0

1.7 Cấu trúc chương trình java

Một chương trình java được được chia thành các gói, lớp riêng biệt. Tất cả các biến, hàm phải được thực thi trong phạm vi của lớp. Chúng ta hãy xem một chương trình java đơn giản:

public class HelloLuvina {
public static void main(String[] args) {
System.out.println("Hello Luvina"); //Tra ve Hello Luvina
}
}

Đầu tiên là chúng ta có một lớp tên là HelloLuvina, trong lớp có một phương thức main. Phương thức main là điểm bắt đầu để thực thi ứng dụng, mỗi ứng dụng phải chứa một phương thức main có dạng public static void main(String[] args). Sau đây chúng ta sẽ phân tích các thành phần chính của phương thức main:
• public chỉ ra rằng phương thức main có thể được gọi bởi bất kỳ đối tượng nào.
• static chỉ ra rắng phương thức main là một phương thức lớp và có duy nhất một vùng nhớ lưu giữ nó và không cần tạo một đối tượng của lớp thì JVM vẫn có thể gọi tới phương thức main này để thực thi.
• void chỉ ra rằng phương thức main sẽ không trả về bất kỳ một giá trị nào.
• args là một mảng các chuỗi là những tham số mà bạn có thể truyền vào khi thực thi ứng dụng java
Dòng lệnh System.out.println("Hello Luvina"); dùng để in ra màn hình chuỗi “Hello Luvina”
Trong đầu mỗi chương trình java thường có thêm những thông tin để chương trình xác định thông tin môi trường, những thông tin này được chỉ dẫn bằng phát biểu “import”, ví dụ: import java.io.*; là để chỉ dẫn chương trình sử dụng tất cả các lớp trong gói nhập xuất. Khái niệm gói (package) ra đời từ ý nghĩa cần tổ chức quản lý tốt hơn, linh hoạt hơn, từ các thông tin, yêu cầu chúng ta đóng gói thành lớp, và để quản lý nhiều lớp có cùng một số điểm chung nào đó chúng ta nhóm chúng thành các gói và khi cần sử dụng phần nào hay toàn bộ gói chúng ta dùng lệnh “import”

Đối với ứng dụng applet thì cấu trúc chương trình sẽ khác ứng dụng java thông thường, chúng thường gồm các phương thức public void init(), public void start(), public void paint(Graphics g), public void destroy() … Chúng ta sẽ tìm hiểu applet trong các phần sau.
1.8 Cách đọc tham số và chuẩn hóa code convention
a. Tham số dòng lệnh
Chúng ta sẽ xem chương trình sau:
public class HelloLuvina {
public static void main(String[] args) {
System.out.println("Hello Luvina"); //Tra ve Hello Luvina
int length = args.length;
for(int i = 0; i < length; i++) {
System.out.println(args); //Tra ve cac tham so
}
}
}
Kết quả thực thi như sau:


Nhìn vào kết quả ta thấy các tham số được phân biệt với nhau bằng dấu khoảng trắng (white space)
b. Truyền tham số
Như trong phần các kiểu dữ liệu cơ bản, chúng ta thấy trong java có 2 kiểu là primitive và reference. Các tham số được truyền theo lời gọi hàm thì được thực hiện theo nguyên tắc: tham trị (pass-by-value) dùng cho 8 kiểu dữ liệu primitive, tham biến (pass-by-reference) dùng cho 3 kiểu dữ liệu reference.
Chúng ta xem ví dụ sau:
class Parameter {
public void passByValue(int a) {
a = 0;
}
public void passByReference(int[] array) {
array[0] = 0;
array[1] = 10;
}
}

public class HelloLuvina {
public static void main(String[] args) {
int number = 10;
int[] arrayOfStaffId = {1, 2};
Parameter p = new Parameter();
p.passByValue(number);
p.passByReference(arrayOfStaffId);

System.out.println(number); //In ra 10
for(int Id : arrayOfStaffId) {
System.out.println(Id); //In ra 0 va 10
}
}
}
Vì number sau lời gọi hàm không thay đổi giá trị vì nó là kiểu primitive nên tham số truyền sẽ là tham trị. Còn mảng arrayOfStaffId là kiểu reference nên tham số truyền là tham biến và giá trị của nó sẽ bị thay đổi.
• Truyền tham số kiểu Varargs (variable arguments)
Chúng ta hãy xem ví dụ sau:
public class HelloLuvina {
public static int makeSum(int... array) {
int sum = 0;
for (int i : array) {
sum += i;
}
return sum;
}

public static void main(String[] args) {
int sum = makeSum(1);
System.out.println(sum); //In ra 1

sum = makeSum(1, 2, 3);
System.out.println(sum); //In ra 6

int[] array = {1, 2, 3, 4, 5};
sum = makeSum(array);
System.out.println(sum); //In ra 15


}
}
Chúng ta hãy nhìn tham số array khai báo trong phương thức makeSum, kiểu khai báo … này được gọi là varargs và có từ java 5. Tiếp đến chúng chúng ta sẽ xem 3 dòng gọi hàm makeSum trong hàm main. Với các gọi có thể truyền như một mảng hay một chuỗi các tham số và Tính năng varargs sẽ tự động thực hiện việc tạo ra mảng tham số cho ta và đồng thời che dấu nó khỏi chương trình. Điều này giúp code trông tự nhiên và gọn gàng hơn.
Một lưu ý là trong một hàm ta chỉ có thể khai báo duy nhất một tham số kiểu varargs và phải là tham số cuối cùng, nếu không trình biên dịch sẽ báo lỗi. Ví dụ
public static int makeSum(int... array, int index) {…} //Sai
public static int makeSum(int index, int... array, int... array1) {…} //Sai
public static int makeSum(int index, int... array) {…} //Dung

1.9 Khái niệm kế thừa, đa hình, interface, constructor, final, overload, override
Trong phần này tôi sẽ giới thiệu về các khái niệm cơ bản của lập trình hướng đối tượng trong java. Các đặc điểm của lập trình hướng đối tượng thì chúng ta đã biết, trong phần này chúng ta sẽ nghiên cứu trực tiếp sự thể hiện hướng đối tượng trong java như thế nào
Kế thừa trong java sử dụng từ khóa extends, ví dụ bạn có lớp Car và một lớp Toyota kế thừa từ lớp Car, bạn sẽ viết như sau:
class Car {

}

class Toyota extends Car {

}
Và khi lớp Toyota được kế thừa từ Car thì nó sẽ nhận tất cả các thông tin được phép của lớp Car làm của mình hoặc có thể thay thế các phương thức này bằng các khai báo chồng.
Lớp trừu tượng là lớp không cụ thể, chứa những method nhưng không có dòng lệnh thi hành phương thức đó, việc thi hành method được giao lại cho các lớp kế thừa lớp đó, ví dụ:
abstract class Vehicle {
abstract void move(int x, int y);
abstract void setSize(int x, int y);
abstract void setColor(Color pColor);
}

class Car extends Vehicle{
void move(int x, int y) {
System.out.println("Method [move] from class [Car]");
}
void setSize(int x, int y) {
System.out.println("Method [setSize] from class [Car]");
}
void setColor(Color pColor) {
System.out.println("Method [setColor] from class [Car]");
}
}

Lưu ý là một lớp chỉ được kế thừa duy nhất từ một lớp cha (kể cả abstract class)
Interface là một khái niệm mới trong các ngôn ngữ lập trình hiện đại, thường được hiểu là giao diện của lớp đối tượng. Tức là interface chứa những thành phần (phương thức) để các lớp khác kế thừa, và các phương thức trong interface không có phần cài đặt mà chỉ có phần khai báo.
Một class kế thừa một interface nào thì bắt buộc phải cài đặt tất cả các method của interface đó. Một đối tượng có thể đưa ra nhiều interface của mình, và như vậy chúng java không có đa kế thừa nhưng chúng ta cũng có thể làm bằng các interface.
Chúng ta dùng từ khóa implements để kế thừa từ một interface, ví dụ ta có một interface là QualityAssurance và một lớp là Car để kế thừa những phương thức kiểm tra chất lượng từ interface đó:

interface QualityAssurance {

}

class Car implements QualityAssurance{

}

Constructor là một phương thức dùng để khởi tạo lớp và truyền tham số để khởi tạo giá trị cho một đối tượng. Constructor trong java cũng có tên giống với tên lớp, không có kiểu trả về và không có cả từ khóa void, một lớp có thể có nhiều constructor và constructor không được kế thừa.



1.10 Ép kiểu và generic type
Java cung cấp các loại ép kiểu sau:
• Implicit Casting (automatic casting) là loại tự động ép kiểu khi phép gán giữa hai kiểu khác nhau và được thực hiện bởi trình biên dịch. Ví dụ:
int a = 1;
double b = a;
System.out.println(b); //In ra 1.0
Một quy tắc đơn giản trong ép kiểu là ép từ kiểu bé sang kiểu lớn thì được, vì kiểu lớn mới có thể chứa hết kiểu bé và không mất dữ liệu. Và quy tắc cho các kiểu cơ bản là:
byte -> short-> int -> long -> float -> double
Tương tự cho các đối tượng, ép từ đối tượng con sang đối tượng cha thì được. Ví dụ ta có lớp Car và lớp Ferrary kế thừa từ Car, và một đối tượng thuộc lớp Ferrary có thể được ép kiểu thành đối tượng thuộc lớp Car, ngược lại thì không thể.

Explicit casting là dạng ép kiểu được ghi tường minh trong chương trình. Ví dụ:
double b = 1.9;
short c = (short)b;
System.out.println(c); //In ra 1

Generic
Generic là một khái niệm mới và bắt đầu có từ java 5, nếu ai lập trình nhiều về template trong c++ thì Generic trong java cũng tương tự. Ưu điểm của Generic là linh động trong việc truyền tham số, và một ưu điểm người ta hay nhắc tới của Generic là làm cho chương trình ổn định hơn và tránh các lỗi ép kiểu.
Chúng ta xem ví dụ:
List l = new ArrayList();
l.add(1);
Integer i = (Integer)l.get(0);
System.out.println(i); //In ra 1

Ví dụ trên chạy tốt và in ra 1. Tuy nhiên chúng ta chỉnh một chút là add một chuỗi vào danh sách như sau:
List l = new ArrayList();
l.add("nice");
Integer i = (Integer)l.get(0);
System.out.println(i);
Chương trình chỉ bị lỗi lúc runtime, và do đó đôi khi không để ý là chúng ta có thể mắc lỗi này. Generic ra đời để giúp chúng ta có thể thấy tường minh lỗi trong khi code, tránh trường hợp lỗi tiềm tàng khi runtime. Ví dụ:
List l = new ArrayList();
l.add(1);
Integer i = (Integer)l.get(0);
System.out.println(i); //In ra 1
Chương trình chạy và in ra 1. Còn khi bạn viết như dưới bạn sẽ bị một lỗi ngay lúc compiler là không tương thích kiểu và như vậy là chúng ta có thể nhận được lỗi lúc biên soạn tránh được lỗi tiềm tàng.
List l = new ArrayList();
l.add("nice"); //Báo lỗi khi biên dịch
Integer i = (Integer)l.get(0);
System.out.println(i);

19 thg 3, 2010

Giới thiệu về Java Threads - lập trình đa luồng trong Java

Giới thiệu về Threads-lập trình đa luồng trong Java


ThreadCó một định nghĩa về thread như sau :



Thread là một dòng các điều khiển trong một process hay một ứng dụng. Nguyên văn là : Threads are multiple flows of control within a single program or process.



Với cơ chế multithreading ứng dụng của ta có thể thực thi đồng thời nhiều dòng lệnh cùng lúc. Có nghĩa là ta có thể làm nhiều công việc đồng thời trong cùng một ứng dụng của ta. Có thể hiểu một cách hết sức đơn giản : hệ điều hành với cơ chế đa nhiệm cho phép nhiều ứng dụng chạy cùng lúc. Thì với cơ chế đa luồng, mỗi ứng dụng của ta có thể thực hiện được nhiều công việc đồng thời.




Tại sao không dùng nhiều processes , sao không là multiprocessing mà lại cần đến multithreading ?



Câu trả lời đơn giản nhất là: Việc tạo ra và quản lý các process đòi hỏi nhiều tài nguyên của hệ thống (cả ram và CPU) nhiều hơn rất nhiều so với việc tạo ra một thread. Trong khi đó có thể chỉ cần tạo ra một thread để thực hiện song song một công việc hết sức đơn giản cùng với một công việc chính.



Viết một ứng dụng Java trên bất kỳ nền tảng nào. Khi ứng dụng ,ta chạy thì thực sự đã có một bản sao của JVM khởi động và ứng dụng của ta là một thread nếu ta không dùng multithreading hoặc là nhiều threads nếu tadùng multithreading.



Tạo một threadNhư đã nói, mỗi khi chạy một ứng dụng trong java thì đã có một thread. Đây là thread chính, nó thực thi các dóng lệnh trong method : public static void main . Đây là một điểm nhập bắt buộc cho mọi ứng dụng độc lập.



Để tạo ra một thread khác ngoài thread chính trên, Java cung cấp cho chúng ta hai cách :



- Tạo ra một lớp con của lớp Thread (java.lang.Thread)



- Tạo ra một lớp hiện thực interface Runnable



Chúng ta sẽ tìm hiểu lần lược hai cách trên.




Tạo một lớp con của lớp java.lang.Thread



Bạn khai báo như sau :



class A extends Thread {



public void run() {



... // code for the new thread to execute



}



}



...



A a = new A(); // create the thread object




a.start(); // start the new thread executing



...



Với cách này các dòng lệnh sẽ được đặt trong method run. Method này được override method nguyên thuỷ của lớp Thread.



Sau đó ta sẽ tạo ra một đối tượng từ lớp của ta.



Gọi phương thức start từ đối tượng đó. Lúc này thread của ta chính thức được tạo ra và phương thức start sẽ tự gọi method run của tavà thực thi các dòng lệnh mà đã đặc tả.



Chú ý rằng: method start là method của hệ thống, nó có nhiệu vụ cấp phát bộ nhớ, tạo ra một thread và gọi hàm run của ta. Vì thế không nên override phương thức này. Điều này có thể dẫn đến ko tạo được thread.



Hiện thực interface Runnable

Khai báo như sau:



class B extends … implements Runnable {




public void run() {



... // code for the new thread to execute



}



}



...



B b = new B(); // create the Runnable object



Thread t = new Thread(b); // create a thread object



t.start(); // start the new thread




...



Cũng giống như cách trên, dòng lệnh đặt trong method run (có thể gọi đến các phương thức khác, nhưng phải bắt đầu trong phương thức này)



Sau đó tạo một đối tượng B từ lớp đã hiện thực interface Runnable, tạo thêm một đối tượng t của lớp Thread với thông số cho constructor là đối tượng B.



Sau đó khi gọi phương thức t.start() thì chính thức thread được tạo ra và phương thức run sẽ được triệu gọi một cách tự động.



Bạn sẽ hỏi tại cách thứ hai vẫn phải tạo ra một đối tượng Thread. Vậy tại sao lại đưa ra hai cách hiện thực làm gì ?



Câu trả lời là :



- Bản thân ngôn ngữ Java không hỗ trợ đa thừa kế . Bạn chỉ có thể extends từ một lớp duy nhất. Nhưng bạn lại có thể implements cùng lúc nhiều interface. Khi mà lớp của ta đã [extends] một lớp nào đó rồi (vd : Applet), thì chỉ có thể implements Runnable để tạo ra Thread.



- Việc extends lớp Thread có thể dẫn đến rủi ro là bạn override các method start, stop, ... thì có thể làm cho việc tạo thread là không thể.



Một lời khuyên là: nên tạo ra một lớp hiện thực interface Runnable (cách thứ hai) khi muốn tạo ra một Thread. Chương trình sẽ trong sáng và dễ tìm lỗi hơn.


Việc đồng bộ hóa một method là cách tốt nhất để hạn chế việc sử dụng một method tại một thời điểm. Tuy nhiên sẽ có những trường hợp mà bạn không thể đồng bộ hóa một method, chẳng hạn như khi bạn sử dụng một class được cung cấp bởi bên thứ ba. Trong những trường hợp như thế, bạn không được phép truy cập vào định nghĩa lớp, sẽ ngăn bạn sử dụng từ khóa synchronized.



Sử dụng phát biểu được đồng bộ hoá



Một cách khác để sử dụng từ khóa synchronized là sử dụng phát biểu được đồng bộ hóa. Một phát biểu được đồng bộ hóa chứa một block được đồng bộ hóa , mà bên trong đó đặt những đối tượng và những method được đồng bộ hóa. Gọi các method chứa block được đồng bộ hóa xảy ra khi một thread có được monitor của đối tượng.

Mặc dù bạn có thể gọi những method bên trong một block được đồng bộ hóa, việc công bố method phải được thực hiện bên ngoài một block được đồng bộ hóa.

Ví dụ dưới đây chỉ cách làm thế nào để sử dụng một phát biểu được đồng bộ hóa. Ví dụ này cơ bản cũng giống ví dụ trước, tuy nhiên phát biểu được đồng bộ hóa được sử dụng thay vì từ khóa synchronized. Phát biểu này được đặt trong method run() của class MyThread. Phát biểu được đồng bộ hóa sẽ đồng bộ hóa instance của class Parentheses và vì thế ngăn hai thread sử dụng method display() cùng một lúc.


class Parentheses {
void display(String s) {
System.out.print (”(” + s);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
System.out.println (”Interrupted”);
}
System.out.println(”)”);
}
}

class MyThread implements Runnable {
String s1;
Parentheses p1;
Thread t;
public MyThread (Parentheses p2, String s2) {
p1= p2;
s1= s2;
t = new Thread(this);
t.start();
}
public void run() {
synchronized(p1){
p1.display(s1);
}
}
}

class Demo{
public static void main (String args[]) {
Parentheses p3 = new Parentheses();
MyThread name1 = new MyThread(p3, “Bob”);
MyThread name2 = new MyThread(p3, “Mary”);
try {
name1.t.join();
name2.t.join();
} catch (InterruptedException e ) {
System.out.println( “Interrupted”);
}
}
}


Ở đây, method display() không sử dụng từ khóa synchronized. Thay vào đó, phát biểu được đồng bộ hóa được sử dụng bên trong method run(). Điều này cho kết quả giống với ví dụ trước bởi vì một thread chờ một khoảng thời gian để thread còn lại kết thúc trước khi tiếp tục xử lý.



Giao tiếp giữa các thread



Các thread mở ra cho các lập trình viên một khoảng không mới trong lập trình, nơi mà ở đó những phần của một chương trình thực thi không đồng bộ với nhau, mỗi một xử lý độc lập với những xử lý khác. Tuy nhiên mỗi thread thỉnh thoảng cần tính toán việc xử lý của chúng và vì thế cần có thể giao tiếp với những thread khác trong suốt quá trình xử lý. Các lập trình viên gọi đây là inter-process communication (giao tiếp trong xử lý).

Bạn có thể có các thread giao tiếp với các thread khác trong chương trình của bạn bằng cách sử dụng những method wait(), notify() và notifyAll(). Những method này được gọi từ bên trong một method được đồng bộ hóa. Method wait() nói cho một thread giải phóng monitor và đi vào trạng thái suspend. Có hai dạng method wait() khác nhau. Một dạng không yêu cầu đối số và vì thế một thread sẽ chờ cho đến khi nó được thông báo. Một dạng khác có đối số để bạn xác định khoảng thời gian chờ. Bạn xác định độ dài thời gian trong mili giây và đặt nó vào trong method wait().

Method notify() nói cho một thread đang suspend bởi method wait() và lấy lại điều khiển của monitor. Method notifyAll() đánh thức tất cả các thread đang chờ điều khiển của monitor. Những thread khác chờ trong trạng thái suspend cho đến khi monitor có sẵn trở lại.


Ví dụ dưới đây chỉ cho bạn làm thế nào để sử dụng những method này trong một ứng dụng. Mục đích của chương trình là có một class Pulishser cho một giá trị cho class Consumer thông qua sử dụng class Queue. Ví dụ này định nghĩa bốn class, class Pulisher, class Comsumer, class Queue và class Demo. Class Queue định nghĩa hai instance: exchangeValue và một biến cờ. exchangeValue đặt vào một giá trị trong queue bởi publisher. Biến cờ được sử dụng như một cách đánh dấu giá trị được đặt vào trong queue. Class Queue cũng định nghĩa một method get() và một method put(). Method put() sử dụng để đặt một giá trị vào queue (gán một giá trị cho exchangeValue), method get() sử dụng để nhận giá trị chứa trong queue (trả về giá trị của exchangeValue. Khi một giá trị được gán, method put() thay đổi giá trị của biến cờ từ false thành true xác định một giá trị được đặt vào trong queue. Chú ý giá trị của biến cờ được sử dụng như thế nào trong method get() và method put() để có thread gọi method chờ cho đến khi có một giá trị trong queue hoặc không có giá trị nào trong queue, phụ thuộc vào method nào đang được gọi.

Class Publisher công bố một instance của class Queue và sau đó gọi method put() đặt vào năm số nguyên integer trong queue. Mặc dù method put() được đặt trong một vòng lặp for, mỗi số nguyên integer được đặt vào trong queue, và sau đó có một khoảng tạm dừng cho đến khi số nguyên integer được nhận bởi class Consumer.

Class Consumer tương tự như thiết kế class Publisher, ngoại trừ class Consumer gọi method get() năm lần bên trong một vòng lặp for. Mỗi lần gọi, method get() tạm dừng cho đến khi class Publisher đặt một số nguyên integer vào trong queue.

Method main() của class Demo tạo ra các instance của class Publisher, class Consumer và class Queue. Chú ý rằng các khởi dựng của của class Publisher và class Consumer đều đặt vào một reference đến instance của class Queue. Chúng sử dụng instance của class Queue cho inter-process communication.

Dưới đây là những gì mà bạn sẽ thấy khi chạy chương trình và mã nguồn của ví dụ

Put: 0

Get: 0

Put: 1

Get: 1

Put: 2

Get: 2

Put: 3

Get: 3

Put: 4

Get: 4


class Queue {
int exchangeValue;
boolean busy = false;
synchronized int get() {
if (!busy)
try {
wait();
} catch (InterruptedException e) {
System.out.println(
“Get: InterruptedException”);
}
System.out.println(”Get: ” + exchangeValue);
notify();
return exchangeValue;
}
synchronized void put (int exchangeValue) {
if (busy)
try {
wait();
} catch (InterruptedException e) {
System.out.println(
“Put: InterruptedException”);
}
this.exchangeValue = exchangeValue;
busy = true;
System.out.println(”Put: ” + exchangeValue);
notify();
}
}

class Publisher implements Runnable {
Queue q;
Publisher(Queue q) {
this.q = q;
new Thread (this, “Publisher”).start();
}
public void run() {
for (int i = 0; i < 5; i++){
q.put(i);
}
}
}

class Consumer implements Runnable {
Queue q;
Consumer (Queue q) {
this.q = q;
new Thread (this, “Consumer”).start();
}
public void run() {
for (int i = 0; i < 5; i++){
q.get();
}
}
}

class Demo {
public static void main(String args []) {
Queue q = new Queue ();
new Publisher (q);
new Consumer (q);
}
}




16 thg 3, 2010

Facebook | Tuan Nx, Một ngày se lạnh thú vị

Một chiều thu, thời tiết se lạnh… ảnh hưởng bão mà. Không đến mức phải mặc áo thật dầy, nhưng cũng đủ để ngta phải cuống quít tìm cái áo thu để mặc. Thời tiết thế này, thik nhất được ngồi trà nóng vỉa hè với mấy anh em, tán gẫu ba chuyện lăng nhăng nhưng khá thú vị :D.

Sẽ chẳng có j để viết tiếp nếu như chiều nay…không có cuộc gặp gỡ bất ngờ đó, không có vụ phải đợi đến 30’ trong tâm trạng vừa háo hức + lo lắng cho một người chỉ mới gặp lần đầu….

Mấy anh em đang nói chuyện, thì bỗng có một nhỏ đi ngang qua. Dáng người, khuôn mặt cũng không có j ấn tượg lắm, bởi lẽ cũng chỉ là những người đi lại trên đường thui. Nhưng đột nhiên nhỏ ngồi rụp xuống ôm bụng. Sẵn tính ga-lăng trong người (haha), Hắn tiến đến hỏi han, dìu nhỏ vào ghế ngồi, gọi cho nhỏ cốc trà nóng. Nhỏ thì vẫn ngồi ôm bụng vậy, mấy anh em hỏi han tí rùi lại quay lại câu chuyện của mình. Hắn để ý Nhỏ cứ nhìn đồng hồ lo lắng, Nhỏ hỏi đi xe bus bao nhiu để đến Chùa Láng????(Làm khó mình đây. Đã bj đi bus đến đóa đâu:-s.). Đã ga-lăng thì ga-lăng cho trót, với lại sắc mặt+tình trạng của nhỏ trong lúc này đi xe bus là không ổn chút nào, Hắn một mực bắt nhỏ lên xe và đưa đến trường. May quá ít ra mặt Hắn cũng có tem đảm bảo nên sau 2 3 lần từ chối, nhỏ cũng chịu lên. Trong lòng tự nhiên thấy vui vui vì làm được việc tốt^^. Hehe. Trên đường đưa nhỏ đi, Hắn bít được nhỏ học Ngân hàng, bình thường thì đi xe máy, mà hum nay mệt nên đi xe bus. Hum nay nhỏ đi học thêm TA, TOEIC j đó ở Chùa Láng, 7h30 là vào lớp, nhà nhỏ ở Định Công… Đưa nhỏ đến lớp xong Hắn và nhỏ tạm biệt, nhỏ cảm ơn và Hắn thì quay xe về nhà. Chuyện tưởng chừng đến đây là có thể kết thúc đc rùi. Nhưng trên đường về, Hắn thấy lạnh, áo cọc, quần ngố mừ, hjx. Nghĩ đến nhỏ bị đau bụng + lạnh thế này, lúc học về chắc cũng 9h 9h30….Sao mình hok làm ng tốt trọn vẹn nhỉ???...Hắn sẽ đón Nhỏ...Ha thế là một kế hoạch được định hình trong đầu, xem nào về nhà cơm nước tắm rửa, mặc thừa 1 cái áo rùi 9h kém ra đợi nhỏ là vừa.. WOAAA, 1 kế hoạch “chuẩn hok cần chỉnh”. Về nhà Hắn tiến hành theo đúng kế hoạch đề ra, hjx có tí ti thay đổi là Hắn mải xem nốt bộ phim nên hơi sai giờ chút^^.Cuối cùng thì cũng ra khỏi nhà,vận trên mình tới 3 cái áo lận…Úi chà chà. Như là sốt rét ế. Nhưng còn lâu mới sốt rét cái trời thế này nhé… Mặc nhìu áo lát về còn cho nhỏ mượn cái áo khoác chứ.:)) Hắn tự thấy mình sao lại chu đáo đến thế (:D.)..Đi đến chỗ nhỏ học là 9h12p. Hie ngồi trà nóng chờ nhỏ chút vậy, chờ đến 9h40p không thấy nhỏ đâu, hắn đoán nhỏ zìa rùi, bùn bùn, vào hỏi một bác thì bác ý bảo : lớp cô ..(j í quên roày) về từ 9h rồi cháu ạ.

Èo. Thế là mất cơ hội làm ng tốt trọn vẹn rùi. Thực sự hắn chẳng hiểu nổi cảm xúc sao lại điều khiển Hắn hành động thế nữa…..Uh thì cứ cho là làm một việc tốt đi…..Hok nghĩ j nữa^^. Hắn trong sáng nhé….:D. Sau ngày hôm nay, có thể trong Hắn cũng hok đọng lại j nhìu về hình ảnh của Nhỏ, về việc mà hắn đã làm. Bởi nó đơn giản như một việc hắn nên làm. Một ngày thu hơi se lạnh + một tâm trạng vui vui khi giúp đc ai đó cũng đủ làm hắn thấy phấn chấn, thấy iu đời.hehe

Có lần hắn đã đọc được:

“Trong cuộc sống, có những điều chắc chắn lại hóa vu vơ

Có những cuộc gặp gỡ bất ngờ lại trở thành định mệnh.” ….Có thể thế hok nhỉ.^^.???

25 thg 2, 2010

Email, Ba con heo

1. Email
Một người đàn ông lên đường đi nghỉ hè lúc vợ của anh ta đi công tác chưa kịp về. Họ sắp xếp kế hoạch gặp lại nhau vào ngày hôm sau. Tới nơi, anh ta vội vàng gửi e-mail về cho vợ. Do đánh sai địa chỉ, bức thư của anh ta thay vì được chuyển về cho vợ, thì nó lại đến một phụ nữ có chồng vừa qua đời ngày hôm trước. Khi người vợ góa tội nghiệp nọ mở hộp thư, bức thư vừa hiện ra bà ta thét lên một tiếng khủng khiếp, té xuống sàn nhà và chết thẳng cẳng. Nghe tiếng thét, người nhà chạy vào phòng thì chỉ thấy một bức thư trên màn hình máy tính: "Vợ yêu quý nhất của anh, anh vừa đến nơi. Mọi thứ đã được chuẩn bị sẵn để đón em vào ngày mai. Người chồng yêu quý nhất của em!"

2.Ba con heo
Ba con heo, heo A tên là "Ai" , heo B tên là "Ở Đâu" , heo C tên là "Cái Gì". Có một hôm, heo A và heo B đứng trước cửa, heo C thì ở trên gác. Một con sói phát hiện và muốn ăn thịt chúng, thế là chạy lại trước mặt heo A...

Sói : mày là ai ??
Heo A : uh !!
Sói : cái gì ??
Heo A : cái gì trên gác.
Sói : tao hỏi mày tên gì ??
Heo A : tôi là ai !!

- Sói lại quay sang hỏi heo B...

Sói : mày là ai ??
Heo B : tôi ko phải là ai, nó là ai.(chỉ sang heo A)
Sói : mày quen nó ??
Heo B : uh.
Sói : nó là ai ??
Heo B : đúng thế.
Sói : cái gì ??
Heo B : cái gì trên gác.
Sói : ở đâu ??
Heo B : ở đâu là tôi.
Sói : ai ???
Heo B : nó là ai !! (lại chỉ sang heo A)
Sói : sao tao biết đc.
Heo B : ông tìm "ai" ??
Sói : cái gì ??
Heo B : cái gì trên gác.
Sói : ở đâu ??
Heo B : là tôi.
Sói : ai ??
Heo B :tôi ko phải là ai, nó là ai.(tiếp tục chỉ sang heo A)
Sói : trời ơi !!
Heo A+B : "trời ơi" là Ba của chúng tôi.
Sói : cái gì là ba của chúng mày à ??
Heo B : ko phải.
Sói chịu hết nỗi, lớn tiếng quát: tại sao...???
Heo A+B : ông quen Ông nội chúng tôi hả ??
Sói : cái gì ??
Heo A : cái gì trên gác, tại sao là Ông nội chúng tôi.
Sói : tại sao ??
Heo A : đúng rồi.
Sói : cái gì ??
Heo A : không, cái gì ở trên gác.
Sói : ai ??
Heo A : tôi là ai.
Sói : mày là ai ??
Heo A : uh, tôi là ai.
Sói : cái gì ??
Heo A+B : nó trên gác.

...Sói cắn lưỡi tự sát

Sưu tầm

24 thg 2, 2010

Chạy NokiaSoftwareUpdaterSetup trên Windows 7

Chuẩn bị:

- 7 zip
- NokiaSoftwareUpdaterSetup.exe
Dùng 7 zip unpack NokiaSoftwareUpdaterSetup.exe ra, chọn thư mục Installer, file Configuration.icf, dòng có chữ TargetOSs=winXP,winVista . Thêm vào ',win7' chạy installer >> ngon!




Running NokiaSoftwareUpdaterSetup on Windows 7


Today I needed to upgrade the software on my Nokia N97, and was prompted by the Nokia software to download and run NokiaSoftwareUpdaterSetup_en.exe.
The only thing was, this just exited with a message saying unsupported platform or something. I quickly tested if the exe file was an archive and discovered I could unpack it with 7-Zip. Inside the resulting directory, in a folder named Installer, I found a file called Configuration.icf, and in this a line with the string


1TargetOSs=winXP,winVista


I added ‘,win7′ on a hunch and ran Installer.exe, and what do you know, it worked :)




Nguồn Running NokiaSoftwareUpdaterSetup on Windows 7 | Rantings in the dark

2 thg 2, 2010

Thước đo sự trong sáng

Các nhà nghiên cứu sau 1 thời gian đã phát hiện ra là trẻ con ko nhìn thấy hình của đôi tình nhân trong ảnh phía dưới này vì đầu óc của chúng còn trong sáng , chưa biết chuyện xxx .... 
Xin mời hãy thử
Nếu sau nhiều nhất là 5 giây bạn vẫn không nhìn ra được con cá heo nào thì có nghĩa là đầu óc của bạn đã thực sự đen tối, hết cách chữa.
Highslide JS
Hjx. Tớ thì nhìn mãi mới ra. >> Hết thuốc!

24 thg 1, 2010

Cách khắc phục lỗi font chữ ở blog yahoo plus!

Trong khảng 1 tháng trở lại đây, Plus và beta Plus bị lỗi font rất khó chịu. Khi post bài lần đầu tiên thì không bị sao, nhưng chỉ cần click vào "sửa bài" là toàn bộ font chữ của bài viết đều bị lỗi, em và rất nhiều bạn đều bị lỗi như thế:







Hiện tại chỉ có thể sửa bài bằng cách copy lại bài cũ (lúc chưa bị lỗi font) sau đó vào sửa bài, check HTML, xóa toàn bộ code HTML đi, check lại rồi paste bài cũ vào rồi sửa bài.


Bạn mình cũng gặp lỗi này, mình search mãi ko thấy chỗ nào có cả, tự viết 1 cái để cho mọi người dùng. Mình đã deploy lên địa chỉ này mọi người vào sử dụng nhé: http://tools.vnonweb.net/