Sunday, 10 September 2017

Installing and Using OpenGrok on Mac OS X

Background

In previous couple of posts we saw how we can setup git repositories, install git client and maintain your codebase. 
In this post we will see how to set up opengrok. This is a code base search tool that you can use to index and search your huge complex codebase. I am going to show this on my mac laptop. If you want to setup a proper server please refer to official documentation.


Installing and Using OpenGrok on Mac OS X

I am going to use Homebrew to do most of the setup here. If you are not aware of homebrew then you can read -
 Couple of things you need to install before are -
  • A servlet container like GlassFish or Tomcat to run and deploy your grok server. I will use tomcat.
  • Exuberant Ctags for analysis.
You can run following commands to set these up -
  • brew update
  • brew install tomcat
  • brew install ctags 
You can just type catalina to see tomcat is properly installed -


Next set environment variable as follows -
  • export OPENGROK_TOMCAT_BASE=/usr/local/Cellar/tomcat/8.5.20/libexec
 For path you can refer to catalina screenshot above. This environment variable will basically tell where grok needs to be deployed.

Download the latest opengrok binary from-
 I am using opengrok-1.1-rc13.tar.gz.

Next go yo your opengrok bin directory. In my case it is -
  • /Users/athakur/Documents/Softwares/opengrok-1.1-rc13/bin
and run -
  • ./OpenGrok deploy
 This will deploy grok code on your tomcat container. Now start the tomcat container




 You can now access it via -


 The error you see is ok since we have not provided our codebase source directory yet.

Noe lets add source directory. My code is in-
  •  ~/Documents/git/DataStructures
NOTE : DataStructures is a local copy of my github repo -
I am going to maintain all codebase references in
  • ~/local_repos/src/
So create a directory and add soft links as below -


 Now it's time to define your code directory that opengrok can understand. So define another environment variable -

  • export OPENGROK_INSTANCE_BASE=/Users/athakur/local_repos

That's now lets index this content. To index it go to you opengrok bin directory and run -
  • ./OpenGrok index.

You can see it automatically creates directory it needs. Just make sure it has appropriate permissions -




That's it you can refresh grok page and start searching code.


 NOTE : For every update to your actual repository or for any new repository getting added you need to call ./Opengrok index to index it. You can probably write a cron job that does an automatic pull of your repository and runs index on it.


Related Links

Saturday, 2 September 2017

Understanding database indexes - Part 2

Background

Some time back we took a look at what database indexing is and how it internally works. -
In this post we will see database indexing more from a development design perspective. Many of you might be of the impression that database indexes, tables , performance, lookups maybe responsibility of database admins. Though this might be true to some extent indexes selection, and constructing where clause is developers responsibility and poor choice of indexes and where clause may often lead to performance issues causing queries to run slow. So whenever you are developing an application that requires database interactions as a developer it is very important that you design your indexes first. How do we do that?  - We will see that in sometime. 

Understanding database indexes - Part 2

An index lookup require 3 steps -
  1. B-Tree traversal to root node
  2. Traversal along root node
  3. Access actual table data from each root node
Step 1 is limited is size as tree height/level will be limited by log N constraint. For millions of rows there could be 3-4 level of the tree. It will be extremely rare to see a B-Tree with level more than 5.
You can use following query to see the B-Tree level for your index -

SELECT index_name, blevel+1 FROM user_indexes ORDER BY 2;


blevel gives you the levels of your B-Tree index. Plus one is for the leaf node. So these are the number of levels that needs to be traversed to get an index at the leaf node (considering unique scan).

Step 2 and Step 3 can vary and in most cases are causes of slow index lookup resulting in slow running queries.

Let's start understanding by taking an actual example. Let's create a table as follows -

create table schema8.EMPLOYEE(ID int, name varchar2(255),age int, department varchar2(255), salary int);
alter table schema8.EMPLOYEE ADD CONSTRAINT PRIMARY_KEY PRIMARY KEY (ID); 

CREATE UNIQUE INDEX schema8.UX_EMPLOYEE_1 ON schema8.EMPLOYEE (name, age, department);
ALTER TABLE schema8.EMPLOYEE ADD CONSTRAINT UK_EMPLOYEE_1 UNIQUE (name, age, department) USING INDEX schema8.UX_EMPLOYEE_1;


Lets' add some data in it -

insert into schema8.EMPLOYEE values(1,'Aniket',26,'IT',100);
insert into schema8.EMPLOYEE values(2,'John',29,'FINANCE',40);
insert into schema8.EMPLOYEE values(3,'Sam',27,'IT',101);
insert into schema8.EMPLOYEE values(4,'Ron',30,'ACCOUNTING',35);
insert into schema8.EMPLOYEE values(5,'Sky',33,'DEVOPS',62);
insert into schema8.EMPLOYEE values(6,'Paul',26,'FINANCE',43);
insert into schema8.EMPLOYEE values(7,'Dan',24,'IT',100);
insert into schema8.EMPLOYEE values(8,'Jess',25,'ACCOUNTING',37);
insert into schema8.EMPLOYEE values(9,'Troy',31,'FINANCE',41);
insert into schema8.EMPLOYEE values(10,'Mike',28,'IT',103);
insert into schema8.EMPLOYEE values(11,'Anuj',28,'DEVOPS',64);
insert into schema8.EMPLOYEE values(12,'Vinit',29,'FINANCE',48);
insert into schema8.EMPLOYEE values(13,'Sudhir',29,'ACCOUNTING',39);
insert into schema8.EMPLOYEE values(14,'Anish',28,'IT',100);
insert into schema8.EMPLOYEE values(15,'Shivam',25,'DEVOPS',61);
insert into schema8.EMPLOYEE values(16,'Monica',26,'ACCOUNTING',30);
insert into schema8.EMPLOYEE values(17,'Ramji',32,'FINANCE',41);
insert into schema8.EMPLOYEE values(18,'Anjali',34,'ACCOUNTING',38);
insert into schema8.EMPLOYEE values(19,'Payas',26,'IT',100);
insert into schema8.EMPLOYEE values(20,'Zara',27,'DEVOPS',60);


Normal index


Let's start with a simple query -

select * from schema8.EMPLOYEE where department='IT';


It gives 6 rows. What we really want to understand is the performance of the query and if we can improve it. To understand the queries performance we need to take a look at the execution plan that was used by the sql optimizer. In Sql developer you can just
  • Select the query -> Right click -> Explain -> Explain Plan



And you should see the plan that was selected to run this query and associated cost.

So for above query execution plan is -



As you can see a "FULL TABLE SCAN" was selected.  Since your where clause has department column in it there was no other option. Unique index starting with name could not be used. Primary key index could not be used (Index is always created on primary key -id in this case). So it had to go for a full table scan. Now this is obviously expensive. You can see the cardinality is 6 which basically means there are 6 rows which satisfy "department='IT'" clause and cost is also high.

Let's do something about this. Let's create an index in column department and then again inspect the plan.

create index X_EMPLOYEE_DEPT on schema8.EMPLOYEE(department);


and now lets see the execution plan -



Better? Our cost is reduced by half now. As you can see this time our new index was used for the lookup - "RANGE SCAN". So full table access was avoided. Recall our earlier discussion on steps needed for index lookup -
  1. It used index to get to the leaf node
  2. Traveled along leaf node linked list to find all nodes with department='IT' ("RANGE SCAN")
  3. finally for each index accessed the actual table using rowid to get other table data ("BY INDEX ROWID BATCHED") (Batched because data for all rowids are retrieved in a single call)
Hope this clears how indexes help faster execution of queries.

NOTE :
Cardinality is the estimated number of rows a particular step will return.
Cost is the estimated amount of work the plan will do for that step.
Higer cardinality mean more work which means higher cost associated with that step.
A lower cost query will run faster than a higer cost query.

Primary key index 

As you know primary key has an index created by default. Let's try to query the table using primary key and  see it's execution plan -

select * from schema8.EMPLOYEE where id='12';



As expected cost has further gone down. As primary key index is unique index (since primary key itself is unique) execution plan went for - "UNIQUE SCAN"  and then simple "BY INDEX ROWID" (No batched lookup here since there will be just one entry given that it is unique).  So again if you recollect index lookup steps this consists of -
  1. Use unique index to reach leaf node (Just one leaf node) ("UNIQUE SCAN")
  2. Get the table data ("BY INDEX ROWID")
Notice how there was no traversal among lead nodes and no consequent batch access by row ids.

Unique key index

This would again be same as primary key index since primary key index is also a unique key index but let's give this a try since we have defined unique key for our table on - name, age, department

select * from schema8.EMPLOYEE where name='Aniket' and age=26 and department='IT';

And execution plan for this is -



As expected it is same as primary key index. Instead of primary key index it used unique index we created on our own. Steps are same too.

Composite index

Remember our unique index - name, age, department . We saw in the 1st case where we had department in where clause (before creating an index on department) that this particular index was not used and a full table scan was performed.

If you recollect from our previous discussion index column order matters. If the column order was - department , name, age this new index would gave been picked up. Anyway lets try based on what we already have. Now we are going to add name in where clause and based on our existing knowledge our unique index should get picked up (since it starts with name column) -

select * from schema8.EMPLOYEE where name='Aniket'; 

Execution plan -



As expected our index got used and a full table scan was avoided. However if you use age in where clause index will not be used again - since none of your index starts with age. Try it yourself!

Order of columns in where clause does not matter

We saw how order of columns matter in index creation. Same does not apply for where clause column order. Eg consider -

select * from schema8.EMPLOYEE where name='Aniket' and age=26;
select * from schema8.EMPLOYEE where age=26 and name='Aniket';


SQL optimizer is intelligent enough to figure out name is one of the column in where clause and it has an index on it that can be used for lookup and it does so -

For each query above execution plan is -



And that concludes  - order of columns in where clause does not matter!

Multiple indexes applicable - select the one with least cost

So far we have seen various cases in which just one index was applicable. What if there are 2. Let's say you use department and name in your where clause. Now there are 2 options -
  1. Use the unique index starting with name 
  2. Use the index in department
Let's see how it works out -

select * from schema8.EMPLOYEE where name='Aniket' and department='IT';


Execution plan -


As you can see index on name was selected and once leaf nodes were retrieved filter was applied in it to get those rows with department='IT' and finally batched rowid access to get all the table data. This index was selected probably because unique indexes are given preference over non unique index since they are faster. But it depends totally on sql optimizer to figure that out based on execution cost.

Covered indexes and queries

In our previous discussion we saw what covered indexes/queries are. They are basically indexes that have all the data needed to be retrieved and there is no need to access the actual table by rowid. FOr eg. consider -

select name, age,department from schema8.EMPLOYEE where name='Aniket';

Take some time to think this though based on our discussion so far. We know where clause has name it it. We also know we have an unique index that starts with name. So it will be used. On top of that we have an added bonus - we just need name,age,department that us already part of that unique index. So we really don't need to access to actual table data to get any other content.

Let's see this execution plan -


 As expected. There is no "BY INDEX ROWID" or "BY INDEX ROWID BATCHED". That's because table access is not needed since all required data is in index itself. Also note the range scan - even though unique index is used there is no unique row returned since only part of unique index is used.

Summing Up

So to sum up execution plan can do -
  • FULL TABLE SCAN or
  • UNIQUE SCAN or
  • RANGE SCAN
 and then access the table data (if needed) with -
  • BY INDEX ROWID or
  • BY INDEX ROWID BATCHED
Either case you need to choose index very wisely based on your where clause, it's combination. Order of columns in index is very important. Always go for index that starts with column that is used in most of the queries where clause. Also go for equality first than range. So if you where clause is something like - "where name='Aniket' and age>24" always for name as column ordered before age. since equality will give less results to filter from. Age will be applied as filter in above case.

Related Links

Sunday, 27 August 2017

Understanding having clause in SQL

Background

If you have written queries or worked on a project that requires database support then you must have use or atleast familiar with having clause. This is also one of the popular interview questions for beginners to test database knowledge if you ask me. Simple syntax looks like -


SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING condition
ORDER BY column_name(s);


So your 1st and foremost answer is that you use having clause with "group by" clause. How and why we will come to later part in of this discussion. Having said that before we proceed make sure you know what group by clause does. Also you need to have an idea of what aggregate functions are . Eg. min(), max(), count(), sum() etc.


Understanding having clause in SQL

So far we know we use having clause with group by clause. Let's answer the question why. 

Let's say you have a table employee which have basic data of an employee - id, name, department etc. 

Problem statement : Now we are interested to find out how many employees are there in each department and probably see the result in sorted order so that department with maximum employees is displayed first. How would you do this? Using following query -

select department, count(*) from employee group by department order by count(*) desc;

This works fine.  Now let's redefine our problem statement.

Problem statement :  Let's say we now want the same thing - department and number of employees in each department sorted in descending order. However this time we have an additional constraint. We want to see only those departments that have more than 10 employees in it. You would probably try -

select department, count(*) from employee group by department where count(*) > 10 order by count(*) desc;

Problem : Does not work
Error : ORA-00934: group function is not allowed here
             00934. 00000 -  "group function is not allowed here"
(Above error is show for oracle database)

NOTE :  An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference

Problem is that you cannot use aggregate functions in where clause. Solution? - Having clause. This is exactly why having clause was introduced. Once you have applied the group by clause and wish to filter the data further on the results obtained you use having clause. So your correct query would be -


select department, count(*) from employee group by department having count(*) > 10 order by count(*) desc;

Aggregate functions are allowed in having clause. So lets go over the original syntax again and see how it works -

SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING condition
ORDER BY column_name(s);

  1. First you select  column_name(s) from the table that match the where clause condition
  2. Once result is obtained then group by clause is applied to it to get the next set of result.
  3. Once that is done condition is having clause is applied to further filter the result.
  4. Finally order by clause is applied to sort the result as required and return.

NOTE :  where clause us applied to filter results before group by clause is applied where as having clause is applied after.

Other alternative can be like -

select department, count from ( 
select department, count(*) count from employee group by department )\
where  count>10;

Related Links

Friday, 18 August 2017

Find fastest 3 horses out of 25 horses puzzle

Question



You have 25 horses and you need to pick fastest 3 horses out of those. In each race you can race maximum of 5 horses as there are 5 tracks available. What are minimum number of races needed to find the fastest 3 without using a stopwatch. 

Solution

7 races needed. 

Understanding

Since we don't have a stopwatch only way to find fastest is by racing horses. Lets have 5 races each of 5 horses and let following be the results -

  • A > B > C > D > E
  • F > G > H > I > J
  • K > L > M > N > O
  • P > Q > R > S > T
  • U > V > W > X > Y
Above are results of each race.  We have 5 races till now. Now lest race between fastest of all previos 5 races i.e A,F,K,P,U. We have 6 races till now .Let's say the result for that is -
  • F > K > A > P > U

Since We are interested in top 3 P and U are useless for us. Also since P and U were fastest among their group we can ignore all members of P and U too. So now only horses under consideration are -

  • F > G > H > I > J
  • K > L > M > N > O
  • A > B > C > D > E
Now if we consider A as possible candidate for top 3 then others in group of A are redundant - since we already have F and K faster than A. So we can ignore B,C,D,E

Now horses under consideration are  -

  • F > G > H > I > J
  • K > L > M > N > O
  • A
Now in the group lead by k possible horse candidates are K and L - since F is already faster than K if we consider K and L we already have 3. So we can ignore M,N and O. So remaining horses are -

  • F > G > H > I > J
  • K > L
  • A
 Now lets consider group led by F. We can consider G and H as possible candidates for top 3 since if they are I and J are redundant. So remaining now are -

  • F > G > H
  • K > L
  • A
 Now we already know fastest among all in F since we got that result by running fastest among each group. So only horses we need comparison for 2nd and 3rd position are - G, H, K, L, A

These are 5 horses we can have another race and find the top 2 out of them. Lets say the result was -
  • L > H > K > G > A
We have done 7 races now. So fastest onces are L and H. We already the fastest among all - F. So the final answer is -
  • F > L > H 
So the answer is 7 races needed.

10 coins puzzle

Question



There are 10 coin placed in front of you 5 of which are heads and 5 of which are tails. You are blind folded so you don't know which ones are which. You need to make two piles of coins so that both have equal heads. You are allowed to flip a coin any number of time. You obviously wont know which is head and which is tails by touching it.

Solution

Make two piles of coins of equal number (5 each) and then flip all the coins on one side.

Understanding

Lets say you split in into two equal piles. 1st pile has 3 heads and 2 tails. Since there were 5 heads and 5 tails other pile will have 3 tails and 2 heads. Now when you flip all in pile 1 then there will be 3 tails and 2 heads same as pile number 2.

Generically if there are n heads and 5-n tails in pile 1 then in pile 2 will have n tails and 5-n heads. When we flip all coins in pile 1 then pile 1 will have n tails and 5-n heads which is same as pile 2.

Burning island puzzle

Question



A man in stranded on an island covered in forest. Wind is blowing from the west. Lightning strikes to the west side of the forest and starts spreading with the wind. The fire will burn the whole forest killing the man in the process. There are cliffs around the island so that man cannot escape. How can man survive the fire?

Solution

Man picks up a logs , lights it up with the fire from the west end. Then he runs towards the east and lights that part of the forest. This will burn up the eastern end of the forest and then man can take shelter in that burnt area while fire from eastern end burns the remaining forest.

Four men in hats puzzle

Question



As shown in picture above there are 4 men looking forward. None of them can see back. There is a opaque wall between man number 3 and man 4 (1,2,3 cannot see pass the wall). Two of the men are wearing a black hat and two of them are wearing a white hat. Each man can see the color of the hat wore by the men in front of him. (1 can see 2,3 and 2 can see 3) but each person does not know the color of the hat he is wearing.

Now one of the man needs to call out the color of his hat else they all die in 10 mins. Which man will callout the color of his hat correctly and why?


Solution

Answer is Man no 2.

Reasoning


 Lets start by eliminating men. Man number 4 is at the other end of opaque wall facing other side. There is no way he can see any men or the color of their hat. So he is eliminated. Now man no 3 also cannot see anyone else - he cannot look back and he cannot see beyond wall. So he is eliminated too. Now man number 1 knows the color of man 2 and 3. Now lets say they (2 and 3) were wearing same color hat then man no 1 would know the color of his hat since there are 2 white and 2 black hat. But he keeps mum which means man 2 and 3 are wearing different hat. S0 man number 2 waits for sometime if he does not hear man 1 calling out that means man 2 and 3 are wearing different color hats. Since man 2 knows the color of hat wore by man 3 he know the color of his hat and calls it out.

Sunday, 6 August 2017

Enabling Eclipse key map/shortcuts in Android Studio

Background

If you are from a developer using Eclipse then when you start using Android Studio then it becomes difficult to learn new shortcuts. For such cases Android Studio provides an option to use Eclipse shortcuts and in this post we will see how.

Enabling Eclipse key map/shortcuts in Android Studio

Go to 
  • Android Studio -> Preferences
Type in keymap in the searchbox. You should be able to see a keymap section -



Next select Eclipse or Eclipse(Mac OS X) whichever you are more comfortable with. Then click Apply and Ok.



You should be good to use Eclipse shortcuts now. No need to restart.


Related Links


Saturday, 5 August 2017

Select top N records from each category in PL/SQL

Background

Lets say you have 2 tables -
  1. EMPLOYEE
  2. EMPLOYEE_SALARY
EMPLOYEE table has employee id which is a primary key and his name.  EMPLOYEE_SALARY has employee id which is foreign key to id in EMPLOYEE table. This table has employee department and salary. You need to write a query that returns top 2 employees from each department that has highest salary.

Tables creation and data insertion

Table Queries :

create table schema8.EMPLOYEE(ID int, name varchar2(255));
alter table schema8.EMPLOYEE ADD CONSTRAINT PRIMARY_KEY PRIMARY KEY (ID);
create table schema8.EMPLOYEE_SALARY(EMPLOYEE_ID int, department varchar2(255), salary int);
alter table schema8.EMPLOYEE_SALARY ADD CONSTRAINT FK_EMP_ID FOREIGN KEY (EMPLOYEE_ID) REFERENCES schema8.EMPLOYEE(ID);

Data Queries for  EMPLOYEE table:

insert into schema8.EMPLOYEE values(1,'Aniket');
insert into schema8.EMPLOYEE values(2,'John');
insert into schema8.EMPLOYEE values(3,'Sam');
insert into schema8.EMPLOYEE values(4,'Ron');
insert into schema8.EMPLOYEE values(5,'Sky');
insert into schema8.EMPLOYEE values(6,'Paul');
insert into schema8.EMPLOYEE values(7,'Dan');
insert into schema8.EMPLOYEE values(8,'Jess');
insert into schema8.EMPLOYEE values(9,'Troy');
insert into schema8.EMPLOYEE values(10,'Mike');

 Data Queries for EMPLOYEE_SALARY table:

insert into schema8.EMPLOYEE_SALARY values(1,'IT',10000);
insert into schema8.EMPLOYEE_SALARY values(2,'Admin',500);
insert into schema8.EMPLOYEE_SALARY values(3,'Sales',1200);
insert into schema8.EMPLOYEE_SALARY values(4,'Sales',1500);
insert into schema8.EMPLOYEE_SALARY values(5,'IT',9000);
insert into schema8.EMPLOYEE_SALARY values(6,'Admin',4000);
insert into schema8.EMPLOYEE_SALARY values(7,'Admin',5000);
insert into schema8.EMPLOYEE_SALARY values(8,'IT',9500);
insert into schema8.EMPLOYEE_SALARY values(9,'Sales',1000);
insert into schema8.EMPLOYEE_SALARY values(10,'Admin',6000);

Final data :
select * from schema8.EMPLOYEE;
select * from schema8.EMPLOYEE_SALARY;


Solution

We are going to use RANK to partition by department and order by salary - 

select * from (
select id , name, department, salary, RANK() over (partition by department order by salary desc) as rank from(
select e.id, e.name, es.department,es.salary from schema8.EMPLOYEE e left OUTER join schema8.EMPLOYEE_SALARY es on (e.id=es.employee_id))
) where rank <= 2;




First we have done a left outer join so that we capture all employee records with their respective salaries and departments. In outer query we have ranked it based on their salaries in respective department. Finally we select all records that have rank <=2 i.e top 2 records.




Related Links


Monday, 31 July 2017

Install Oracle instant client and sqlplus using Homebrew

Background

 In one of the previous posts we say how to install and run sql plus  and Oracle instant client  on Ubuntu operating system -
In this post we will see the same for a Mac.

This post expects you have homebrew installed. If not please refer -

 Install Oracle instant client and sqlplus using Homebrew

For this you need to download following two files -
  1. instantclient-basic-macos.x64-12.1.0.2.0.zip 
  2. instantclient-sqlplus-macos.x64-12.1.0.2.0.zip 
You can download these files from oracle site - http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html

Once download copy these files into following folder-
  •  ~/Library/Caches/Homebrew 
 Once done run following commands -
  • brew tap InstantClientTap/instantclient
  • brew install instantclient-basic
  • brew install instantclient-sqlplus
 This should install sqlplus for you.


Related Links

Friday, 28 July 2017

How to Disable a MacBook’s Built-In TrackPad When Using a Mouse or Wireless Trackpad

Background

For me this became a requirement as my trackpad started malfunctioning. But it can be a useful feature as well. When we connect a mouse we would not want trackpad to work. For eg. lets say you are playing counter strike with a mouse you definitely don't want trackpad to change your aim in game. So it would be better if you disable in build trackpad while mouse is connected. In this post I will show you how you can do this.



Disable Trackpad in OS X Lion and Above

For this you need to go to -
  • System Preferences > Accessibility > Mouse & Trackpad
Here you will find a checkbox saying "Ignore built-in trackpad when mouse or wireless trackpad is present". Click it and make sure you have checked it. Setting should take effect immediately.



Disable Trackpad in OS X Snow Leopard

Setting is the same here too. It's just at different path. So head to 
  • System Preferences > Universal Access > Mouse & Trackpad
Here again you will find the same checkbox. Check it and you should be good to go.






Sunday, 9 July 2017

How to install wine and run windows programs on your mac

Background

Sometimes it becomes necessary to install windows program on your Linux or mac machine. Like I mentioned in a post sometime back there may be some sites that require IE only -
In this post I will show you how to install wine on your mac. Wine is a very handy software that allows you to install and run windows programs in a windows like simulated environment.


Installing Wine on Mac

You need to have homebrew installed on your mac. If not please refer -
 Next Homebrew uses an extension called Homebrew Cask to install other programs. You can install the Cask extension by running following command -
  • brew tap caskroom/cask


Wine needs -
  • Java and 
  • XQuartz 
as dependencies to be already installed. I am assuming you already have Java installed on your machine and set it up in classpath. You can install  XQuartz with following command -
  • brew cask install xquartz


NOTE :  You can similarly install Java if you already done have it -
  • brew cask install java
 Once dependencies are done you can directly install wine with following command -
  • brew install wine


Also install winetricks -
  • brew install winetricks

 Use winetricks to set environment as windows 7 -
  • winetricks win7

Installing and running Windows program from wine

Go to the directory where you have downloaded your exec file and run -
  • wine installer.exe
where installer.exec is your exe file.

 You can find installed files in dir -
  • /Users/athakur/.wine/drive_c
You can then navigate to program files, find your installed program and run it -


 Once in the program directory you can simply run it as -
  • wine ioexplorer.exe


And you are done :)

Related Links

How to check if a Singly Linked List is a Palindrome or not

Background

This is another classic data structure interview question that fall into basic DS problems. You might have seen or known method to find if a String is palindrome or not. You can simply iterate on half of the String and check with reversed other half if it same.

Time Complexity : O(N)
Space Complexity : O(1)

It will be as simple as -

    public static boolean isPalindrome(String str) {
        if(str == null) {
            return false;
        }
        for(int i = 0; i< str.length()/2; i++) {
            if(!(str.charAt(i) == str.charAt(str.length() - i - 1))) {
                return false;
            }
        }
        return true;
    }

Test :
        System.out.println(isPalindrome("ABCDCBA"));
        System.out.println(isPalindrome("ABBA"));
        System.out.println(isPalindrome("ABCD"));
Output:
true
true
false

It can have a variant such that instead of a String you have a Linked List. Now if you have a double linked list it becomes very easy. You start from head and from the tails and keep comparing. Increment the header pointer and decrement the tail pointer in each iteration. Time complexity will be O(N) only.

However the question at hand is of Singly Linked List.

How to check if a Singly Linked List is a Palindrome or not

 

Method 1 : Using a String

 

Iterate over the Linked list and construct a String out of it and then check if that String is a Palindrome.Time complexity O(N) but space complexity is also O(N) since you are now creating a String.

Since interviewer asked you Linked List this is most definitely something he does not want. He could have asked a String palindrome itself if that was the case. But it never hurts to put it out what you are thinking and build upon your answer as you proceed.

 

Method 2 : Using a Stack

 

You can iterate over the Linked List put it's content in stack. Once iteration is over we can iterate over Linked List again and this time with each iteration compare Nodes content with Stacks popped out content. If it does not match it is not a palindrome.
This again has time complexity O(N) and space complexity O(N).

1) Traverse the given list from head to tail and push every visited node to stack.
2) Traverse the list again. For every visited node, pop a node from stack and compare data of popped node with currently visited node.
3) If all nodes matched, then return true, else false.

Code :

    public static boolean isPalindrome(ListNode<String> head) {
        boolean isPanindrome = true;

        Stack<String> stack = new Stack<>();
        ListNode<String> currentNode = head;

        while (currentNode != null) {
            stack.push(currentNode.getValue());
            currentNode = currentNode.getNext();
        }

        currentNode = head;
        while (currentNode != null) {
            if (!currentNode.getValue().equals(stack.pop())) {
                isPanindrome = false;
                break;
            }
            currentNode = currentNode.getNext();
        }
        return isPanindrome;
    }

I have also added it to my Data Structure github repo. Check isPalindrome() method in  https://github.com/aniket91/DataStructures/blob/master/src/com/osfg/questions/LinkedListPalindromeFinder.java 

 

Method 3 : Reversing the 2nd half of the Linked List

 

This is a better version and always one you should aim for. It provides O(N) time complexity and O(1) space complexity -

1) Get the middle of the linked list.
2) Reverse the second half of the linked list.
3) Check if the first half and second half are identical.
4) Construct the original linked list by reversing the second half again and attaching it back to the first half

4th point is optional and depends if you need original List back.

I have added it to my Data Structure github repo. Check isPalindrome2() method in  https://github.com/aniket91/DataStructures/blob/master/src/com/osfg/questions/LinkedListPalindromeFinder.java  

 

Related Links


How to display or hide line numbers in vi or vim text editor

Background

Line number come in very handy when you are working with any Text Editor. However if you take vi or vim editor then line numbers are hidden by default. In this post we will see how we can turn it on.


How to display or hide line numbers in vi or vim text editor

This post assumes you are a vim user and are aware of basic usage. Like for example when you need to save and quit data in vim you-
  • press escape followed by :wq
or if you want to exit without saving
  • :q!
 vi support a lot of commands to use and  options to be set by using colon (:)

To show line numbers in vi simple type below are pressing escape -
  • :set number OR
  • :set nu
 To hide it you can type -
  • :set nu! OR
  • set nonumber





This you need to do every time you launch into vi editor. To make it default edit your file at location ~/.vimrc and append following line at the end -

  • set number
NOTE : You can create this file if it does not exist already.

Now you will always get line numbers when you launch vim editor.




 Now that we have seen how to hide and display line numbers in vim editor lets see how we can jump to a particular line in vim -

How to jump to a particular line in vim

This is also fairly simple. Once you have launched vim you can simply move to any line number using following command -
  • : linenumber
Eg.
  • :6


 You can ever jump directly to your line number immediately as you open vim. To do that use following command while opening vim -
  • vi +linenumber filename
Eg.
  •  vi +6 test.txt
This should open your file and move to the linenumber you have provided.


General Info

vim provides a lot of configurable options to set. To see them all type following command -
  • :set all

To see everything that you have set so far you can type following command -
  • :set
For me it is as follows -



Related Links

Wednesday, 28 June 2017

How to access websites on your Mac that requires Internet Explorer

Background

There are certain websites that can be accessed from Internet Explorer only. This happens because of the websites compatibility with IE. But this will not work on your Mac laptop or Linux machine since you cannot run IE on it. At least not in traditional way - You can always install a software like Wine and then run your windows application in that simulated environment. But there is a much simpler way.

How to access websites on your Mac that requires Internet Explorer

I will take Safari browser in our Mac as an example. 
  • Open Safari browser and open preferences from menu bar at the top.
  • Once opened go to "Advanced Tab"
  • In "Advanced Tab" select the "Show Develop menu in menu bar" check box.

  • Once done you should be able to see "Develop" menu in menubar on top. 
  • Under "Develop" menu you can select "User Agent" and then select the user agent you want. For eg - "Internet Explorer 7"

  • Once you select that your IE compatible page should load fine.

 On other operating systems and browser  - Linux/Chrome/Firefox

Above approach was specific to Safari but the solution remains same - You need to change the user agent. So you have plugins to do so -


Similar you can find a similar plugin in chrome store. 

Manual way

    FIREFOX 4.0 :  In Firefox type in the URL Address: about:config. A webpage will appear saying a warning about the use of the Config. Click on the button about you being careful. In the search bar in the Config type agent and look for the variable general.useragent.override. Double click on it and overwrite the value it has with one of the following (For the default leave the value EMPTY):

    IE6 - Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
    IE7 - Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)
    IE8 - Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)


    CHROME :  Chrome has an about page to CHECK if you have changed your User Agent about: and other options like about:labs, about:memory, about:hang, about:plugins and many others that depending on your version they could be available or not. But for the question at hand this option is not yet in any of the about pages i have found. To have it manually in chrome you need to start chrome with the option user-agent. For example google-chrome --user-agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" which will open Chrome like it were IE6. The IE User Agents are from the Firefox option above.

    OPERA : In Opera type in the URL Address: about:config. A list will appear and a search address in the upper part of the list. Type in the search address user agent. The option for User Agen will appear below the search address. Click on it and depending on the Browser you want you have several options that change depending on version. For example:

    1 - Opera (this is the default user agent string used by Opera)
    2 - Mozilla (With the Opera String in it)
    3 - Internet Explorer (With the Opera String in it)
    4 - Mozilla (Without the Opera String in it. 100% Mozilla)
    5 - Internet Explorer (Without the Opera String in it. 100% IE)


    But this values could change so you would need to test each one to know what User Agent value it has.

Related Links

Saturday, 17 June 2017

Make a bootable flash drive from an ISO image on Ubuntu

Background

There are many times you download an ISO file from internet and want to install it on your machine. For eg. Windows or Ubuntu image. What you really wish is flash it iso image into a bootable drive like USB drive or a CD drive and install it from there on your machine.

 Make a bootable flash drive from an ISO image on Ubuntu

You have following options -
  1. Etcher- is a free and open-source image burner with support for Windows, OS X and GNU/Linux.
  2. Easy2Boot- Flexible and configurable USB drive multiboot solution which also supports UEFI booting.
  3. LiveUSB Install- is a free software for GNU/Linux and Windows. With LiveUSB Install you can effortlessly install various Linux distros.
  4. Multisystem- is an awesome tool created by LiveUSB.info that works similar to our Windows based MultiBootISOs USB creator.
  5. WinUSB - is a simple tool that enable you to create your own usb stick windows installer from an iso image or a real DVD.
  6. Unetbootin - UNetbootin allows you to create bootable Live USB drives for Ubuntu and other Linux distributions without burning a CD.
 Let's see some of the options -

Unetbootin

To install this run following command in your terminal -
  • sudo apt-get install unetbootin


Once installed you can  open the app. Now you can either select one of the given linux distros (those will get downloaded automatically) or  provide it an iso file from local machine.



WinUsb

To install winusb run following commands on your linux terminal -
  • sudo add-apt-repository ppa:colingille/freshlight
  • sudo apt-get update
  • sudo apt-get install winusb
Once installed you can open up the app select iso file and target usb and start creating bootable usb drive for windows.



NOTE : If you are looking for rufus then it is for Windows only. You cannot use it on your Linux machine.

t> UA-39527780-1 back to top