I've been playing around with Android development lately and it's been a fairly "interesting" ride so far. Well, apart from the horror that programming in Java is (I'll leave that rant for a separate post).
One extremely frustrating facet of designing an app for the Android platform is the plethora of devices with varying screen sizes out there. Coming from a web background, where you pick a minimum screen resolution and get going, it's a rude shock. Android's own guide on supporting multiple screens recommends having four (!) versions of bitmap resources (pictures).
I did a quick survey on Flipkart for the screen sizes & resolutions of all Android phones under Rs 18,000, which I'm assuming would be the top sellers in India. Here's the data (the first column is the screen resolution in pixels, the second column is the diagonal length of the screen in inches, and the third column is the number of handsets available in that particular combination):
So, while designing for Android, you have the mental overhead of thinking about more than 12 screen size & resolution combinations. That's right -- more than twelve. Contrast that with iPhone, where it's just two, I think -- one for normal displays and one for retina displays. Contrast that with the web, where, till some time back, you had to basically pick between designing for a minimum of 800x600 or 1024x768.
Based on the screen classification proposed by Android, even if this number can be brought do half, that would leave us with more than 6 possible outcomes! I haven't even started looking at supporting multiple API versions (2.2, 2.3, 3.0, 4.0, etc.) and multiple device capabilities (scroll wheel, D-pad, etc. etc.) I'm afraid I'll give-up even before I reach that point!
Is there any report out there which segments: (a) the amount spent on the Android market & (b) the in-app advertising revenue, by the handset capability / screen size / etc? I'm sure app developers would be willing to pay for it, to save themselves the time spent on handsets generating a few hundred rupees, at best.
Having been through the initial phase of a startup, I've been responsible for fairly large projects on impossible timelines. With ever-changing specs and the pressure to ship, we never really got the time to write any automated tests.
It's not something that I'm proud of.
I took the first opportunity to experiment with "Test Driven Development" (TDD) when the support contract with a vendor ran out and I had to fix a bug myself. Based on this experience here's why I think every project needs test driven development:
I believe that the lack of archives in business communication is a serious enough problem to solve. Especially in these times, when a lot of brainstorming happens on email amongst team members located in different geographies.
I've tried using Basecamp for all business communication and succeeded only partially. Although Basecamp can serve as a good archive for email communication, it just doesn't beat the simplicity of adding any random email address to the CC list when you hit "Reply all". You have to first add a user to a project, then add him to the message, and then reply to the message. This, of course, will work only if the person knows how to use Basecamp. Otherwise, add the additional overhead of evangelizing Basecamp over regular email before getting him to accept this new mode of communication. [1] If something confidential is being discussed, there's also this fear of archiving your trade secrets on someone else's servers.
Probably there's a good use-case to add a new feature in SMTP servers -- an archive header and an email archiving module. If an incoming email has the archive header (X-Archive: true) the SMTP server will archive the email by storing a copy of that email and making it accessible on a web page. All replies to that email (and further replies to those emails) will automatically get archived, regardless of whether they have the archive header or not [2]. The server can also add a footer to each email in the thread to direct the user to the archive. Optionally, the archiving module may also archive email attachments and make them available on the company intranet (or the web).
Various mail clients will also need to be modified to present a user with a checkbox while composing the mail that sets/unsets the archive header.
I think this feature can be easily hacked into postfix (or sendmail) and a couple of open source email clients (like Evolution and Thunderbird).
Alternatively, this can also be achieved by having a record-keeper email ID (something like archive@somecompany.com). Any email CCed to the record-keeper will be archived and available on the company intranet (or the web). The only drawback of this is that the archival chain can break very easily if someone removes the record-keeper from the CC list. This approach can probably be an easier path towards implementation, both from the client's as well as the server's side. (Aren't such archival modules already available?)
If anyone wants to collaborate on this project with me, please drop me an email at saurabhnanda (at) gmail (dot) com. I've been wanting to work on a decent tech project for quite some time now.
[1] Given, recipients of Basecamp messages can now simply reply to messages just like normal email, it's still not perfect. All formatting (even line-breaks) are stripped. And you still have to log on to Basecamp to compose a completely new message.
[2] I think it's reasonable to assume that since the parent wanted the email thread to be archived, it must be archived in its entirety.
The latest exploit to hit the web is CSRF. It's nothing fancy, very simple to execute and understand. In a nutshell:
You're signed in to website A
You open a new tab and visit website B. Website B is a malicious website (or is a trusted website which has the potential of being malicious because of allowing user generate content-UGC).
Website B has an image tag (not necessarily, but the simplest to inject via UGC) which points to a predictable URL on website A. For example, <img src="http://www.a.com/account/delete?confirm=yes" /> which basically deletes your account on website A.
Your browser will try to fetch the "image" from website A, merrily sending your session cookie along with the request. And BOOM! On website B you don't get the image ('cuz there is none) but your account has just been deleted from website A.
This is the simplest scenario I've explained. Read the Wikipedia article CSRF to understand how it can be executed in a variety of ways and situations.
Over the past year or so I've been going ga-ga over RESTful architecture and stateless servers. I've tried making URLs predictable and discoverable. Personally, I click on the "keep me signed in" checkbox whenever on browsing the web on my laptop. This just turns my world around!
Does it mean that we now need to make sure we're not signed-in to one site while visiting another? Or that all web applications now have to be stateful and URLs have to be non-predictable? Which means that while generating a page the webserver will have to add a random token to each URL and validate that when the browser requests the URL? The horror!
Any thoughts, anyone? This sounds like impending doom!
Why can't I compose posts in Textile Markup? It's so damn simple and guarantees conversion to clean HTML. I hate using the rich text editor for composing posts. It's too complicated and I don't like the superfluous markup it generates. Plus I've also gotten addicted to Textile, thanks to the amount of time I spend on Basecamp.
... that's how non-geeks feel. I'm extremely sure of that now.
I had been spending some time planning my parents' trip to Kerala. I had every event (flight, car travel, hotel stay, etc.) added neatly to my Evolution calendar. (Given the number of meetings I now have to attend - I've been using Evolution avidly for the past month or so - but that's a different story). Finally, I sent out notifications for each event to my parents.
I called up my Mom expecting the entire travel-plan communication process to be a breeze. What's the complication, I thought. You get a bunch of meeting invites; you click "Accept" for each one and boom! you have a proper travel calendar right in front of you.
She got the mails alright, she even clicked "Accept" on each one of them. But I had one hard of a time trying to get her to the calendar.
Me: Okay, now that you've accepted them, you can see the schedule in the calendar. Mom: How do I get to the calendar? Me: Okay, do you use Outlook? [That's what most offices use.] Mom: Yes. Me: So, the left pane, sorry column, sorry left side of the screen will have a button for calendar. Click on it. Mom: It's not there. Me: Can you see your mail folders? Mom: Yes. But no calendar. Me: Okay, I'll call you back in 5 min.
Then I rushed to a guy with Microsoft Windows on his machine. Fired up Outlook and noted the exact location of the Calendar button. It was pretty visible. But then I realized, probably it's been turned off on her machine. I asked the guy with M$ installed, he showed me how to configure your left pane to show/hide various buttons. I was like, yeah right. "Mom look at the left pane, there's a teeny-weeny arrow there which will lead to a menu, which will have an option called 'configure', which will have various checkboxes...." Not happening!
I spent the next 10 mins trying to figure out how to get to the calendar in Outlook without clicking on an onscreen button or going through the configuration process. It's bloody un-intuitive. It's "Go > Calendar" if you don't already know. The shortcut for it is Ctrl+2.
Back to the phone:
Me: Okay, press Ctrl+2. Mom: [After 30 sec] I did, nothing happened. Me: Are you in Outlook? [Damn!] Mom: Yes. Me: Do you have a Menu item called "Go"? You know, right at the top where file, edit, etc. are? Can you see a "Go" there? Mom: No, there's no "Go" option! Me: Are you sure you're using Outlook? Mom: Yes. Me: Are you sure it's not Netscape? Mom: [getting irritated] yes! Me: okay, are you using Outlook on your own desktop? Or do you sign in to Outlook using the Internet Explorer? [Ah, probably she was on one of the M$ web mail box thingies] Mom: No. It's on my desktop. We have two different icons. One for Internet Explorer and the other for Outlook Express. [!!]
I wanted to pull my hair out! And as it turn out, Outlook Express, indeed does not have a calendar application.
I just gave up on the entire cool iCal stuff. Took a screenshot of my Evolution Calendar screen and mailed it to her.
That means, the threading is simulated by the Ruby VM and they are not "true OS threads".
That means, if a thread in your Ruby program makes a call that the VM can't suspend, all threads running in that VM will block. In effect, your Ruby VM will "hang" until the rogue thread returns.
Basically, the recommended way to achieve concurrency, if each concurrent thread/process is doing even moderately complex I/O tasks, is to fork a new process. (The much-touted "shared nothing" architecture)
PS: And in case you're wondering, ActiveRecord *is* thread-safe. It's just that most apps don't use it because of the preferred way of achieving concurrency in Ruby (forking processes).
I spent around 30 minutes trying to figure out why a particular Ruby file was being loaded twice, only to be struck in my face with this gotcha.
Basically, when you use require 'file' the method Ruby uses to determine whether the file has been loaded earlier is pretty stupid. It looks for the filename passed verbatim in it's internal data structure/hash/whatever. So, if you give require 'file' and require './file' the damn file will be loaded twice.
WTF?! Seriously!
Anyways, I thought this was undocumented behaviour but I found this in the RDoc entry for 'require' - should have looked there before.
Ruby tries to load the library named string, returning true if successful. If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $:. If the file has the extension ``.rb’’, it is loaded as a source file; if the extension is ``.so’’, ``.o’’, or ``.dll’’, or whatever the default shared library extension is on the current platform, Ruby loads the shared library as a Ruby extension. Otherwise, Ruby tries adding ``.rb’’, ``.so’’, and so on to the name. The name of the loaded feature is added to the array in $". A feature will not be loaded if it‘s name already appears in $". However, the file name is not converted to an absolute path, so that ``require ‘a’;require ’./a‘’’ will load a.rb twice.
Apart from the flame war that's going on the comments section there, there is one thing about the "design for yourself" philosophy that has intrigued me. What if you really aren't designing for yourself? What if the software that you are developing/designing is not for your daily use? For example an accounting+finance system that is to be used by hardcore accountants? Do you not concede to how the end user wants the software to function? Don't you lose confidence in your "gut feel" automatically?
The products that 37signals are working on are general purpose products, as such. A project management tool, todo list, CRM application can be used by any company or department. What about specialized software? Can we apply the same principles there?
Oracle, unlike MySQL, does not auto-generate values for the primary key column for you. That means, you can't "auto_increment" a column in Oracle. With each INSERT statement you have to provide the value for the primary key column yourself. Oracle has database sequences to help you generate series of numbers for this purpose.
Sometimes you end up using Oracle sequences for stuff other than as a source of values for your primary key. And sometimes you need to reset the value of the sequence back to 1 at midnight everyday. I ended up with the same problem and I couldn't find a canned solution off the Net for this. I spent a day trying to solve this and ended up learning a lot about Oracle sequences, Oracle packages and PL/SQL, the dbms_lock package, and the dbms_scheduler package.
The problem would be fairly easy to solve if resetting an Oracle sequence were a single atomic SQL statement. No, it turns out that you have to do a bit of circus involving multiple statements to reset the sequence back to 1. I figured that you basically have two options:
Drop the sequence (statement #1) and recreate the sequence (statement #2)
Change the INCREMENT BY property of the sequence to be negative of the CURRVAL (statement #1). Increment the seqeunce (statment #2). Reset the INCREMENT BY property back to 1 (statement #3).
In both the solutions, you run the risk of some other process coming along and doing a seq.nextval on the sequence while the reset is underway. Boom! A bit like getting caught with your pants down.
So, here's what I did:
Create a PL/SQL package in Oracle which acts as a proxy for the sequence. Make sure that no application module does a seq.nextval directly. All requests to get the nextval have to go through the getNextSeq() function/procedure provided by the PL/SQL pacakge.
The getNextSeq() function first acquires a lock in shared mode provided by the dbms_lock package in Oracle. Increments the sequence. Releases the lock, and returns the nextval. (Note: The dbms_lock package is a general purpose lock library. It does not mean that you acquired a lock on the sequence - that's not possible in Oracle, as some gurus told me. You just acquire a lock. Very much like a mutex lock you acquire in programming languages.)
In the same PL/SQL package, you create a function resetSeq() which acquires the same lock in exclusive mode, resets the sequence using either of the solutions given above, and releases the lock.
Now, you can create a scheduled job in the DB using the dbms_scheduler package to run the resetSeq() function at midnight everyday. In fact, you can execute that at whatever frequency/interval you want.
In the process I also realised that Oracle has the capability of doing a fair amount of metaprogramming through the EXECUTE IMMEDIATE statement. You can pass it any string and Oracle tries to parse + execute that as an Oracle statement, much like eval in Ruby or Lisp.
I spent most of my time breaking my head over why dbms_lock.request didn't seem to be working. Then I realized that dmbs_lock.allocate_unique worked on a per session basis. What that means is, if two separate connections called dmbs_lock.allocate_unique to create a lock with the same lock handle, both of them would end up getting lock objects that would behave independently of each other. In which case, effectively, both the processes were working on different locks and the whole purpose of using locks would be defeated. This is why, I'm calling allocate_unique just once, and "hard coding" the lock id in the package definition using Oracle "metaprogramming".
PS: I'm still not sure whether this is the best solution to this problem, but it's a solution that works. Please let me know if you have a better way of solving this.
Here's the script:
set serveroutput on; declare lock_handle number; begin dbms_lock.allocate_unique('my_lock', lock_handle, 31536000); dbms_output.put_line('Dropping my_seq'); execute immediate 'drop sequence my_seq';
dbms_output.put_line('Creating my_pkg declaration'); execute immediate 'CREATE OR REPLACE PACKAGE "my_PKG" AS procedure reset_my_seq; function get_my_next_seq return number; END;';
dbms_output.put_line('Creating my_pkg definition'); execute immediate 'CREATE OR REPLACE PACKAGE BODY "my_PKG" AS my_lock_handle number := ' || lock_handle || ';
procedure reset_my_seq is lock_status integer; curr_val integer; begin lock_status := dbms_lock.REQUEST(lockhandle => my_lock_handle, lockmode => dbms_lock.x_mode);
execute immediate ''alter sequence my_seq minvalue 0''; execute immediate ''select my_seq.nextval from dual'' into curr_val ; execute immediate ''alter sequence my_seq increment by -'' || curr_val ; execute immediate ''select my_seq.nextval from dual'' into curr_val ; execute immediate ''alter sequence my_seq increment by 1'';
Cleartrip is supporting FOSSKriti – a 4 day mini-conference about Free/Open Source Software. It'll have technical talks, hands-on workshops, hackfests, and general geek chatter.
In an RoR workshop I'll be creating the OARS (Online Academic Registration System) website in 90 minutes – or something that can at least be called the OARS website. My friend Chaitanya will be giving a talk on Common Lisp.
If you're somewhere around, be there – it'll be fun.
We've just launched a new product – Cleartrip Trains Search It's simple. It's fast. It's comprehensive. And it rocks! Give it a spin and let us know at Cleartrip Forums
A lot of hard work put in by Piyush, Anurag, of course our rocking UI team (Hrush, Varun, Rakesh, et al).
Talking (in part) on how the two cultures, Unix and Microsoft, differ fundamentally, Joel Spolsky nails it in his Talk at Yale:
Anyway, the two cultures roughly correspond to highbrow vs. lowbrow, and in fact, it’s reflected accurately in the curriculum of computer science departments throughout the country. At Ivy League institutions, everything is Unix, functional programming, and theoretical stuff about state machines. As you move down the chain to less and less selective schools Java starts to appear. Move even lower and you literally start to see classes in topics like Microsoft Visual Studio 2005 101, three credits. By the time you get to the 2 year institutions, you see the same kind of SQL-Server-in-21-days “certification” courses you see advertised on the weekends on cable TV. Isn’t it time to start your career in (different voice) Java Enterprise Beans!
In my experience the perfect mix is a "highbrow" computer education (to get the basics right) with a pinch of exposure to the "lowbrow", which will give the person the ability to get stuff done. Not just sit there and come up with beautiful architectures, theoretical proofs, and DSLs which have no frikking use whatsoever.
I've previously written about my experience with an extremely "lowbrow" college when I went recruiting for Cleartrip.
On a separate note, we're always on the lookout for developers who're passionate and thoughtful about the work they do. We are a travel company, but technology is a core component. We can't bear to see sloppy code at any level (and that also includes the HTML). If you think you'd be interested in working with us, drop me a line.
I tried searching on Google but couldn't find all the information in one place as a simple TODO. So here's my contribution back to the Linux user's out there:
I've been successful in configuring Reliance ZTE MG880 modem/data card over the USB bus. I'm not sure whether this model is available as a PCMCIA card, but I don't know whether it'll work for it.
Plug in the smart looking black little thingie in a USB slot. dmesg should give weird message like this:
[37246.516000] usb 2-1: new full speed USB device using uhci_hcd and address 15 [37246.640000] usb 2-1: device descriptor read/64, error -71 [37246.864000] usb 2-1: device descriptor read/64, error -71 [37247.080000] usb 2-1: new full speed USB device using uhci_hcd and address 16 [37247.200000] usb 2-1: device descriptor read/64, error -71 [37247.424000] usb 2-1: device descriptor read/64, error -71 [37247.640000] usb 2-1: new full speed USB device using uhci_hcd and address 17 [37248.048000] usb 2-1: device not accepting address 17, error -71 [37248.536000] usb 2-1: new full speed USB device using uhci_hcd and address 19 [37248.760000] usb 2-1: configuration #1 chosen from 1 choice
Don't worry. Just execute the following command and look for ZTE in the output:
A dmesg should give you similar looking output at the end:
[38360.764000] usbcore: registered new interface driver usbserial [38360.764000] drivers/usb/serial/usb-serial.c: USB Serial support registered for generic [38360.940000] usbserial_generic 2-1:1.0: generic converter detected [38360.940000] usb 2-1: generic converter now attached to ttyUSB0 [38360.940000] usbserial_generic 2-1:1.1: generic converter detected [38360.940000] usb 2-1: generic converter now attached to ttyUSB1 [38360.940000] usbserial_generic 2-1:1.2: generic converter detected [38360.940000] usb 2-1: generic converter now attached to ttyUSB2 [38360.940000] usbcore: registered new interface driver usbserial_generic [38360.940000] drivers/usb/serial/usb-serial.c: USB Serial Driver core
Now run a wvdialconf:
$ sudo wvdialconf Editing `/etc/wvdial.conf'.
Scanning your serial ports for a modem.
Modem Port Scan<*1>: S0 S1 S2 S3 WvModem<*1>: Cannot get information for serial port. ttyUSB0<*1>: ATQ0 V1 E1 -- OK ttyUSB0<*1>: ATQ0 V1 E1 Z -- OK ttyUSB0<*1>: ATQ0 V1 E1 S0=0 -- OK ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 -- OK ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 -- OK ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 -- OK ttyUSB0<*1>: Modem Identifier: ATI -- ZTEiT, Incorporated ttyUSB0<*1>: Speed 4800: AT -- OK ttyUSB0<*1>: Speed 9600: AT -- OK ttyUSB0<*1>: Speed 19200: AT -- OK ttyUSB0<*1>: Speed 38400: AT -- OK ttyUSB0<*1>: Speed 57600: AT -- OK ttyUSB0<*1>: Speed 115200: AT -- OK ttyUSB0<*1>: Speed 230400: AT -- OK ttyUSB0<*1>: Speed 460800: AT -- OK ttyUSB0<*1>: Max speed is 460800; that should be safe. ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 -- OK WvModem<*1>: Cannot get information for serial port. ttyUSB1<*1>: ATQ0 V1 E1 -- failed with 2400 baud, next try: 9600 baud ttyUSB1<*1>: ATQ0 V1 E1 -- failed with 9600 baud, next try: 115200 baud ttyUSB1<*1>: ATQ0 V1 E1 -- and failed too at 115200, giving up. WvModem<*1>: Cannot get information for serial port. ttyUSB2<*1>: ATQ0 V1 E1 -- failed with 2400 baud, next try: 9600 baud ttyUSB2<*1>: ATQ0 V1 E1 -- failed with 9600 baud, next try: 115200 baud ttyUSB2<*1>: ATQ0 V1 E1 -- and failed too at 115200, giving up.
Found a modem on /dev/ttyUSB0. Modem configuration written to /etc/wvdial.conf. ttyUSB0: Speed 460800; init "ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0"
Finally edit /etc/wvdial.conf to make sure it looks like the following. I've added emphasis to the stuff which I had to edit. I'm not sure the "Stupid Mode = 1" line is need or not. It was required for the older Reliance data cards so I just put it in there:
Just in case this did not work for you and you had to tweak the process, please post it in the comments section and I'll update the post accordingly.
Update: I noticed that if I do the modprobe with the modem inserted in the USB slot, the /dev/ttyUSB* devices are not created. So, first modprobe, and then insert the modem.
At least two Ubuntu packages. I present to you cycle and mencal for tracking menstrual cycles. Immense entertainment ensues to think about the functional testing.
Man from testing team: Honey, did you have your period today? Test subject: Get lost you insensitive clod! Man from testing team:(Filling out bug report form) Prediction early by few days. Kindly fix ASAP.
Cycle
calendar program for women Cycle is a calendar for women. Given a cycle length or statistics for several periods, it can calculate the days until menstruation, the days of "safe" sex, the fertile period, and the days to ovulations, and define the d.o.b. of a child. It allows the user to write notes and helps to supervise the administration of hormonal contraceptive tablets.
Possibilities of the program: - Calculate days of menstruation, based on the length of the cycle or on statistics of previous periods. - Calculate days of "safe" sex, fertile period and day to ovulations. - Definition of D.O.B. (Date Of Birth) of a child - Allows to write notes. - Helps to supervise reception of hormonal contraceptive tablets. - Multiple users allowed. Data is protected by a password for every user.
NOTE: This program is not a reliable contraceptive method. It does neither help to prevent sexual transmision diseases like AIDS. It is just an electronic means of keeping track of some of your medical data and extract some statistical conclusions from them. You cannot consider this program as a substitute for your gynecologist in any way.
Homepage: http://cycle.sourceforge.net/
Mencal
A menstruation calendar Mencal is a menstruation calendar written in Perl.
It is a simple variation of the well-known Unix command cal. The main difference is that you can have some periodically repeating days highlighted in color. This can be used to track menstruation (or other) cycles conveniently.
Author: C. McCohy Homepage: http://mencal.kyberdigi.cz/english.html
I've read so many arguments and debates on why we don't have women in technology, especially software. And I never really figure out the real reason for it. But now I can say, at least we're trying!
I used to be a fanatic anti-Microsoft (or anti-M$ to some) spokesperson. There was a time in college when I used to hate everything Microsoft. Soon after I tasted Linux for the first time during (yes during) my 12th standard boards -- and managed to get X working on my SiS VGA card -- I uninstalled Windows from my machine. And have taken pride in the fact that since then Windows ke liye mere computer ke darwaaze hamesha hamesha ki liye band ho gaye hain!
But later, during my job, I realised that there are places that still require Windows. Some places where Windows actually does a better job that Linux (operatibility with LCD projectors, one; presentation software, two). Therefore I found myself shifting to Microsoft Powerpoint on a Windows machine for making a client presentation whenever I needed to.
However, I still held the strong opinion that Windows users are on average "dumber" than Linux users. And I don't mean dumber in the IQ kind of sense. I mean "dumber" because they don't know what's happening under the hood. It's just like you and I, or the average person off the street, would be dumber about cars than an average car mechanic.
And my opinion was reinforced last week. Microsoft is bad for computer education.
I had recently gone to a college to recruit freshers for the tech team at Cleartrip. (It wasn't any of the IITs or RECs.) We were interviewing final year BE students (IT/CS/EE streams). A few were with a work ex. of one year or so.
I was stunned, and I mean absolutely STUNNED, when people who claimed to have worked on their college website did not know what a URL meant when I asked them for it! When people who had claimed to work on e-shopping carts could not tell me exactly how sessions were maintained.
And these are not your typical B.Com. + GNIIT kind of students. These are people who would, in a matter of months, be passing out with a computer engineering degree. They would become part of the so called "talent pool" of India.
Out of the 15 people I interviewed (there were about 45 divided amongst three interview panels), not a single person was able to write a program that generated the Fibonacci series!
No one was able to tell me what IDE they use to write C/C++ programs. After a series of indirect questiononing (what are the steps you do before you start writing your program, etc) only some were able to tell me that they used something called "tc" (Turbo C). No one had heard of "bc" (Borland C). I didn't bother asking about BloodShed.
Apparently, their college lab had only Windows installed. For four years they had been fed on a staple diet of .Net, ASP, C#, VB, VB.net, and what M$ technology have you. Where you simply right clicked on an HTML form control and set its property to hidden instead of learning that was happening under the hood. Where you didn't care what cookies or URL rewriting was – the session object just worked.
No one had seen a Linux command prompt ever, despite of having done a theoretical course on Unix.
Average Joe users can get by without knowing the innards of a computer.
Computer engineers can't.
Had the students been exposed to the Linux command prompt, they would've been introduced to an IDE, after they would've gone through the pain of writing a C program in a powerful text editor (like emacs), and then compiling and linking it by hand.
Had they been writing CGI scripts in Perl or web programming in PHP, they would've known how HTML forms work; the difference between GETs and PUTs. Some of them might've been exposed to more than one broweser, and the bad world of browser inconsistencies out there, and how to get around them (and over a period of time, most websites would work!)
Microsoft has kicked in a vicious circle of dumbing down the users. I'm sure the students were so clueless partly because their teachers were. And guess what OS the teachers had used in their college days?
You can raise dumb users on Linux. But it would be goddamn hard to do it.
Linux induces a sense of play. A sense of adventure. It encourages you to look under the hood. Millions of lines of open source code are an invitation to the inquisitive minds of college students to come, play!
And I'm not saying that you can't raise smart computer engineers Windows. But it would be goddamn hard to do it.
The evidence proves it.
(PS: We're still looking for freshers, or people with under one year experience to join our tech team. Drop me your resume nanda at cleartrip dot com in case you're interested, or know someone who is. )