06 September, 2013

Back....

Hello World,

Its been a while. I was busy working with Polycom as a Software Developer Intern in a product called Millennium - 360 degree panoramic 1080p video solution which would hit the market shortly. Hopefully everything goes well.

Alrighty... So what I got now..I came across one thing recently which I thought I would share.

So everyone would have used wikipedia atleast once. So how do you print a wiki article?

Open the wiki page  -> Chose Print option from web browser ? Is that what you think...
Won't the pages look disordered with images scattered and contents not justified properly......
What if you want to combine many wiki articles and take printout?
 Do you download all html pages and print each page? Isn't this annoying?

So wiki has come up with this ( I'm not sure when it was ) concept called "Book Creater".
If you had already known about this, there is nothing new I'm gonna tell.
For those who doesn't know about it, go on.

Goto wikipedia.org main page (http://en.wikipedia.org/wiki/Main_Page)
Under Print/Export in left pane, chose create a book -> Start book creater.
Now you can visit any wiki pages you want and add to your book. At the end, this can be downloaded as a pdf which can be later printed or you can read it using your gadgets. Cool isn't it :)

This is such a nice feature which I didn't know earlier :)
Anyways, hope you can make use of this cool stuff.
Take care guys.  Will come up with articles as and when I learn new things or something strikes my mind.

17 April, 2013

Self Modifying Code

Sorry guys. It's been a while. I'm near the end of Spring Semester with hectic things ahead.
In the mean time, I thought I would post something for us to chew.

Okay this post is about Self Modifying Code which I came across recently in my course work
where there was a line "The issues with Binary Translation (VMM) is Self Modifying Code".

 Lets not look into VMM aspects, rather I shall restrict myself to the later.

What is Self Modifying Code?

Program that purposely alters its own instructions while executing.
Something like a chameleon :-)

If we write a code that improperly manipulates a buffer then its a self modifying code :-) leading to crash.

Questions arise as to why we need this kind of code for which I would suggest to read the wikipedia article for its usages.

Of-course one can use this to create viruses ! making life difficult for anti-virus programs / honeypots.

It is not the code that gets changed [ Of course it needs to :-) ] but the executable that needs to change while its running. This restricts us to OS specific.

Say suppose we have a program emitting some output. Now lets open the executable using
hex editor, modify the executable to emit a different one.

If we see windows updates, its evident that program which is in execution is closed, re-written and started again. Can't this be done while the program is in execution?

Consider a huge deployment where there is a small bug with respect to your component.
The fix is just adding a check or changing some macro.

Instead of rebuilding the entire component,  is it possible to write a small piece of code ( a function ) which could tweak into image of running file and fixes the bug by altering it.
This would be of great help. isn't it ? :-)

So how do we do it?  I'm also trying it.
In the mean time, you guys too can try.

Lets state our objective

a) We know the operating system where our "*.so || *.exe || *.sl" is running.
b) Our objective is to tweak this executable for a minor fix that was found in site deployment.
    [Note : we are not supposed to restart the process]

Have fun while trying :)

30 March, 2013

What is it like for an Indian student to pursue MS/PhD from a US university?

    Courtesy : Quora

    Before I answer this question, I would like you to know that I am not from one of the premier Institutes in India . What I say henceforth is largely from a view point of an average Indian pursuing his/her graduate studies in the United States. I will warn you that this is going to be a subjective analysis and more like I am venting out my frustration against fellow Indian students. I know I am likely to draw a lot of flak for this and may fetch comments like I should check out some of the top schools, but yeah well, I am in one of the top CS programs and things are no different from a 2nd tier school. You can only imagine the shock I felt.

    The American way of life.
    Folks here are largely individualistic. And I applaud them for being so. I might have seen only a niche group of Americans here, but I can safely conclude that they are polite, humble and most important of all, have this extreme passion for a godforsaken field that we, status loving, name dropping folks, are largely alien to. I know of a American teammate who is crazy about collecting motocross statistics and he is pretty serious about it . The passion is so infectious, it makes me go weak on my knees, to the point of being mistaken as someone experiencing a hot flush. No kidding. There is just no match to the passion these guys have.

    Point to be noted: They are one of the few groups that go on a vacation during Spring Break, mostly because they are disciplined with their work and manage their time well.
    .
    Occasionally, I do run into some whack-jobs who are anti-abortion or anti-gay, but that's a minuscule number and doesn't represent the whole. Americans in general are a private lot, love sports and take a great deal of pride in who they are and what they do.They could be running your local grocery store and they are mighty proud about it. Unlike us who look down upon anyone not a Computer Science Engineer or a Doctor, they are less pretentious and more open to failures. A Stanford graduate never talks about his pedigree because he knows what it is to be subtle and he knows that it is the idea that matters more than where the person is from. I appreciate this quality a lot and I only, only wish we, as a nation, embraced it.

    We all grew up in a place where there is so much noise about all things personal : grades, salary, property details to the precision of the last decimal point. That way, it is a breather here because almost all conversations with the non-Indian graduate students revolve mostly around their various hobbies, their interests, ideas and some dry humor. No one asks you whether you secured an internship or a job . They will never ask you your grades and will never question you if you are seen talking to someone from the opposite sex. Privacy, civility and respect is almost embedded into their culture as is lack of personal space and lack of sense of individuality in ours. I seldom hear them say "Oh well, when I was at Stanford, I got job offers from X , Y and Z!

    The Indian way of American life:

    The culture shock I experienced was from the Indian Community : There will be a certain 'Indian Student Association' in your graduate school. My two cents on this one. Run like Usain Bolt from them. Run as fast as you can. Their sole reason for existence is to display their 'accomplishments' in the pretext of on-boarding freaked out freshers like us. I could hear imaginary trumpets blaring when I got introduced to a couple of them. This is where your brainwashing begins and your starry eyed dream of an international experience begins to fade with the song-dance gala welcome party and samosas. And god forbid you are from the meek (elegant, I would say) southern part of India, you will probably receive 'light-hearted' racist comments about your 'Madrasi' idlis and sambhars. These are the same folks who extend their sincere support when one Mr.Khan gets questioned by the TSA and cry foul about how racism is rampant in the western world. These guys cannot differentiate Chennai from Bangalore from Hyderabad and even Orissa. Goodness gracious. I don't even want to comment on poor East-Indians. Double standards, not new right?

    Soon after, you will mail your Indian senior graduates asking them for suggestions on courses to choose, professors to work with, projects to work on, all with the primary intent of landing a plum job with a very well known firm. Things are often exaggerated (like the Indian weddings), you are scared the hell out if you dare go beyond the norm and pick courses that your senior friend brands as 'very difficult' by his standards. He will scare you SO much, that it reverberates all through your semester, your confidence taking a beating with every tiny mistake you make. And worse, you repeat the same cycle, plant this seed into another incoming student's head and there, you have an entire line of Indians not signing up for a course because, oh well, seniors did not take it. Indians here are risk averse, not because they are not capable of taking risks (a foreign graduate study is risk in itself) but because they are surrounded by a peer group that psychologically prevents them from taking risk. I hardly see them trying out something as unpredictable as a start-up or going for that arduous PhD that they dream of.
    Herd mentality has its victims. Not new to us, is it?

    You were perfectly capable of doing well in that subject till you decided to get that bloated advice from your senior friend. Trust yourself to make the right call here and pick courses that you are passionate about, not because your senior friend tells you that it is 'easy' or 'difficult' or worse, that not signing up for that course will not fetch you a job (This, by far, is the lamest advice I have heard from an Indian senior. Made me cringe)

    The other side of this affair, the dangerous one, here goes: There are a certain 'easy' courses in your curriculum. By easy, it means easy grades or a lenient professor. Well, before you know it's easy (takes a month to realize that) your Indian friends and their senior bum-chums would have ragged you on your incompetency for not signing up for an intellectually challenging course like they did. Here I am paying nearly all my life savings in tuition for a subject that everybody makes fun of. How does that feel? It feels bloody miserable that such black and white judgement process exist in a world class university and your peers do not let you enjoy what you are studying. Easy or difficult, it's the learning I enjoy more so than anything. Of course, you could always show the finger and move on, but it does become a little difficult when the peer group views you as an intellectual misfit. They are all out to prove their choices, decisions are far superior to yours. Sounds familiar?

    The great Indian hype : If you happen to have worked for the biggies back home, you are a superstar here. Your friends hype your work, when you yourself don't care a penny about it, suddenly everyone thinks you are a smart kid, and nasty comments like 'Well, you are the smart one, you will obviously crack this, it's a joke for you' will be spewed. And if you fail to crack it, the same group immediately writes you off, leaving you wondering if you signed up for this after all. I did not create the hype, I did not publicize my work, but here I am being made fun for failing something I did not even claim I could solve!

    Minor annoyance, the Facebook feed of your party-kid Indian friend : There is also this certain Indian group who are one of those misinformed college kids clicking endless pictures and doing endless check-ins at every happening and non-happening place in the city. They are another reason for you to cringe. Having never seen the US or been here once or twice on a family trip , they are this uber excited , hyper active social beings who make us all look like party kids, desperate for attention. There is a flood of photos of your wannabe Indian friend with an American/Ukranian/German/French guy/girl (Who cares! they are all a bunch of good looking white folks anyway!) every 10 minutes on your news feed. Believe me, it makes you immensely popular among your Indian friends, you become the talk of the town (your Indian group). It is pretty much like living in India.

    You, if you are one of those pitiable Indian student with a hefty loan and with the sole purpose of learning, with dreams and ambitions beyond a job, inclined to know more about the American way of life, the history, the politics, the culture, the people, will be left wondering if you accidentally landed in India. Worse, they will look at you with contempt if you make the slightest indication that you are not inclined to their way of life, you are different, and you want to be a part of a broader culture that emphasizes on individualism than the collective thinking we have been brought up to accept. If you follow the election primaries/ presidential elections, my suggestion is to keep it a secret and pretend you enjoy Bollywood songs when you are with your group. Helps to bond and make them feel home.

    Your friends are nosy. They want to know who you hang out with, your grades, who you stay with, if things are okay with your roommates, the white 'chick' you find hot, whether you managed to get an internship, if not, some unsolicited advice on how I should be prepared for an unpaid internship, your salary and your plans of securing a job after Master's and more unsolicited advice. The rat race repeats all over again, the very same reason why you left India.

    Academics
    Life is not as easy-peasy as those Facebook photos depict. It is a lot of work, actually. More like a correction facility for all the tardiness back in our undergraduate classes. You will be forced to wake up early, forced to sleep late, forced to think for every assignment, forced to feel miserable about your performance in term exams and forced to shut up about your grades. You will be forced to become more disciplined in life. This is why I wrote in the beginning that I am not from one of the premier Indian institutes, because those guys are probably used to such load. If you are an average student like me, you will wonder where you are going wrong, in spite of being one of the top students in your class back home. It was rote learning back there, it is not that way here. Not a day passed in the first couple of months where I did not wish that I had studied in the US since the very beginning.

    But, of course, there is an easy way out of this, something you must know by now, given how things work in India. You can always get your answers on the internet or by discussing them with your Indian friends beyond the permitted levels and break all the academic honesty rules. Rules are meant to be broken isn't it? That's how things are back home! And with the self-righteous attitude we have, we collectively look down on anyone caught for academic dishonesty, but pretty much do it ourselves. 'Hey let's work on this assignment' is the norm, even if it clearly states that collaboration is not allowed. Any guesses why the Indians score well and way above average? Here it is.

    I know I did drift from the main topic. Now back to your actual answer.You will do great if you are sincere with your work, if you have a desire to learn, if you are curious and if you don't let the above affect you much. As another post here highlights, professors are approachable (Indian professors alike), resources are aplenty and school will keep you busy enough to forget a lot of peer pressure I mentioned above.You can select courses from technical/non-technical departments alike, while you are majoring in say Computer Vision. It need not be always coherent, because a lot of us are here to explore.You are not expected to become a subject matter expert and specialize in something. It is recommended, not mandatory. I know of a professor who majored in Music in his undergraduate studies and went on to get his PhD in Computer Science. That is the flexibility this system offers. Awesome isn't it?

    If you are in one of the research schools, I recommend you to get a hang of the kind of research that goes on and think about how you could contribute your tiny little idea to the academia, no matter how nebulous it is. That said, there is nothing wrong in looking for a job (I too want to make my living) but do not let it become a priority, because you are here for graduate studies and jobs/internships are more or less a by-product of what you do here. Education is something very close to my heart and it does bother me personally when the whole purpose is diluted with unnecessary add-ons like what I mentioned above.


23 March, 2013

Nitty-Gritty Things - 1

In this blog lets talk about some nitty-gritty implementation stuffs.

Okay. So assuming the reader knows C/C++

a) How to add time restrictions to user input?

To elaborate, we know in C, the user input is read using scanf/getc/getchar and in C++ using cin object.

So our objective is to add some time limit so that user inputs the value before the timeout.

a) You can do by calling a script written in bash/python etc from C code and evaluate.
b) May be create a thread and fire the thread when timeout happens.

Is there any other way? <Think before scrolling down>
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

http://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html
http://pubs.opengroup.org/onlinepubs/009695399/functions/alarm.html

After reading the above links, I came up with this.

#include<stdio.h>
#include<unistd.h>

#define TIMEOUT 5
int main()
{
        int t_iTemp;
        while( alarm(TIMEOUT), ( t_iTemp = getchar() ) != EOF )
        {
                putchar(t_iTemp);
        }
        return 0;

}

This program waits for 5 secs. If user doesn't input anything, it exits else just echoes the input
and waits for next 5 secs.

The idea is simple i.e to generate a signal based on timer.
But the important takeaway is about alarm function.


Okay lets see one more.

b) Say you are developing a clock app. Now you will have conditions for hours,seconds,mins etc

The thing we will talk is how do you display 00 when the clock moves from 59 in case of mins/secs and 23 in case of hour.

When we think about it, its nothing but printing "00". But remember here we are talking about numbers :-)

What happens when you assign 00 to a integer and print it. It should be printing 0 instead of 00.
So how do you print an integer as 00. This is what we will be talking.

<Think before scrolling>
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
..
.
.
..
.
.
.

You can use a format specifier :D

int a = 00;
printf("%d",a) -> 0
printf("%02d",a) -> 00

However there are functions which can replicate a given number/character which is the takeaway.
Check the below link.
http://www.cplusplus.com/reference/iomanip/setfill/


 int hrs = 0;
 cout<<setw(2)<<setfill('0')<<hrs<<endl;

Hope you enjoyed reading and got something out of it.
Please post comments/suggestions(if any).

20 March, 2013

Performance metrics of Computer Systems - 1

When we think about evaluating the performance of a system, some things that comes to our mind are

a) Configuration and Flow that needs to be bench-marked.
b) Number of instances of node/server (1 or many ).
c) Duration of the task.
d) Tools that are gonna be used for analyzing and preparing report.
e) Existing benchmark report of the system for comparing the new data.


Let me give you my idea on each of the above aspects as well as my views on performance metrics of a system. Specifically let me discuss about "arriving  at benchmarks when we release the Version 1 of the software" in this blog.

consider a simple coin toss :)  Yeah its about probability and queuing :D
How are we going to measure the performance of this toss?
a) May be height travelled by the coin ?
b) Number of flips it makes? etc etc.

We use "laws of physics" as a tool to measure the performance metrics of the coin.

Now consider a system where messages are received, parsed and given to various components and sent back. This kind of system is called Open system.

There is one more type of system called Closed System. Interpret it to a CI machine where CI-coordinators submit jobs which in-turn is executed on a set of machines ( servers ) and returns back to idle state.

Our software (Version 1) can be open or closed. As we don't have any previous benchmarks for this software, we have to arrive at a theoretical bench-mark so that we are able to ascertain the practical measurements.

So how do we arrive at theoretical benchmarks?
Using Queuing models :-). Yeah its all maths buddy :D

For those who have taken a Queuing course, these things should not be new. Others please continue reading.

As we are used to event-driven programming, lets continue our thoughts using this.

What is event-driven programming?
Some events happen and based on the event we execute some tasks ( code ). After this may be the server goes to wait state to handle next set of events.

So lets define 4 set of events.
a) Customers / Messages arrive randomly (which we call Poisson arrivals)
b) Customers / Message wait in queue for getting processed.
c) They get processed. ( called exponential service times)
d) They leave the system ( our system memory allocs are put back to pool. )

Of-course there are certain systems where messages arrive at fixed time slots like burst ( Systems like ALOHA / Slotted ALOHA uses something like this. Other case may be where attacker is trying to send a burst message causing buffer overflows in network elements) or what not.

So having defined these events we can categorize our system ( software ) as M/M/N/K system.
First M denotes the arrival rate of messages into our system. Second M denotes the rate at which it is processed. N denotes the number of servers handling our messages and K denotes the system capacity.

Why do we have two M's ?
Aren't the messages going to be served in the order they arrive?

No. Most systems have some thing called classes similar to IntServ/DiffServ model where customers paying more are grouped into higher classes and have better experience while those pay low have lower experience comparatively.

Also consider the case where server is bombarded with lots of requests it can't handle. What can server do now ?

It can delay the person entering the system through some protocols like Stateless Cookie protocol
i.e if some one sends INVITE message in case of SIP protocol or SYN message in case of TCP the server handling it can send a reply asking him to solve a hardest puzzle/ calculating a hash which would take sufficient amount of time for the sender to compute and reply. In the mean time server clears the messages in its queue and is ready to accept new connections.

So we are deliberately delaying the customer entering the system. This happens with IRCTC [ Indian Railway Reservation Systems Servers :) ]

So coming back to our M/M/N/K model, this model has a set of predefined formulas through which
one can arrive at various metrics of system like throughput, delay, waiting time of customer(message), time spent by the message in the system etc.

Using these values along with the system parameters one can arrive at the theoretical bench-mark of a system and then use it to compare with practical data of our version1 software.
 
Let us conclude it for now. Other factors would be posted gradually.
Hope you got something out of this post.
Please post comments/feedback (if any).

15 March, 2013

My experiences with Thread safe code - 1

In this post, let me share my views and experiences about things to be done while coding in a distributed environment with respect to thread safety.

Persons who had taken a course on operating systems would be knowing about thread safe code. For those who doesn't know anything about it, as always let me give a gist.

What is thread?
Thread is a light weight process.

What is process?
A process is a program in execution.

For example : Consider microsoft word. When you open it, the process starts running i.e this program is in execution. This program has lots of features like spell check, auto correct etc which are independent threads running along with it.

In a single threaded process, only one flow of control exist.  The code executed by these processes  need not be thread-safe. In multithreaded programs, the same functions and the same resources may be accessed concurrently by several flows of control.

Let me explain thread-safeness  through an example.

Consider the case where there are group of people who come together to perform a particular task.
Each people has a role i.e they have some boundaries/memory which they don't cross.
Ex : Hadoop/GFS(Chubby)/Open Stack etc.

To illustrate still more, consider a bathroom.
Only one person can use it at a time. Other persons should wait for their turn.

A thread-safe code protects shared resources from concurrent access by locks. 
Thread safety concerns only the implementation of a function and does not affect its external interface.

For further info please read this.

So having defined some basics of thread safe function, let me share my experiences on it.

If you had read my previous post on design patterns , I would have spoken about something called service and session. I was writing a separate library in my previous concern where the objective was to provide some features like calculating current time and attaching to message based on customer specified version.

This library written would be loaded by the service using dlopen and would be accessed for each and every session. So for calculating the current time, I was looking for some system calls which would return me the time/date etc and I came across this function called localtime. I was happy, used it & finished my implementation and was waiting for code review comments from my technical lead.

To my shock, the implementation was not supposed to be done in the way I had done.
My usage was proper. I have used proper libc function which is a tested code.

But then why?

I missed seeing the below one in  the local time function.

/***********************
The function accesses the object pointed by timer.


The function also accesses and modifies a shared internal object, which may introduce data races on concurrent calls to gmtime and localtime. Some libraries provide an alternative function that avoids this data race: localtime_r.
***********************/
I should have used localtime_r function () . Why ?

Because there can be multiple parallel sessions running in the server and there is a potential chance of multiple sessions accessing this library at same time leading to corruption.
I was thankful as it was caught in review stage else it would have leaked after deployment.

So the lesson learnt from this

"If you are programming in a multithreaded environment and you are looking for system functions defined in libc kind of libraries, confirm whether it is thread safe or not and then use it".

However there are many others which i would post gradually. I just glossed over some things in this post.

Thanks for reading. Lets conclude it for now about my view/experience on writing thread-safe programs.

Please post any comments/suggestions so that I can improve.
 

14 March, 2013

Dumping my ideas - 1

As you would have noticed in my profile, I used to think a lot on new things by using existing infrastructure both technically and socially. This blog is not about how to cultivate this. May be I can post later on how to develop ourselves.

Okay coming to the topic, I used to discuss ideas with my best pal Arun who is currently a Master's Student at Georgia Tech. But as things get tougher in our grad days, we hardly speak about new ideas currently as we have a lot of grad stuff to do. These ideas run in some swapped block and occasionally/randomly we used to bring it to main memory  :P. There is no specific scheduling algorithm for it.

This is one such idea that we spoke last month. I'm not sure whether this already exists. So, if some one is planning to use this idea let us know before you start as current world is a patent world. :-)

Time Line :

17/2/2013 -> This idea struck my mind.

18/2/2013 -> We spoke about this. Thought about its feasibility and factors.
14/3/2013 -> This blog is written.

Let me explain my idea in subsequent paragraphs.

Everyone loves food :-) There can't be even a single person in the world who can say "I hate eating".
That's the reason food stores/hotels came up with websites where customers can make online orders and get them delivered using delivery guys associated with that shop. Ex : Pizza / Burger shops, Notorious restaurants etc etc.

Then came a new trend of online sites like www.justeat.in whose objective is to make all restaurants to advertise themselves using their platform so that people can purchase stuffs and it gets delivered using the shop-appointed delivery guys. As the site says, all they need is an area name through which they can suggest us shops to purchase or spam us by placing ads.
How do they get paid?
1) They provide a common platform for all guys to create their sites. So the hotels should be paying them.
2)  They can place ads and use click feature to track and charge.
3) They can also charge based on the purchases made to a particular shop.

However the common thing is, if we want to host our shop/hotel/store we need to either create our own site by buying all necessary servers, hiring engineers or  use cloud providers like GApp Engine or AWS or Azure. In this case its justeat as persons use this to advertise their shops but they need to pay for it.

Okay so whats my idea? Before spilling it out, let me give some use-cases on who would be benefited.

1) Contractors who work as delivery guys in shops.
2) Home Makers like our mom.
3) College students and all people who want to work part-time .
4) Restaurants who don't have sufficient capital to invest in website for them.
5) Common person like you and me.
6) The country.

and many more. [ Note : Comment if you have any more use-cases after reading it. ]

To create a website which has the following features.

1) Restaurant owners / Home makers post their foods that are available for sale in this site.
2) Delivery guys register themselves with this site and give their locality preferences for delivering so that he/she is able to see posts only related to his/her region.

Now how things gets delivered?
Common man who needs food looks,orders and pays to the site.
The site posts this requirement in delivery guys section based on locality.
Delivery guys allocates the order to them so that it doesn't gets chosen by other person belonging to same region. The order goes to the required shop/home through all means ( phone call , sms, email etc).

Now delivery guys visits that location picks it and delivers to the required location. Their credibility increases based on customer feed back / delivery of the item. If he doesn't deliver it and haves it for his own purpose he is barred from further correspondence. So we need to authorize these persons through some system [ like tracking them through some unique ID like SSN or Passport Number ].
Also the customer can claim he didn't receive by putting the blame on delivery guys. This can be authorized by delivering guys sending a signal(digital image of signature) to some server confirming the acceptance.


Income factor :

Delivery guys earn through tips as well as site pays him/her based on some factor in food order.
Site earns through may be a factor on usage. For example : If a particular shop / person ships lots of orders, he will be charged more. Similar to Pay when you use model of cloud computing :-)
If some one doesn't get any order, they needn't pay anything.

Now why it can be popular?
a) Delivery guys needn't be bonded to contract. They get paid on number of customers they deliver.

b) Homemakers can make money from home by posting in this site.

c) College students can earn part-time handy money by doing this in their region. Suppose two
persons are in love with each other. The girl can order. The guy delivers it to her home. Lol :P

d) Restaurants who don't have sufficient capital to create their site can try this feature and increase their revenue.

e) Common person like you and me often visits restaurant. Through this site we can do something like this. We can place the order as well as register in the site as delivery person. We visit the shop get the food and also get paid by the site for delivering it. So "we earn for what we eat" :)

f) Finally the country gets benefited as production rate increases and there are lots of persons now with some jobs :)

Isn't this nice or am i missing some things?

I would like to thank one of my friend Karthik on bringing some couple of problems to me.

a) By using this system, delivery guys  gets to know the preferences of persons belonging to a particular locality as he knows both producer & consumer. So he can go on starting his own business of delivery by cutting down the revenue of site-restaurant owner/homemaker. [ like Man in the Middle attack. i.e remaining silent till the connection is made and attacking the person ]

b) .. c)...

I'm in the process of thinking about other attack vectors in this and possible solutions.

I hope you enjoyed reading this.
Please feel free to give your opinions by commenting here :)


11 March, 2013

My views and experience with Design patterns - Part 1

           
As it is said in almost all design pattern books, any real time problem can't be solved with just one design pattern. All are intertwined.

Assume we are producer. May be say we are developing an SDK.
Lets see what all patterns can be present.

1) Always have a factory which manufactures objects ( Factory pattern )
           some function like getInstance() or getFactoryObject()->createA() , getFactoryObject()->createB() is fine.

2)  Expose API's to consumer which is simple ( Facade pattern )
          The API's should be simple for the consumer to fill values hiding the underlying complexity of the system.

3) As most of the systems being developed are distributed in nature, try having proxies in your code.
            Say. For example we have n processes (services) sending/receiving messages and processing the request and these process rely on our SDK.

Now we shall have design's like

a) Having a recvBufferQ which receives the message and a thread keeps on polling this Queue to take this message to put in some other Queue based on type of message or any criteria.

b) The other way we could think of is identifying each message as new session and subsequent requests belong to same session if it comes from the same user.

To be more clear on this lets define something called a Service and Session.

Service : A service is one which does a particular job. For example : Order processing , Payroll processing, Query processing, Call Processing. It is a single object.

Session : A Session is one which is associated with this service. There can't be any session without service. It can be correlated to users who are performing those operations. So lets associate each user to one particular session.

For example : If A orders something or searches something using amazon.com or google.com or anyother sites, his query goes to a particular service which in turn gets a unique session object for this user and he is permitted/not permitted to do operations based on session state.

For persons who have done
a) Theory of Computing course, visualize it to an Automata or Turing Machine.
b) Probability & Queuing course, visualize it to M/M/N/K system.


Once the user logs out, the session is no longer associated with the user and is deleted. May be we can dump the object state to DB for charging him in case of call processing system / auditing him later / placing ads based on previous session history etc etc.

So now as we said each user is treated as a new session. Now we can't handle all those requests using a single class implementation. It will obviously lead to adding locks, processing delays leading to performance bottleneck and dropping of messages leading to 503 Service Unavailable. This can be visualized in a different way where attacker keeps on creating N number of sessions and not releasing those sessions causing the server to overshoot its memory leading to 503.

Lets get back to design patterns. As a single class implementation can't handle all requests we have to delegate the requests to a different person. We can either use the queue method to give it to each process based on some factor or we can go with something called proxies.

Lets define new terminologies called Service Proxy and Session Proxy.
A session proxy is one  which handles the requests on behalf of the session.
A service proxy is a client side proxy of a service.

If you are interested more try understanding http://msdn.microsoft.com/en-us/library/windows/desktop/dd430452%28v=vs.85%29.aspx.

So how many sessions do we create ?
Ans : Here comes the concept of Object Pool.

Ideally it is based on the load of the webpage / server or based on some heuristics.
We can initialize huge sessions and place it an object pool and mark it idle. Every time a request arrives the session is used and returned back. Before returning back to the object pool, the user state may be recorded in DB. There can be a separate service which uses some API's to analyze this session object and use that information to display Ad's or get the user email ID and spam him :P and what not :).

How long should we maintain a session?
May be we can run a timer which is done in most of the systems and erase it once the timer fires.

Should we create more sessions on-demand?
Of course yes. Say if 90% of object pool are in use, there is a potential chance of it to reach 100%, so may be the service can add some more new sessions to object pool.

How can we add new sessions to an existing object pool?
Think of it as a linked list. There is Node1 which points to the 1st object pool. Now we can create node 2 and initialize with another chunk and keep on repeating this.


I talked about exposing cool API's, hiding the complex implementation to consumer.
Now these API's usually have an input parameter and output parameter.
Input param should be some structure where customer fills some values and may be a system call happens based on those and the guy who receives the call fills the output param with values.

Customer may/may not fill all values. For example consider a job portal where there are lots of fields which are mandatory and fields which are optional. Any programmer(who doesn't sleep while coding :P ) would initialize all the member variables in constructor thereby ensuring values for optional params also.

What if we need to modify this API future? Are we permitted to add new variables or new structures?

DEFINITELY NOT.

Why?
The size of the object changes. To illustrate more, lets say customer one uses your library builds his application. Later he needs some updated feature version of the library. Now if you modify an existing API, the newly built application would work fine.

What happens to applications which are already running?
when that call is made for the API which is modified the app COREDUMP's  :) similar to my mind right now :)

So how do we solve this problem?
1) The API defined initially should not have an object as parameter. Instead we can define it as an AutoPtr.

2) If some new features needs to be added instead of adding new objects we shall define something called Extension Ptr.

class A
{
       // mandatory features.

       // Extension
       ExtensionAutoPtr B;

};

Now this class B can be used to add new features.
The API exposed to customer can be Func(AutoPtrofA,RetAutoPtrofA)

Now how do we decide whether some variable is set by user or not?
Naive approach would be to check by comparing the values with the initialized values in the constructor.

Is there any other way?
Think of it. Variable storage differs based on type. For ex : char occupies 1 byte, structures occupy the size of it, union occupies the max value defined it.  So to decide whether an object has  a value set or not we can use char which occupies 1 byte or may be a boolean with each variable/object initialized to false instead of iterating through all variables inside a complex structure or checking with initial values.

When the objects value is set by the consumer this boolean variable associated with the object has the value true which means consumer has set it else not.

Lets conclude it for now about my view on design patterns - part 1 .

I hope readers understood something about design patterns.

Kindly do read my other blogs and give feed back so that i can improve :)





09 March, 2013

Traceroute: How It Works and Overcoming Firewall Limitations

Understanding the Basics

When we execute a traceroute command, our machine sends out 3 UDP packets with a TTL (Time-to-Live) of 1. When those packets reach the next hop router, it will decrease the TTL to 0 and thus reject the packet. It will send an ICMP Time-to-Live Exceeded (Type 11), TTL equal 0 during transit (Code 0) back to our machine - with a source address of itself, therefore we now know the address of the first router.

Next our machine will send 3 UDP packets with a TTL of 2, thus the first router that we already know passes the packets on to the next router after reducing the TTL by 1 to 1. The next router decreases the TTL to 0, thus rejecting the packet and sending the same ICMP Time-to-Live Exceeded with its address as the source back to our machine. Thus we now know two paths.

This process keeps going until we reach the destination. Since we are sending UDP packets with the destination address of the host we are concerned with, once it gets to the destination the UDP packet is wanting to connect to the port that we have sent as the destination port. Since it is an uncommon port, it will most likely be rejected with an ICMP Destination Unreachable (Type 3), Port Unreachable (Code 3). This ICMP message is sent back to our machine, which will understand this as being the last hop, therefore traceroute will exit.

The Firewall Problem

The regular traceroute usually uses either ICMP or UDP protocols. Unfortunately, firewalls and routers often block the ICMP protocol completely or disallow the ICMP echo requests (ping requests), and/or block various UDP ports.

When we execute traceroute using ICMP or UDP using commands:

traceroute -I www.microsoft.com (ICMP) traceroute -U www.microsoft.com (UDP)

After some couple of message exchanges, we often end up getting * * * as the firewall blocks our message.

The TCP Solution

So how do we get the actual address of the destination host? The answer: using traceroute over TCP.

To our surprise, executing:

traceroute -T -p 80 www.microsoft.com

returns the exact IP address!

Of course, there are lots of traceroute implementations, and if your system doesn't have the one as stated above, please check http://michael.toren.net/code/tcptraceroute/

Why TCP Works Better

TCP traceroute works better in these situations because many firewalls are configured to allow TCP traffic on common ports like 80 (HTTP) and 443 (HTTPS), as blocking these would prevent normal web browsing. By using TCP on these permitted ports, we can often bypass the restrictions that would block traditional ICMP or UDP traceroute attempts.

This technique is particularly useful when troubleshooting connectivity issues to web servers or other services that primarily communicate over TCP.

Practical Applications

This knowledge can be invaluable when:

  • Diagnosing network connectivity issues
  • Identifying where packets are being dropped in a network path
  • Mapping network topologies behind firewalls
  • Performing security assessments

Next time you're faced with a traceroute that's showing stars instead of hops, remember to try the TCP variant - it might just reveal the full path you're looking for.

24 February, 2013

Life as a Random Oracle Model: How We Cache Our Social Interactions

Understanding the Random Oracle Model

For those who are new to this term "Random Oracle Model," let me give a gist.

Given a query, this model returns a result. But how does it return? If it has already seen the query, it just returns the result in O(1) time; otherwise, it does a lookup operation in evaluating and returning the result.

It can be interpreted as a form of permanent caching and is used in almost all cryptographic algorithms. For more info, check this Wikipedia article.

The Human Random Oracle

Then I thought about the way we live our lives. It sounded similar to me. Maybe these models were invented by those who were able to model these data structures based on their personal life—or I'm just a douche :)

Anyway, here's the thing: everyone should have similar examples in their life. We come across many people in our lives. We maintain a cache for those people with whom we want to always move or respond. For others, it's just a random response or no response.

Random Oracles in Interviews

Consider you're attending an interview. The interviewer asks a question which you've already come across. Now what would you do? Would you behave like a random oracle model? :)

Would you answer the question instantly as you know the solution already, or drag out the time doing fake thinking, returning some false positives similar to a bloom filter... and finally give the solution?

I would suggest notifying the interviewer that you've already come across this question and use ROM in your head to provide the answer directly. But many people don't do that. They act like they've seen it for the first time.

To be frank, I was educated by my undergrad college seniors not to respond quickly though I knew the answer...

Social Caching and Response Mechanisms

Let's consider another example: your friend introduces you to their friend. Do we immediately consider the new person a friend? I guess not. Most of us just remember them, and when we see them on another occasion, we greet them and that's it. We maintain a cache for this person, but we're responding to them with answers which may or may not satisfy them.

A Case Study in Social Oracle Failure

Recently, one of my friends came across this situation. Let's use notations for privacy:

Let A, B, C be three persons defined as follows:

  • A - My friend
  • B - A's friend
  • C - B's friend who is not A

The following events took place:

  1. C had gone to his home country for vacation.
  2. A had asked B to get some items from persons who are returning from that country.
  3. B informs C.
  4. C brought those items as requested by B.
  5. Now C brings those items back.
  6. A queries B and reaches C's house.

Now, whenever someone visits your house, it's common to greet them with drinks or sweets, learn about them, and rejoice with them if there are any common moments. In this case, A was taken aback by C's behavior:

C: "Oh. It was you. Good. Good... Okay. Here is your item which was requested by B. Have it." A: "Thanks for bringing it. [Some pleasant conversation]"

// C and A stare at each other for some time. A expects C to welcome him and ask him to take a seat.

C: "Make yourself comfortable. Take some sweets [pointing to some room]." C leaves the scene. A: Perplexed on what to do, leaves.

Why did C behave like that?

  1. Probably C had already known about A that he is difficult through some other person D.
  2. He was so busy that he didn't have the courtesy to explain to A.
  3. He himself observed A and made a quick judgment. ...or whatever.

Maybe you can justify that I'm in the wrong here, so is A, and that's the reason C behaved like that.

If any of the above cases were true, C should not have brought those items for A when informed by B. It's better to avoid getting committed rather than taking on such tasks and making the situation awkward.

This could be compared with stories a programmer takes for implementation: either take a requirement and implement it correctly, or don't take it at all.

The Courtesy Protocol

Random Reader: "I already have lots of friends. I don't want anyone new in my group." My answer: "Yeah, buddy. Sure. But one should have the courtesy to politely decline the new person."

Is that the reason Facebook came up with lists, groups (secret, closed, etc.), and the ability to block updates from people who are still on your friend list? :)

Coming Back to the Original Theory

Are we violating the Random Oracle Model in our lives?

Now you might ask why we need to follow the Random Oracle Model. I'm not advising anyone to follow this model. I just noticed that our life design patterns are akin to this.

I guess all of us are selfish in one way or another.

We use the model only when it benefits us, or we behave in a way similar to existing models :)

It can be business, personal, or anything.

The Ultimate Question

So one more question arises: Is life deterministic enough to be accommodated into some model?

What do you think about this?


[For readers who made it through this philosophical exploration, thank you very much for visiting my blog. Please post comments on what you feel as well as suggestions so that I can improve my writing.]

23 February, 2013

Is Life Deterministic or Non-Deterministic?

I feel life is a deterministic-polynomial time solvable Turing machine :P in the way it has been to me till this time.

Things happen which have a trigger in the past and the loop keeps on running. Oh yeah, who pulled the trigger?? Some unknown void pointer which happens to be the unseen God :)

Don't think I'm an atheist :)

My mind core dumped and I thought I would post the stack trace here :)

Sarcasm: The Ultimate Social Encryption Algorithm

Sarcasm is an encryption technique used by relatively smart people to keep idiots out of their conversations. It may also be used to belittle and mock them.

The encryption and decryption technique of sarcasm is inbuilt in many humans.

Some humans are capable of encrypting a message using sarcasm in O(1) time, while some take O(n^2), where n is the number of characters in the message. Some idiots are also capable of encrypting messages with sarcasm, but it is very rare, as they need O(2^n) time in most cases to encrypt a message of length n.

Decryption, on the other hand is a bit tedious. The most brilliant minds on this planet take about O(log n) time to decrypt any sarcastic message in worst case; although the average time needed by them is still O(1). The average intelligent being takes about O(n^3) time to decrypt a sarcastic message. Idiots on the other hand, are completely off chart when it comes to decryption. The smartest idiots are capable of decrypting sarcastic messages in O(5^n) time, because they're counting with fingers on one hand only; although the average idiot is not capable of deciphering a sarcastic message in his/her lifetime.

It's a sick sad world with intelligent people keeping their information and techniques secret encrypted with sarcasm and idiots can't have access to it to become intelligent even if they want to. Ah, the irony of it!

No, this is not meant to demonstrate sarcasm.

Software Diversity as a Security Measure: Can Unique Executables Prevent Attacks?

We're constantly hearing news about cyberattacks on major companies like Facebook, LinkedIn, and Twitter. One common vulnerability often cited is issues with the Java plugin that allow attackers to penetrate systems. While Oracle regularly releases patches, I've been wondering: are these just temporary fixes, or do we need more fundamental approaches to software security?

Last month, I had the opportunity to attend a fascinating colloquium by Dr. Michael Franz from UC Irvine, held at UT Dallas. His talk, titled "Software Immunity via Large Scale Diversification," presented a novel approach to cybersecurity that got me thinking about the future of software protection.

The Concept: A "Multicompiler" for Software Diversity

Dr. Franz and his team have been investigating compiler-generated software diversity as a defense mechanism against attacks. The core idea is surprisingly elegant: imagine an App Store containing a diversification engine (a "multicompiler") that automatically generates a unique version of every program for each user.

Here's the fascinating part - all these different versions of the same program behave identically from the end-user's perspective, but they implement their functionality in subtly different ways under the hood. The compiler introduces variations in memory layout, code sequences, and other implementation details based on a seed value (similar to how cryptographic algorithms work).

Why This Approach Could Be Revolutionary

The security benefits of this approach are compelling:

  1. Attack Dilution: Any specific attack would succeed only on a small fraction of targets since each user has a uniquely compiled version.
  2. Increased Attack Complexity: Attackers would need to develop a large number of different exploits and would have no way of knowing which specific attack would succeed on which target.
  3. Resistant to Reverse Engineering: This approach makes it much more difficult for attackers to generate attack vectors by reverse engineering security patches.

According to Dr. Franz, his team has already built a prototype multicompiler capable of diversifying large software distributions such as the Chromium web browser or a complete Linux distribution. He mentioned that this technique is currently being deployed at Mozilla.

Practical Challenges

While the concept is promising, it does introduce some practical challenges:

Patch Management: The process makes patching more complex, as updates need to be customized for each user. Companies would need to track the versions running for every user, retrieve the seed used in the original executable, and generate a new executable based on either the existing seed or a new one.

Error Reporting: When every binary is unique, how do you handle error reports? Traditional error reporting relies on identical binaries to identify patterns.

Resource Requirements: Generating unique versions for millions of users could require significant computational resources.

Could This Really Work?

The question remains: can we really enhance security by creating unique executables for every user? The approach certainly introduces a new dimension to security - moving from a monoculture where all systems share the same vulnerabilities to a diverse ecosystem where attacks can't easily scale.

It reminds me of biological diversity in nature, where genetic variation helps populations survive diseases that might otherwise wipe out a genetically uniform group.

The concept leverages a fundamental asymmetry in cybersecurity: attackers need to find just one vulnerability to succeed, while defenders need to protect against all possible attacks. By introducing diversity, we force attackers to develop multiple exploits for the same vulnerability, significantly raising their costs and reducing their success rate.

Dr. Franz and his team have clearly thought through various aspects of this approach, but as with any security innovation, time will tell how effective it proves in real-world scenarios.

What's Your Take?

I'm curious about your thoughts on this approach. Could software diversity be the key to building more resilient systems? What other challenges might arise in implementing such a system at scale?

Let's observe how this develops as time progresses. Perhaps we're witnessing the early stages of a fundamental shift in how we approach software security - moving from a model of "patch and hope" to one of built-in resilience through diversity.


For those interested in learning more, you can find Dr. Michael Franz's research at http://www.ics.uci.edu/~franz/.

22 February, 2013

Elegant Software Design: Principles for Maintainable Applications

In my journey as a software engineer, I've discovered that writing code that merely functions is the easy part. The real challenge lies in crafting code that remains maintainable and adaptable as systems evolve. Today, I'd like to share some design principles that have proven invaluable when building robust applications.

The Foundation of Good Design

At its essence, good software design is about managing complexity. As systems grow, complexity naturally increases. Without intentional design decisions, this complexity becomes overwhelming, leading to bugs, development friction, and technical debt.

As Ralph Johnson once said, "Before software can be reusable, it first has to be usable." This simple statement captures the importance of thoughtful design in creating sustainable software systems.

SOLID Principles

The SOLID principles provide an excellent framework for creating maintainable code. Let's explore each one:

Single Responsibility Principle

A class or module should have only one reason to change. This principle encourages us to design components that are focused on a single concern, making them easier to understand, test, and maintain.

When I first started programming, I often created large, monolithic classes that handled multiple concerns - validation, database operations, email notifications, and logging all in one place. Eventually, I learned that separating these responsibilities into distinct components made my code significantly more maintainable.

For example, instead of a massive UserManager class that handles everything, we might have a UserValidator, UserRepository, NotificationService, and ActivityLogger, each with a clear, focused responsibility.

Open/Closed Principle

Software entities should be open for extension but closed for modification. This means we should be able to add new functionality without changing existing code.

This principle has saved me countless hours of debugging. By designing interfaces that can be extended with new implementations, I can add features without risking regression bugs in existing functionality.

Consider payment processing - if we design our system properly, adding support for a new payment method (like cryptocurrency) shouldn't require modifying our existing credit card or PayPal processing code.

Liskov Substitution Principle

Subtypes should be substitutable for their base types without altering the correctness of the program. This principle ensures that inheritance hierarchies are designed properly.

I've seen many inheritance hierarchies that violate this principle, creating subtle bugs. For instance, a Square class that inherits from Rectangle might seem logical, but could break code that expects to set width and height independently.

Interface Segregation Principle

Clients should not be forced to depend on interfaces they don't use. It's better to have many small, specific interfaces than one large, general-purpose interface.

This principle has helped me create more flexible and decoupled systems. By defining focused interfaces, components only need to implement what they actually use, reducing unnecessary dependencies.

For example, rather than having a single FileHandler interface with methods for reading, writing, compressing, and encrypting, we might have separate Reader, Writer, Compressor, and Encryptor interfaces.

Dependency Inversion Principle

High-level modules should not depend on low-level modules. Both should depend on abstractions. Additionally, abstractions should not depend on details; details should depend on abstractions.

This principle has been transformative for my approach to software design. By depending on abstractions rather than concrete implementations, I can easily swap out components without changing the core business logic.

For instance, a UserService might depend on a DataStore interface rather than directly on MongoDB or PostgreSQL implementations, making it easy to change the underlying storage mechanism.

Practical Design Patterns

Beyond SOLID principles, several design patterns have proven particularly useful in my projects:

Factory Pattern

The Factory pattern provides a way to create objects without specifying the exact class of object that will be created. This pattern helps decouple object creation from the code that uses the objects.

I've found this pattern especially useful when the exact type of object needed isn't known until runtime, or when object creation involves complex logic.

Strategy Pattern

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern allows the algorithm to vary independently from clients that use it.

I've used this pattern extensively for implementing different business rules, sorting algorithms, or pricing strategies that can be selected dynamically based on context.

Decorator Pattern

The Decorator pattern allows behavior to be added to individual objects, either statically or dynamically, without affecting the behavior of other objects from the same class.

This pattern has helped me add cross-cutting concerns like logging, caching, or access control to existing functionality without modifying the core components.

Observer Pattern

The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

This pattern has been invaluable for building event-driven systems and user interfaces, where changes in one component need to be reflected in others.

Design Principles in Practice

While these principles and patterns provide valuable guidelines, applying them effectively requires judgment and context. Here are some practical insights I've gained:

Balance is Key

Overengineering is just as problematic as underengineering. I've learned to strike a balance between applying design principles and keeping solutions simple.

Early in my career, I fell into the trap of applying patterns everywhere, creating unnecessary complexity. Now I recognize that sometimes a straightforward approach is best, especially for simpler problems.

Evolve Your Design

Perfect design rarely happens upfront. Instead, I've found that good design emerges through continuous refactoring and adaptation as requirements become clearer.

I now practice incremental design, starting with simpler solutions and gradually introducing patterns and abstractions as complexity increases.

Consider the Team

Design decisions should account for the team's expertise and familiarity with different patterns. The most elegant design is worthless if the team struggles to understand and maintain it.

I've learned to collaborate with team members when making design decisions, ensuring everyone understands and buys into the approach.

Test-Driven Design

Writing tests first often leads to better design decisions. When I write tests before implementing features, I'm forced to consider how components will be used, leading to more intuitive interfaces.

This approach has helped me create more modular, loosely coupled designs that are easier to test and maintain.

Conclusion

Good software design isn't about following rules rigidly—it's about understanding the principles behind them and applying them judiciously to your specific context. The principles and patterns I've outlined here have served me well in my own projects, helping me create code that's not only functional but also adaptable to change.

As your applications evolve, you'll find that time invested in thoughtful design pays dividends in reduced maintenance costs and increased development velocity.

Remember that the best code is not just correct—it's clear, maintainable, and a joy to work with. Happy coding!


What design principles have you found most valuable in your projects? I'd love to hear your thoughts in the comments below.

Hello World!

After months of contemplating, planning, and yes—battling procrastination—I'm thrilled to finally launch this blog. Welcome to my little corner of the internet!

"Arise, awake and stop not till your goal is reached." - Swami Vivekananda

That quote has been my North Star throughout this journey. Along with the Tamil proverb "Ellam nanmaike" (All is well), these words of wisdom guide my approach to both life and coding.

And yes, I'm well aware of the irony in the joke: "Procrastinators unite... Tomorrow." Try not to procrastinate as much as you can—a lesson I'm still learning myself!

I've come to realize that passion alone is not sufficient. It should be backed by suitable knowledge. That's partly why I've created this blog: to deepen my understanding through sharing.

What This Blog is About

This space will serve as my digital journal where I'll share:

  • Technical insights and challenges from my software engineering projects
  • Deep dives into interesting programming concepts and technologies
  • Lessons learned throughout my career journey
  • Thoughts on software architecture, design patterns, and best practices
  • Occasional reflections on the tech industry and developer culture

I hope that by documenting my experiences, I might help fellow developers avoid pitfalls I've encountered or discover solutions I've found useful.

About Me

I'm Ganapathy Subramanian Ramachandran, though most people know me as Ganu. I'm a software engineer passionate about building robust, scalable systems. My journey in tech has taught me that continuous learning and adaptation are essential in our ever-evolving field.

When I'm not coding, you might find me discovering new restaurants around town, driving to scenic places on weekends, or simply spending quality time with my kid. I particularly enjoy exploring the culinary diversity this region offers, finding those quiet, picturesque spots that make for perfect getaways, and watching my child learn and grow through our everyday adventures together.

What's Next

In the coming weeks/months/years, I'll be sharing posts about my thoughts on the technology space . If there's anything specific you'd like me to explore, feel free to reach out!

For more updates and to connect professionally, you can find me on LinkedIn.

Thanks for joining me on this journey. Here's to breaking the procrastination cycle and building something meaningful together!