Yearly Archives: 2011

A message from Wikipedia

Source: Wikipedia

From Wikipedia author Aniruddha Kumar

I can speak Hindi, Urdu, English, Sanskrit and Moroccan. But I can’t read what’s on my computer screen.

Being blind online means I have to listen to all the text — including ads. That’s one of the reasons I rely on Wikipedia so much. It doesn’t waste my time by making me sit through advertising like almost every other website.

Wikipedia is one of the most beautiful things in the world. It takes the concept that everyone has a basic right to information and makes it into something real — a tool that’s free for anyone to access, even blind people like me, and completely neutral.

When I first found out about Wikipedia — that I could be part of this amazing collective project — I knew I wanted to contribute. And I’m asking you to join me.

Will you support Wikipedia with a gift of $5, €10, ¥1000 or whatever you can afford?

Wikipedia gets almost as many visitors as huge sites like Google and Facebook, but it operates on a tiny fraction of their resources. And it depends entirely on donations from readers like you.

Instead of ads, Wikipedia has a community of millions of volunteer editors double-checking every word and citation. I’m so grateful for them – their work makes learning online possible.

The philosophy of Wikipedia is to make a sea from drops. And it applies to everyone who contributes, whether a few edits or a few dollars.

Thank you,

Aniruddha Kumar
Wikipedia Author

The message says it all. Most of the time, web pages are filled with advertisement. It only make us annoying, but with Aniruddha, it cause a lot of problems.

And I also hope for a free Wikipedia.

A quick experiment on HTML5 Canvas

Photobucket

/** Vietnamese: một thử nghiệm nhỏ lên trang canvas của HTML5 **/

HTML5 is out for a while, and many people have already play with it. Inspired by the great article here, I managed to make a simple dirty experiment.


<!DOCTYPE html>

<html lang="en">

  <head>

    <title>Good night</title>

  </head>

  <body><script type="text/javascript">
  if ( !window.requestAnimationFrame ) {

    window.requestAnimationFrame = ( function() {

      return window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {

        window.setTimeout( callback, 800 / 60 );

      };

    } )();

  }
</script><script type="text/javascript">
var canvas, context;
var xx = new Array();
var yy = new Array();
for (var i = 0; 40 > i; i++) {
   xx[i] = Math.random()*600;
   yy[i] = Math.random()*150;
}

init();
animate();
function init() {
  canvas = document.createElement( 'canvas' );
  canvas.width = 600;
  canvas.height = 400;
  context = canvas.getContext( '2d' );
  document.body.appendChild( canvas );
}
  
function animate() {
  requestAnimationFrame( animate );
  draw();
}
function draw() {
  var time = new Date().getTime() * 0.001;
  var x = Math.cos( time ) * 250 + 300;
  var y = Math.sin( time ) * 250 + 300;
  
  if(150 >= y) {context.fillStyle = 'rgb(250,250,250)';}
  else {
    if (200 >= y) {
      context.fillStyle='rgb(200,200,200)';
    } else {
      context.fillStyle='rgb(14, 14, 14)';
    }
  }
  
  context.fillRect( 0, 0, 600, 400 );
    
  context.fillStyle = 'rgb(255,255,0)';

  context.beginPath();
  
  context.arc( x, y, 15, 0, Math.PI * 2, false );
  context.closePath();
  context.fill();
  
  context.fillStyle = 'rgb(0,0,255)';
  context.fillRect(0, 215, 600, 400);
  
   for (var i = 0; 15 > i; i++) {
      
      context.fillStyle = 'rgb(255,255,255)';
      context.beginPath();
      context.arc(xx[i], yy[i], 1, 0, Math.PI * 2, false );
      context.closePath();
      context.fill();
  
      if (y > 200) {
          if (Math.floor(time) % 2 == 0) {
            context.fillStyle = 'rgb(255,255,255)';
            context.beginPath();
            context.arc(xx[i], yy[i] + 215, 1, 0, Math.PI * 2, false );
            context.closePath();
            context.fill();
          } else {
            context.fillStyle = 'rgb(255,255,255)';
            context.beginPath();
            context.arc((yy[i] / 150) * 600, (xx[i] / 600)*150 + 215, 1, 0, Math.PI * 2, false );
            context.closePath();
            context.fill();
          }
        }
      } 
    }
    </script>
  </body>
</html>

You can view the example online here.

Free ads: thanks for the start-up Handcraft for letting me quickly “craft” this product.

Quick note on Java time

The analog timer, From openclipart.org
One of the things I dislike most in Java is… unfriendly. DateTime manipulation is a typical example. I think at least one time, a Java developer will encounter this message: getYear() is deprecated.

Such a simple and often-heavily-used function is deprecated. So programmers must walk around by the Calendar class.

Calendar localCalendar = Calendar.getInstance();
Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Date date = new Date();
localCalendar.setTime(date);
utcCalendar.setTime(date);

TimeZone localTimeZone = localCalendar.getTimeZone();

System.out.println("Year: " + localCalendar.get(Calendar.YEAR));
System.out.println("Month: " + localCalendar.get(Calendar.MONTH) + 1);
System.out.println("Day: " + localCalendar.get(Calendar.DATE));
System.out.println("Day of week: " + localCalendar.get(Calendar.DAY_OF_WEEK));
System.out.println("Hour: " + localCalendar.get(Calendar.HOUR_OF_DAY));
System.out.println("Minute: " + localCalendar.get(Calendar.MINUTE));

System.out.println("Timezone: " + localTimeZone.getDisplayName());
System.out.println("UTC Hour: " + utcCalendar.get(Calendar.HOUR));
System.out.println("UTC Minute: " + utcCalendar.get(Calendar.MINUTE));

Although Java big heads all have valid reasons for this inconvenience – which is the complexity of time manipulation, I still think this way is over-killing. Yes, no computer is accurate enough to calculate the correct solar time. But we are no astronomy expert, who cares if the time lacks one or two leap seconds*? Daylight saving stuffs is still necessary, but shouldn’t be too much of a problem.

In the end, I think Java powerful libraries should also make it easy to do simple tasks, instead thinking ahead too much for easy enlargement later**. With the Internet as popular as today, I think we can safely calculate “simple” time only, leaving the task to do additional astronomy calculation for the big servers, and cover the gaps by synchronizing.


(*) Like leap year, a leap second is sometimes added to our current timeline to cover the gaps between solar year & normal year. Because a leap second is too small,  people seldom notice. Reference: http://tycho.usno.navy.mil/leapsec.html

(**) Java has the reputation for easy scaling, and this is very true in my experience. On the opposite, small application is suddenly heavy at their very first cradle time, because a fair amount of efforts are put in “making room” for future changes.

Lorem Lipsum

Lorem Lipsum

Source: http://www.lipsum.com/

“Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.”

Do you find the above passage familiar? If yes, can you guess what language it’s written by?

“Lorem lipsum” is simply a dummy passage which often appears on mocking website. Since the first appearance at 1500s, it soon become the standard text for printing and typesetting industry. Surprisingly, such an old standard still survive till today.

There are 3 reasons to use “Lorem lipsum”. First, it looks more like natural English than “Content here Content here …” text. Reading it give the customers a more accurate image of how the text look like when the site is complete. Second, the content on mocking website shouldn’t be uP/nderstandable, because many studies have point out that people are inclined to be distracted by readable text. And finally, since it has become a standard, it’s a shared background for any content layouters.

And… in case you don’t know, the content of “Lorem lipsum” actually has a meaning. It’s a Latin text taken from ”de Finibus Bonorum et Malorum” (The Extremes of Good and Evil) by Cicero, written in 45 BC – a popular book during the Renaissance.

I have been developeing website for more than a year, and such simple things always make people surprised…

P/s Thanks bro Lai Huu Nhon – a senior from my company (Evolus) – for this piece of knowledge. And by the way, I think his layout is cool.

Text

Force refreshing second level cache in Hibernate

/** Vietnamese: cách xóa second level cache bằng code trong Hibernate**/

Hibernate second level cache is helpful, but only if using wisely.

In the ordinary context, if you delete an object in database by Hibernate, Hibernate will know and update its cache. But if the object/ tube got deleted by other programs (or by cascade delete set up in database itself), Hibernate won’t know and won’t update anything. Hence the deleted objects may remain in the cache for quite a time, and your code may throw an exception or two when trying to get items related to that object.

It’s a good practice to do every database-related thing through Hibernate. But in reality, sometimes we must do the other way around:

@SuppressWarnings("unchecked")
private void evict2ndLevelCache() {

  try {
    log.info("Evicting all Entity Regions of 2nd Level Cache");
    sessionFactory.getCache().evictEntityRegions();
    Map classesMetadata = sessionFactory.getAllClassMetadata();
    for (String entityName : classesMetadata.keySet()) {
      log.info("Entity from 2nd level cache:" + entityName);
    }
  } catch (Exception e) {
  log.error("Error evicting 2nd level hibernate cache entities: ", e);
  }

}

The solution provided here is an alternate of the solution in this question. Thanks brother Tinh for this information.

Running JMeter from command line

I trust that someday, you will understand me.

Though out there are plenty documents to run JMeter with Ant task, sometimes it’s not the best solution. For example, if the plan is to run several test scripts on several cloud server instances, it may not worth the effort to install Ant on each of those instances.

In that case, we can run JMeter script from command line, using one statement in the followings:

[jmeterBinDirectoryPath]/jmeter -n -t <testfile> 

or

[jmeterBinDirectoryPath]/java -jar ApacheJMeter.jar -n -t <testfile>

Credit goes to this blog post and this discussion in mailing list.

Google isn’t a history book anymore

Google

It’s not as cool and hot as the barrel roll trick, but the other news from Google today really catch my eyes.

The story is here.

In short, Google made changes to its algorithm to alter search result behaviors. In stead of results with more than several months old, now you get newer results (maybe only minutes after it was online).

It mean that Google changed the way they do searching. They do change. They are not satisfied with what they achieved, but they seek to improve on. And this improvement is one of the things that Google could do better.

(From my own experience, in past it took several weeks to a new blog post from WordPress make it way to Google search results.)

Cheers for it!

JMeter – Simulate multi-users scenario with counter

/** Vietnamese: bài viết trình bày về cách dùng JMeter Counter để  giả lập nhiều user truy xuất hệ thống cùng lúc **/

In load testing field, JMeter is a powerful tool, and powerful tool often means high learning curve. The fact that JMeter document is not so well-written caused programmers lots of troubles getting around with it. If you know how things to be done, it’s very simple. If not, you are going to spend several hours searching for the solution.

The situation: I need to simulate 1000 users to login in my system, using different username (ofcourse). After logging in, each user must input their activation code, gotten from the database. Then they go for the site functions as usual.

The interesting thing is that the activation code are random strings: I have no control how it be. But I must do mapping accurately from user to activation code. To do that, I write bootstrap code to generate  1000 users (user1 -> user1000) and their activation code. Next, export them to a CSV file to be read by JMeter.

  • user1,12345
  • user2,52341
  • user3,12534

But how to get those information to  JMeter? Using bean shell script, I managed to put these values in custom variables CurrentUser and CurrentUserActivationCode. But I must only put one pair of different value for each thread. Since JMeter have no global variable, I can’t tell it to increase each time a new thread start!

I searched for global variables for a while and try some suggestion (properties and the likes) without success. And then I remember that I only need a counter, because it simply doesn’t matter if the users log in in a order or not.

Solution: It’s JMeter Counter Config Element(actually I have no idea why a counter is a Config Element).