Monday, October 22, 2012

ORACLE Generate Dynamic Data Insert GEN_INSERT_STATEMENT function

Some time back, I have a requirement to pull the data on some server and load into my local Db. The best decoupled way to do that is create insert scripts on server and run them back in local(sure, there will be some key constraints and checks, which I am planning to disable and import data).

I googled for the solution, I just got the solution from http://mahmoudoracle.blogspot.in/2012/07/create-insert-statement-for-table-data.html

Just for quick copy paste, I copied the proc from there and keeping it here.


CREATE OR REPLACE FUNCTION GEN_INSERT_STATEMENT (IN_TABLE_NAME VARCHAR2)  
   RETURN VARCHAR2  
 IS  
   LC$COLS_SELECT     VARCHAR2 (4000);  
   LC$COLS_VALUES     VARCHAR2 (4000);  
   LC$COLOUMN      VARCHAR2 (200);  
   CURSOR LCUR$TAB_COLUMNS (IN_TABLE_NAME VARCHAR2)  
   IS  
     SELECT COLUMN_NAME, DATA_TYPE, COLUMN_ID  
      FROM USER_TAB_COLS  
      WHERE TABLE_NAME = IN_TABLE_NAME  
    ORDER BY COLUMN_ID;  
 BEGIN  
   FOR LREC$TAB_COLUMNS IN LCUR$TAB_COLUMNS (UPPER (IN_TABLE_NAME))  
   LOOP  
    LC$COLS_SELECT :=  
       LC$COLS_SELECT  
      || CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END  
      || LREC$TAB_COLUMNS.COLUMN_NAME;  
    IF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'CHAR') > 0  
    THEN  
      LC$COLOUMN :=  
       '''''''''||' || LREC$TAB_COLUMNS.COLUMN_NAME || '||''''''''';  
    ELSIF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'DATE') > 0  
    THEN  
      LC$COLOUMN :=  
       '''TO_DATE(''''''||TO_CHAR(' || LREC$TAB_COLUMNS.COLUMN_NAME  
       || ',''mm/dd/yyyy hh24:mi'')||'''''',''''mm/dd/yyyy hh24:mi'''')''';  
    ELSE  
      LC$COLOUMN := LREC$TAB_COLUMNS.COLUMN_NAME;  
    END IF;  
    LC$COLS_VALUES :=  
       LC$COLS_VALUES  
      || CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END  
      || '''||DECODE('  
      || LREC$TAB_COLUMNS.COLUMN_NAME  
      || ',NULL,''NULL'','  
      || LC$COLOUMN  
      || ')||''';  
   END LOOP;  
   RETURN  'SELECT ''INSERT INTO '  
      || IN_TABLE_NAME  
      || ' ('  
      || LC$COLS_SELECT  
      || ') VALUES ('  
      || LC$COLS_VALUES  
      || ');'' FROM '  
      || IN_TABLE_NAME  
      || ';';  
 END;  




Let's Now run function for table EMP
 SELECT GEN_INSERT_STATEMENT('EMP') FROM DUAL;  

The output is select statement that we should run it to get insert statement of data.
 SELECT 'INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES ('  
     || DECODE (EMPNO, NULL, 'NULL', EMPNO)  
     || ','  
     || DECODE (ENAME, NULL, 'NULL', '''' || ENAME || '''')  
     || ','  
     || DECODE (JOB, NULL, 'NULL', '''' || JOB || '''')  
     || ','  
     || DECODE (MGR, NULL, 'NULL', MGR)  
     || ','  
     || DECODE (  
        HIREDATE,  
        NULL, 'NULL',  
         'TO_DATE('''  
        || TO_CHAR (HIREDATE, 'mm/dd/yyyy hh24:mi')  
        || ''',''mm/dd/yyyy hh24:mi'')')  
     || ','  
     || DECODE (SAL, NULL, 'NULL', SAL)  
     || ','  
     || DECODE (COMM, NULL, 'NULL', COMM)  
     || ','  
     || DECODE (DEPTNO, NULL, 'NULL', DEPTNO)  
     || ');'  
  FROM EMP;  

If we run the previous select statement it will generate inert statement for data existed in table EMP.
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7369,'SMITH','CLERK',7902,TO_DATE('12/17/1980 00:00','mm/dd/yyyy hh24:mi'),800,NULL,20);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7499,'ALLEN','SALESMAN',7698,TO_DATE('02/20/1981 00:00','mm/dd/yyyy hh24:mi'),1600,300,30);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7521,'WARD','SALESMAN',7698,TO_DATE('02/22/1981 00:00','mm/dd/yyyy hh24:mi'),1250,500,30);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7566,'JONES','MANAGER',7839,TO_DATE('04/02/1981 00:00','mm/dd/yyyy hh24:mi'),2975,NULL,20);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7654,'MARTIN','SALESMAN',7698,TO_DATE('09/28/1981 00:00','mm/dd/yyyy hh24:mi'),1250,1400,30);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7698,'BLAKE','MANAGER',7839,TO_DATE('05/01/1981 00:00','mm/dd/yyyy hh24:mi'),2850,NULL,30);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7782,'CLARK','MANAGER',7839,TO_DATE('06/09/1981 00:00','mm/dd/yyyy hh24:mi'),2450,NULL,10);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7788,'SCOTT','ANALYST',7566,TO_DATE('04/19/1987 00:00','mm/dd/yyyy hh24:mi'),3000,NULL,20);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7839,'KING','PRESIDENT',NULL,TO_DATE('11/17/1981 00:00','mm/dd/yyyy hh24:mi'),5000,NULL,10);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7844,'TURNER','SALESMAN',7698,TO_DATE('09/08/1981 00:00','mm/dd/yyyy hh24:mi'),1500,0,30);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7876,'ADAMS','CLERK',7788,TO_DATE('05/23/1987 00:00','mm/dd/yyyy hh24:mi'),1100,NULL,20);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7900,'JAMES','CLERK',7698,TO_DATE('12/03/1981 00:00','mm/dd/yyyy hh24:mi'),950,NULL,30);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7902,'FORD','ANALYST',7566,TO_DATE('12/03/1981 00:00','mm/dd/yyyy hh24:mi'),3000,NULL,20);  
 INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (7934,'MILLER','CLERK',7782,TO_DATE('01/23/1982 00:00','mm/dd/yyyy hh24:mi'),1300,NULL,10);  




Made few changes to above GEN_INSERT_STATEMENT to give insert script for table which have too many columns..




CREATE OR REPLACE FUNCTION GEN_INSERT_STATEMENT (IN_TABLE_NAME VARCHAR2)  
   RETURN CLOB
 IS
   LC$COLS_SELECT     CLOB;
   LC$COLS_VALUES     CLOB;
   LC$COLOUMN      CLOB;

   CURSOR LCUR$TAB_COLUMNS (IN_TABLE_NAME VARCHAR2)
   IS
     SELECT COLUMN_NAME, DATA_TYPE, COLUMN_ID
      FROM USER_TAB_COLS
      WHERE TABLE_NAME = IN_TABLE_NAME
    ORDER BY COLUMN_ID;

 BEGIN

   FOR LREC$TAB_COLUMNS IN LCUR$TAB_COLUMNS (UPPER (IN_TABLE_NAME))
   LOOP

   LC$COLS_SELECT :=
       LC$COLS_SELECT
      || CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END
      || LREC$TAB_COLUMNS.COLUMN_NAME;

    IF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'CHAR') > 0
    THEN

      LC$COLOUMN :=
       '''''''''||' || LREC$TAB_COLUMNS.COLUMN_NAME || '||''''''''';

    ELSIF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'DATE') > 0
    THEN

      LC$COLOUMN :=
       '''TO_DATE(''''''||TO_CHAR(' || LREC$TAB_COLUMNS.COLUMN_NAME
       || ',''mm/dd/yyyy hh24:mi'')||'''''',''''mm/dd/yyyy hh24:mi'''')''';

    ELSE

      LC$COLOUMN := LREC$TAB_COLUMNS.COLUMN_NAME;

    END IF;

    LC$COLS_VALUES :=
       LC$COLS_VALUES
      || CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END
      || '''||DECODE('
      || LREC$TAB_COLUMNS.COLUMN_NAME
      || ',NULL,''NULL'','
      || LC$COLOUMN
      || ')||''';

   END LOOP;

   RETURN  'SELECT ''INSERT INTO '
      || IN_TABLE_NAME
      || ' ('
      || LC$COLS_SELECT
      || ') VALUES ('
      || LC$COLS_VALUES
      || ');'' FROM '
      || IN_TABLE_NAME
      || ';';

 END;


DECLARE
   IN_TABLE_NAME VARCHAR2(100) := 'TABLE_NAME_HERE';
   LC$COLS_SELECT     CLOB;
   LC$COLS_VALUES     CLOB;
   LC$COLOUMN      CLOB;
   CURSOR LCUR$TAB_COLUMNS (IN_TABLE_NAME VARCHAR2)
   IS
     SELECT COLUMN_NAME, DATA_TYPE, COLUMN_ID
      FROM ALL_TAB_COLS
      WHERE TABLE_NAME = IN_TABLE_NAME
    ORDER BY COLUMN_ID;
 BEGIN
   FOR LREC$TAB_COLUMNS IN LCUR$TAB_COLUMNS (UPPER (IN_TABLE_NAME))
   LOOP
   LC$COLS_SELECT :=
       LC$COLS_SELECT
      || CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END
      || LREC$TAB_COLUMNS.COLUMN_NAME;
    IF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'CHAR') > 0
    THEN
      LC$COLOUMN :=
       '''''''''||' || LREC$TAB_COLUMNS.COLUMN_NAME || '||''''''''';
    ELSIF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'DATE') > 0
    THEN
      LC$COLOUMN :=
       '''TO_DATE(''''''||TO_CHAR(' || LREC$TAB_COLUMNS.COLUMN_NAME
       || ',''mm/dd/yyyy hh24:mi'')||'''''',''''mm/dd/yyyy hh24:mi'''')''';
    ELSE
      LC$COLOUMN := LREC$TAB_COLUMNS.COLUMN_NAME;
    END IF;
    LC$COLS_VALUES :=
       LC$COLS_VALUES
      || CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END
      || '''||DECODE('
      || LREC$TAB_COLUMNS.COLUMN_NAME
      || ',NULL,''NULL'','
      || LC$COLOUMN
      || ')||''';
   END LOOP;
   dbms_output.put_line('SELECT ''INSERT INTO '
      || IN_TABLE_NAME
      || ' ('
      || LC$COLS_SELECT
      || ') VALUES ('
      || LC$COLS_VALUES
      || ');'' FROM '
      || IN_TABLE_NAME
      || ';');
 END;
/







Thursday, October 18, 2012

Ref: http://mugurel.sumanariu.ro/windows/vista-and-win-7-openvpn-route-problem/

How to fix Open VPN issue: Route addition via IPAPI failed

Please refer above link.


OR

add the following to the end of the configuration (ovpn) file:
--------------------------------------------------------------------------------------------------------

route-method exe
route-delay 2

--------------------------------------------------------------------------------------------------------

Friday, October 12, 2012

Learning How to Learn

Ref : http://java.dzone.com/articles/learning-how-learn


I’d like to talk about three aspects of knowledge: span, depth and connections between the disciplines. I’ve come up with a good metaphor to bring these aspects together, and it looks very to the point. Though, I don’t like metaphors that much, as they’re misleading quite often.
Basically, my metaphor stems from another metaphor according to which people can be broken down into two types. The first type is someone who likes to go over many things in their learning and research. The people of the second type pick just one or two disciplines and dig into them. The first type are foxes, the second type are hedgehogs.
To me, learning looks very much like a geological field research. Imagine that you’re facing a new mysterious continent. You know nothing about it. Of course, you can see mountains, forests, rivers but you have no idea of what’s in there. You don’t know what’s over the horizon, is there a sea, how cold this continent is on the north and what’s the temperature in the south.

The map

So, you start putting the map together. You send expeditions everywhere and you sketch the local maps. Then you drill surface holes to identify the soul texture and composition. Then you discover oil, gold, diamonds, and you start mining.
Learning follows exactly the same scenario. Let’s say you’re studying maths. In the beginning you know very little about it.  Okay, you count to 10, and you see how three red balls are different from five blue balls.  Step by step you’re discovering some new territories. You learn multiplication tables, and you’re amazed as you get to know the real numbers, or as you find out that it’s impossible to divide by zero.  You briefly touch upon differential calculus, and for some unknown reason you learn how to take integrals. By the time you’re 16, you’ve got the map of the nearby territories on your hands, but most likely you have no idea of the set theory, topology and functional analysis. It’s very unlikely that you’ve acquired in-depth knowledge in any of the fields in mathematics. Just scooped and scratched the tidbits off of the surface.
High school doesn’t provide solid knowledge. You only sketch your map at school as you get ready to drill the surface holes.

Connections

Choosing your field can be easy … or difficult. One way or another, there you are at a university. Your teachers rightly assume that you know nothing. The truth is: most of the teachers don’t really care where you start your drilling. They deliver their lectures in a boring or in a fun way, and they rarely put any emphasis on the connections between disciplines. Take physicists: they grab differential calculus and use it to solve their problems. No one cares to trace mathematical analysis to physics and to check if it can be used there. Any given scientific field is an island on your map. For some reason, the common belief states that it’s your job to build bridges between the islands – or at least to set up a ferry service.
Your map abounds in the white patches of seas and oceans that can hardly be drilled, except for the shelf areas.
The islands of knowledge build up clusters as they become one integral whole for you, and instead of the bridge an archipelago emerges. That’s the time when you lay down the foundation for cross-field connections. As these connections take shape, the archipelago transforms into a solid land, good enough to host a highway.  For example, you’ve got this distinct knowledge of what derivatives are, and how they can be applied to mechanics. Bang, there you go, now you definitely see a connection between the motion of bodies and differential calculus.
Why differential calculus is a standalone subject in the school curriculum? Why no one ever says how it can be applied to solving practical tasks?
The contemporary education, at least in this country, does help if you’re set to discover and develop the new islands… but not the new continents. Too little attention is paid to the connections, as well as to the paths and the logic of discoveries.  That’s too bad.

Foxes and Hedgehogs

Back to knowledge span vs. knowledge depth. When you set out to some new field, it’s better to put together a map first, that is, to acquire a span of knowledge. That’s the only way to be able to dig deep into the subject later and identify the spots for drilling.
For example, you learn programming. It’d be stupid to dive straight into the theoretical depths of the artificial intellect or the lambda calculus. It’s equally stupid to rush into some programming language. At the entry level, you need to find out the basics: how programming evolved, what is it for, which branches are available, what are their specifics. Next, it’s about the paradigms, types of programming languages, the platforms, how the platforms relate to each other, what are their development trends. Again, it’s about sketching a map of the continent called “software development” and understanding where to get started with this map. If you’re interested in web development – welcome to the world of JavaScript, functional programming, scripting and markup languages. If you’re more into game development, go ahead and look into AI, strictly typified languages and algorithms. Of course, it doesn’t mean that you can skip all the rest, but that’s the way you identify the spots for deep drilling.
You must be a fox first, to be able to shape-shift into a hedgehog later. That’s the problem of today’s world: it’s much easier to end up being a fox forever, than to become a hedgehog. I feel it myself; it’s a lot harder to get deep down into your chosen field of knowledge.  You always want to read just one more blog post, check Twitter, take a look at this interesting article or book.  When all the world’s information is at your fingertips, it’s soo tempting to be a fox.  

Deep drilling

The spot is selected, and the drill sharpened. So, how to drill now? Watch out for interesting soil layers and horizons. If you reach those layers, you’d never roll back. Beware the space in between the layers – that’s where the rocks might crumble. You dig deep into the subject, you read, you do something, and there’s a moment when things fall into place. Congrats! You’ve found the gold.
There’s one more good metaphor, I’ve picked it up in some book. In the beginning you find yourself in the dark room, and you’re using touch and feel to discover what’s in this room. Then there’s an instant, when the lights turn on, and you see very clearly what is where. The same is going on in your head. The light is suddenly on, and all the standalone concepts get precisely aligned. You will never forget that moment, and this clear alignment will always be there. The lights will be on at all times. The overhead lights might dim with time, but they won’t go out completely.
At times it’s very hard to make yourself keep on drilling. When you see that nothing changes, and you’ve been pecking this subject for several months with no evident progress, you just want to give up everything and get away to some sunny beach. What are you supposed to do in this case? The answer is the same – keep on doing it. If you give up once, give up twice – you’d lose your self-confidence, that’s it. You’d obsess over the thought that you’re good for nothing and get stuck at your current layer forever. You have to keep on drilling. You have to get to the first precious layer and experience the “aha!” moment. You have to turn on the lights to see what’s in the room.
What’s the difference between brilliant programmers and average programmers? It might well be about just one thing: with brilliant programmers, this faith is there all along. They just believe they can’t be anything else but brilliant programmers, whereas average programmers never conjure such things and give up on the drilling eventually. The power of faith and self-confidence can work wonders.
What if you don’t like the drilling location that you’ve previously selected? You have to get busy with something else then. If you take no delight in the studies, if you unconsciously register the count of pages in a new book the moment you open it – this subject or this discipline is not for you. Go over your map one more time and find another location. Maybe you’d get interested in UX, or automation, or marketing. With one or two trial drillings you will locate the spots worth putting your effort into.

Summary

So, how we learn? What should we do to make the learning process more efficient?
  1. Turn on “the fox mode” and sketch your map. Identify some starting points for a more in-depth look into the subject.
  2. Try to make sense of the connections between disciplines and order the studies logically. It’s quite easy on the high-level.
  3. Turn on “the hedgehog mode” and dig deep. You’ll have to interrupt the focused digging though to jump to the related subjects, otherwise you won’t be able to reach the even deeper layers.
A great teacher would disclose his map to the students, guiding their way and showing implicit connections between the disciplines. Students will never lose their way if they have such a map.
Unfortunately, I haven’t come across a teacher who would have done that to his students. So I have to break through the jungle all by myself, working with my machete and carrying my torch, as I put new territories on the map. Hopefully, my children will have better luck.

List all IP addresses connected to your Server

Ref: http://www.techgig.com/skillpage/Java/List-all-IP-addresses-connected-to-your-Server/1063

Below is an Unix command to list all the IP addresses connected to your server on port 80.


netstat -tn 2>/dev/null | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head





Output – Total connections by IP, from highest to lowest.


 97 114.198.236.100
 56 67.166.157.194
 44 170.248.43.76
 38 141.0.9.20
 37 49.248.0.2
 37 153.100.131.12
 31 223.62.169.73
 30 65.248.100.253
 29 203.112.82.128
 29 182.19.66.187





Note

This command is useful to detect if your server is under attack, and null route those IPs. Read this null route attacker IP story.



Let break above lengthy command into pieces :

1. netstat -tn 2>/dev/null



Uses netstat to list all network connections, ins and outs.


  1. -n – Display numeric only, don’t resolve into name.

  2. -t – Display only TCP connections.


Output


#Examples - 7 connections
 tcp 0 0 64.91.*.*:80 114.198.236.100:12763 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 175.136.226.244:51950 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 175.136.226.244:51951 TIME_WAIT 
 tcp 0 0 64.91.*.*:23 202.127.210.2:14517 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 149.238.193.121:65268 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 114.198.236.100:44088 ESTABLISHED
 tcp 0 0 64.91.*.*:80 175.136.226.244:51952 TIME_WAIT





2>/dev/null

Redirect all unwanted output to /dev/null, a special place to absorb all output and clear it.


2. grep :80



Only display the IP address that connected to server on port 80.


tcp 0 0 64.91.*.*:80 114.198.236.100:12763 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 175.136.226.244:51950 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 175.136.226.244:51951 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 149.238.193.121:65268 TIME_WAIT 
 tcp 0 0 64.91.*.*:80 114.198.236.100:44088 ESTABLISHED
 tcp 0 0 64.91.*.*:80 175.136.226.244:51952 TIME_WAIT




3. awk ‘{print $5}’



Uses awk to display the 5th field only.


114.198.236.100:12763 
 175.136.226.244:51950
 175.136.226.244:51951
 149.238.193.121:65268
 114.198.236.100:44088
 175.136.226.244:51952




4. cut -d: -f1



Uses cut to extract the content.


  1. -d – Character immediately following the -d option is use as delimiter, default is tab.

  2. -f – Specifies a field list, separated by a delimiter.


114.198.236.100
 175.136.226.244
 175.136.226.244
 149.238.193.121
 114.198.236.100
 175.136.226.244




5. sort | uniq -c | sort -nr



Sort the list, group it and sort it again in reverse order.


sort


114.198.236.100
 114.198.236.100
 149.238.193.121
 175.136.226.244
 175.136.226.244
 175.136.226.244





uniq -c – Group it.


2 114.198.236.100
 1 149.238.193.121
 3 175.136.226.244





sort -nr – sort by numeric, and reverse order (highest display first)


3 175.136.226.244
 2 114.198.236.100
 1 149.238.193.121





Done.

6. head



This is optional, to display the first 10 result. 

References



  1. /dev/null

  2. Netstat

  3. AWK

  4. Cut

  5. Uniq

  6. Sort

Tuesday, October 9, 2012

Things Great Engineers (almost) never say

Ref: http://java.dzone.com/articles/things-great-engineers-almost

  • “I’ve used _____ but I have no idea how it works” – Great engineers gained their skills through probing and curiosity.  They go ‘under the hood’ of the products they use just to understand how things work, even if that information will never be very useful to them.  It is unclear whether this need to dig deeper is a choice or a compulsion, but it seems that it is a trait of the best talent.
  • “______ works, I just don’t know how to explain it”
  • “I will need ______ (tool/condition) to complete this task”
  • “I’ve learned all I want/will ever need to know about ________ “
  • “There is no solution”
  • “I hate programming” -
  • “I’m an expert in _____”
  • “I don’t understand the business”
  • “I don’t pay particular attention to industry trends”