<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
	<title>Tech Mo</title>
	<link>https://tech.wodemo.com/</link>
        <item>
        <title><![CDATA[Read-Only Mac HFS+ driver for Windows 8.1 and 10]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/380370]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Sun, 27 Dec 2015 20:16:16 +0800]]></pubDate>
        <description><![CDATA[Read-Only HFS+ driver from Boot Camp 6.0 (Build 6237). Apple_HFS_Read_Only_Driver_v6.0.1.0.zip]]></description>
    </item>
        <item>
        <title><![CDATA[Cello: Higher level programming in C]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/323358]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Sat, 27 Dec 2014 22:38:20 +0800]]></pubDate>
        <description><![CDATA[[Cello](http://libcello.org) is a library for C

It provides some features that commonly found in high level programming languages, for example dynamic type:

```
var int_item = $(Int, 5);
var float_item = $(Real, 2.4);
var string_item = $(String, &quot;Hello&quot;);

```

It uses a &quot;var&quot; structure where it is able to hold different types of values

The way of defining a universal structure to describe different types of values is commonly used in the core engines of dynamic type programming languages like PHP.

Here is how Zend - the PHP Core engine - is doing this universal type structure:
```
typedef struct _zval_struct zval;

typedef union _zvalue_value {
    long lval;                  /* long value */
    double dval;                /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;              /* hash table value */
    zend_object_value obj;
} zvalue_value;


struct _zval_struct {
    /* Variable information */
    zvalue_value value;     /* value */
    zend_uint refcount;
    zend_uchar type;    /* active type */
    zend_uchar is_ref;
};

```

Now the Cello did something similar and much more to get the C programming being more efficient on writing and maybe reading as well



### The list of features quoted from http://libcello.org

- Interfaces allow for structured design
- Duck Typing allows for generic functions
- Exceptions control error handling
- Constructors/Destructors aid memory management
- Syntactic Sugar increases readability
- C Library means excellent performance and integration


### Examples

```
/* Example libCello Program */

#include &quot;Cello.h&quot;

int main(int argc, char** argv) {

  /* Stack objects are created using &quot;$&quot; */
  var int_item = $(Int, 5);
  var float_item = $(Real, 2.4);
  var string_item = $(String, &quot;Hello&quot;);

  /* Heap objects are created using &quot;new&quot; */
  var items = new(List, int_item, float_item, string_item);

  /* Collections can be looped over */
  foreach (item in items) {
    /* Types are also objects */
    var type = type_of(item);
    print(&quot;Object %$ has type %$\n&quot;, item, type);
  }

  /* Heap objects destroyed with &quot;delete&quot; */
  delete(items); 
}
```


```
/* Another Example Cello Program */

#include &quot;Cello.h&quot;

int main(int argc, char** argv) {

  /* Tables require &quot;Eq&quot; and &quot;Hash&quot; on key type */
  var prices = new(Table, String, Int);
  put(prices, $(String, &quot;Apple&quot;),  $(Int, 12)); 
  put(prices, $(String, &quot;Banana&quot;), $(Int,  6)); 
  put(prices, $(String, &quot;Pear&quot;),   $(Int, 55));

  /* Tables also supports iteration */
  foreach (key in prices) {
    var price = get(prices, key);
    print(&quot;Price of %$ is %$\n&quot;, key, price);
  }

  /* &quot;with&quot; automatically closes file at end of scope. */
  with (file in open($(File, NULL), &quot;prices.bin&quot;, &quot;wb&quot;)) {

    /* First class function object */
    lambda(write_pair, args) {

      /* Run time type-checking with &quot;cast&quot; */
      var key = cast(at(args, 0), String);
      var value = cast(get(prices, key), Int);

      try {
        print_to(file, 0, &quot;%$ :: %$\n&quot;, key, value);
      } catch (e in IOError) {
        println(&quot;Could not write to file - got %$&quot;, e);
      }

      return None;
    };

    /* Higher order functions */
    map(prices, write_pair);
  }

  delete(prices);
}
```]]></description>
    </item>
        <item>
        <title><![CDATA[What should viewport be set]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/320598]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Sat, 06 Dec 2014 17:54:37 +0800]]></pubDate>
        <description><![CDATA[In most cases, the viewport should be set as:

```
&lt;meta name=viewport content=&quot;width=device-width, initial-scale=1&quot;&gt;
```


Never use minimum-scale, maximum-scale and user-scalable, unless you really need them. By using them the users may not able to zoom the page in the way they want

And never set initial-scale to other values than 1, unless you really know what are you doing here. Below are the screenshots captured from a mobile phone, which will explain why you should use 1 in most cases

### initial-scale=1. viewpoint-1.0.png### initial-scale=0.2. viewpoint-0.2.png]]></description>
    </item>
        <item>
        <title><![CDATA[Logging Interfaces of PHP Frameworks]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/317237]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Fri, 14 Nov 2014 01:21:55 +0800]]></pubDate>
        <description><![CDATA[## Conclusion First

The frameworks / libs described in this article are Zend Framework, Monolog, Apache's log4php, Slim and Yii

They all support the major logging concepts: Level, Writer and Formatter

 
### Level

All of them support levels defined in http://tools.ietf.org/html/rfc5424 fully or partly

In RFC 5424 we have eight levels: debug, info, notice, warning, error, critical, alert, emergency

Zend Framework supports custom levels. But IMO custom levels are evil as they create undocumented things. Nobody knows what is &quot;FOO&quot;


### Writer (Yii calls it Routing)

Write tells the logger where the logs should be written to: Local files, syslog, database(Like MySQL), stdout, browse console, NewRelic

Monolog(used by Laravel) seems has the best coverage of writers.


### Formatter (Yii has this thing Context which is similar to Formatter)

If you want to add the pid as part of the log line, or if you want to write the log as JSON, formatter is your friend
   

## Interfaces and Examples

### Zend Framework
http://framework.zend.com/manual/1.12/en/zend.log.html

```
$logger = new Zend_Log();

$writer = new Zend_Log_Writer_Stream('php://output');
//Or
//$writer = new Zend_Log_Writer_Stream('/path/to/logfile');
//Or
//$db = Zend_Db::factory('PDO_MYSQL', $params)
//$columnMapping = array('lvl' =&gt; 'priority', 'msg' =&gt; 'message'); 
//$writer = new Zend_Log_Writer_Db($db, 'log_table_name', $columnMapping)
//Or 
//$writer = new Zend_Log_Writer_Firebug();
//Or
//$writer = new Zend_Log_Writer_Syslog(array('application' =&gt; 'FooBar'));


$logger-&gt;addWriter($writer);
$logger-&gt;log('Informational message', Zend_Log::INFO);
$logger-&gt;log('Informational message', Zend_Log::INFO);
$logger-&gt;info('Informational message');
$logger-&gt;log('Emergency message', Zend_Log::EMERG);
$logger-&gt;emerg('Emergency message');

//By default log line includes timestamp, message, priority, and priorityName. If you want to add more information in the log line:
$logger-&gt;setEventItem('pid', getmypid());

//You can also customize the log line by setting formatter to the writter
$format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
$formatter = new Zend_Log_Formatter_Simple($format);
$writer-&gt;setFormatter($formatter);

```

### Laravel
http://laravel.com/docs/4.2/errors

```
//By default it writes to app/storage/logs/laravel.log
Log::info('This is some useful information.');
Log::warning('Something could be going wrong.');
Log::error('Something is really going wrong.');


//Laravel is using https://github.com/Seldaek/monolog as its underlying logging lib. So you can get the power of monolog by accessing it directly:
$log = Log::getMonolog();

// create a log channel
$log = new Logger('name');
$log-&gt;pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

// add records to the log
$log-&gt;addWarning('Foo');
$log-&gt;addError('Bar');
```

### Log4php
http://logging.apache.org/log4php/

```
// Insert the path where you unpacked log4php
include('log4php/Logger.php');
 
// Tell log4php to use our configuration file.
Logger::configure('config.xml');
 
// Fetch a logger, it will inherit settings from the root logger
$log = Logger::getLogger('myLogger');
 
// Start logging
$log-&gt;trace(&quot;My first message.&quot;);   // Not logged because TRACE &lt; WARN
$log-&gt;debug(&quot;My second message.&quot;);  // Not logged because DEBUG &lt; WARN
$log-&gt;info(&quot;My third message.&quot;);    // Not logged because INFO &lt; WARN
$log-&gt;warn(&quot;My fourth message.&quot;);   // Logged because WARN &gt;= WARN
$log-&gt;error(&quot;My fifth message.&quot;);   // Logged because ERROR &gt;= WARN
$log-&gt;fatal(&quot;My sixth message.&quot;);   // Logged because FATAL &gt;= WARN
```

### Yii
http://www.yiiframework.com/doc/guide/1.1/en/topics.logging

```
Yii::log($message, $level, $category);
```

### Slim
http://docs.slimframework.com/#Logging-Overview

```
//Enable logging
$app-&gt;log-&gt;setEnabled(true);
$app-&gt;log-&gt;setLevel(\Slim\Log::WARN);

$app-&gt;log-&gt;debug(mixed $object);
$app-&gt;log-&gt;info(mixed $object);
$app-&gt;log-&gt;notice(mixed $object);
$app-&gt;log-&gt;warning(mixed $object);
$app-&gt;log-&gt;error(mixed $object);
$app-&gt;log-&gt;critical(mixed $object);
$app-&gt;log-&gt;alert(mixed $object);
$app-&gt;log-&gt;emergency(mixed $object);
```]]></description>
    </item>
        <item>
        <title><![CDATA[PanGu Team released the Jailbreak for iOS8]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/314174]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Wed, 22 Oct 2014 20:08:58 +0800]]></pubDate>
        <description><![CDATA[The Pangu team has released a jailbreak for iOS 8 to iOS 8.1. This is the first jailbreak release for iOS8

This release does not include the Cydia. Pangu claims that Cydia and other plugins relying on Substrate is not compatible with iOS8

They also said that strictly speaking, this release is for jailbreak developers


Twitter: https://twitter.com/PanguTeam
Website (Chinese): http://pangu.io/
Website (English): http://en.pangu.io/
Weibo: http://weibo.com/panguteam. jailbreak.png]]></description>
    </item>
        <item>
        <title><![CDATA[What does Taobao mean?]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/314019]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Tue, 21 Oct 2014 14:25:38 +0800]]></pubDate>
        <description><![CDATA[In Chinese, Taobao(淘宝) means finding something good, in which the Tao(淘) means finding / looking for, and Bao(宝) means something good / valuable

Taobao.com is the latest online shopping marketplace in China. You probably already know that as Alibaba, who owns the Taobao, had the latest IPO ever in the world 2 months ago

The U.S. equivalent of Taobao.com is Ebay.com. The equivalent of Alipay is Paypal]]></description>
    </item>
        <item>
        <title><![CDATA[PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from '/path/to/file' : failed to load external entity "/path/to/file"]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/312021]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Wed, 08 Oct 2014 16:48:17 +0800]]></pubDate>
        <description><![CDATA[All you need to do is:

add

libxml_disable_entity_loader(false);

before

new SoapClient

Check this out for more details]]></description>
    </item>
        <item>
        <title><![CDATA[Hacker News now has the API]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/311932]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Wed, 08 Oct 2014 02:44:08 +0800]]></pubDate>
        <description><![CDATA[The purpose of releasing this API, according to this: http://blog.ycombinator.com/hacker-news-api, is that they are going to publish a new look of the hack news website. And before doing that they want all the scrappers of the current web pages have the time to convert to API-based data collecting

Here are the cURL examples of how the hacker news APIs work


## To get a list of top stories

$ curl 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty'
[ 8422599, 8422087, 8422581, 8422408, 8422051, 8421607, 8421656, 8420274, 8422864, 8420902, 8421518, 8421594, 8421866, 8421623, 8421807, 8420309, 8421147, 8421937, 8422094, 8421862, 8421263, 8421013, 8421466, 8419658, 8421238, 8421562, 8421790, 8421684, 8421375, 8419222, 8416393, 8419702, 8417062, 8421445, 8416693, 8421088, 8418836, 8419628, 8420918, 8420417, 8422928, 8421493, 8422278, 8422282, 8419807, 8415912, 8419984, 8422891, 8415647, 8420013, 8417343, 8419801, 8419803, 8422680, 8422592, 8420698, 8418865, 8419734, 8420199, 8421295, 8419210, 8418677, 8416455, 8421782, 8418588, 8421468, 8419867, 8420948, 8422750, 8419794, 8422490, 8420292, 8421302, 8411638, 8422690, 8422058, 8421021, 8415634, 8417178, 8422243, 8420597, 8421469, 8421056, 8422415, 8418020, 8421128, 8422013, 8421477, 8420766, 8422198, 8421850, 8414437, 8414752, 8416747, 8415029, 8419345, 8419386, 8417105, 8417825, 8421855 ]

## To get the detail of an item

$ curl 'https://hacker-news.firebaseio.com/v0/item/8422599.json?print=pretty'
{
  &quot;by&quot; : &quot;kevin&quot;,
  &quot;id&quot; : 8422599,
  &quot;kids&quot; : [ 8423025, 8422922, 8422904, 8422663, 8422889, 8423002, 8422941, 8423019, 8422991, 8422932, 8422736, 8422703, 8422684, 8422768, 8422995, 8422905, 8422661, 8422749, 8422933, 8422629, 8422893, 8422807, 8422771, 8422640 ],
  &quot;score&quot; : 257,
  &quot;time&quot; : 1412703525,
  &quot;title&quot; : &quot;Hacker News API&quot;,
  &quot;type&quot; : &quot;story&quot;,
  &quot;url&quot; : &quot;http://blog.ycombinator.com/hacker-news-api&quot;
}


## To get a comment(an item in the kids)

$ curl 'https://hacker-news.firebaseio.com/v0/item/8423015.json?print=pretty'
{
  &quot;by&quot; : &quot;naiyt&quot;,
  &quot;id&quot; : 8423015,
  &quot;kids&quot; : [ 8423052 ],
  &quot;parent&quot; : 8422087,
  &quot;text&quot; : &quot;So if you have an existing DigitalOcean account, it makes it seem like you can&amp;#x27;t apply the promo code to it. But I shot off a ticket to DigitalOcean&amp;#x27;s support, and they applied the $100 promo to my account within 5 minutes. So definitely send them a message if you have an existing account that you would like to have the credit applied.&lt;p&gt;Awesome pack, and great service from DigitalOcean as well.&lt;p&gt;Also of interest is that  my account is apparently already flagged as a &amp;quot;student account&amp;quot; since I&amp;#x27;ve gotten the 5 free private repos in the past with it. Which means once I hit &amp;quot;Get your pack&amp;quot; it immediately gave me access.&quot;,
  &quot;time&quot; : 1412706798,
  &quot;type&quot; : &quot;comment&quot;
}]]></description>
    </item>
        <item>
        <title><![CDATA[BitNami WordPress on Amazon EC2 redirects to internal IP]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/311931]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Wed, 08 Oct 2014 02:15:36 +0800]]></pubDate>
        <description><![CDATA[By default BitNami WordPress uses the internal IP when you install it on an EC2 instance

When you visit https://&lt;public_ip&gt;/, it will redirect to https://10.x.x.x/wp-signup.php?new=&lt;public_ip&gt;


The solution is to call the /opt/wordpress-4.0-0/apps/wordpress/updateip alone with the public IP


# /opt/wordpress-4.0-0/apps/wordpress/updateip &lt;public_ip&gt;


If updateip is not found at above location you can do this to find it out:

# find /opt/wordpress-4.0-0/ -name updateip
/opt/wordpress-4.0-0/apps/wordpress/updateip


## Here is the list of args that updateip accepts
# /opt/wordpress-4.0-0/apps/wordpress/updateip --help
Bitnami Config Tool 
Usage:

 --help                         Display the list of valid options

 --version                      Display product information

 --unattendedmodeui &lt;unattendedmodeui&gt; Unattended Mode UI
                                Default: none
                                Allowed: none minimal minimalWithDialogs

 --optionfile &lt;optionfile&gt;      Installation option file
                                Default: 

 --debuglevel &lt;debuglevel&gt;      Debug information level of verbosity
                                Default: 2
                                Allowed: 0 1 2 3 4

 --mode &lt;mode&gt;                  Installation mode
                                Default: unattended
                                Allowed: qt gtk xwindow text unattended

 --debugtrace &lt;debugtrace&gt;      Debug filename
                                Default: 

 --installer-language &lt;installer-language&gt; Language selection
                                Default: en
                                Allowed: sq ar es_AR pt_BR bg ca hr cs da nl en et fi fr de el he hu it ja ko lv lt no pl pt ro ru sr zh_CN sk sl es sv th zh_TW tr va cy

 --machine_hostname &lt;machine_hostname&gt; Hostname
                                Default: 

 --appurl &lt;appurl&gt;              Change the application URL prefix
                                Default: 

]]></description>
    </item>
        <item>
        <title><![CDATA[PHP Warning:  DOMDocument::load(): I/O warning : failed to load external entity]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/311777]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Mon, 06 Oct 2014 17:59:28 +0800]]></pubDate>
        <description><![CDATA[If you are seeing this error:

PHP Warning:  DOMDocument::load(): I/O warning : failed to load external entity in xxx.php on line x
PHP Notice: Trying to get property of non-object in yyy.php on line y

You have 2 solutions:

## Solution 1

Update 

//Let the DOMDocument to read the XML file
$doc = new DOMDocument();
$doc-&gt;load($fileLocation);

to 

//Read the XML contents and give it to DOMDocument
$doc = new DOMDocument();
$xmlContents = file_get_contents($fileLocation);
$doc-&gt;loadXML($xmlContents);


## Solution 2 (Warning: this is insecure)

Add this line to the top of your php file:

libxml_disable_entity_loader(false);


But be careful with solution 2 as it will bring in the XML external entity injection attack]]></description>
    </item>
        <item>
        <title><![CDATA[硅谷人超过 35岁 会做什么？]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/311559]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Sun, 05 Oct 2014 11:47:08 +0800]]></pubDate>
        <description><![CDATA[Quora 最近有个热门问题是硅谷人超过 35 会做什么？(What do people in Silicon Valley plan to do once they are over 35? http://www.quora.com/What-do-people-in-Silicon-Valley-plan-to-do-once-they-are-over-35)


## Jimmy Wales (Wikipedia创始人)的回答：

I turned 35 the year I founded Wikipedia.  38 the year I founded Wikia (now ranked #30, quantcast).
我35岁创立了 Wikipedia, 38岁创立了 Wikia

The premise of the question is wrong.  A better question might be: How can we in the tech community make sure that unusual success at a very early age is not mistakenly thought to be the norm?

这个问题的预设是错误的。一个更好的问题或许是：在技术圈子里，我们怎么确保一个在年轻时非凡的成功不被认为是普遍存在的？



## Frank Jernigan 的回答：

I joined Google’s software engineering team in 2001 when I was 55 years old. That’s right, I said fifty-five, as in five five. I was the oldest employee at Google for the entire four years I was there. 

2001年，我以55岁的年龄加入 Google。你没看错，我说的就是55岁。之后的四年里，我一直是Google年老的工程师

What did I do? I was not an executive… and I was not a manager… I was simply a software engineer working alongside all my dear colleagues whose median age was probably 25 years younger than I was. My age never seemed to be an issue with anyone. I felt like I was just another member of the team and I felt I was accepted that same way.

我在 Google 做了什么？我不是一个执行官，不是管理者(经理)。我只是一个很简单的软件工程师，工作伙伴们大都比我年轻25岁


There is no such thing as being “over the hill.” There is only becoming irrelevant. To keep from becoming irrelevant, I never stopped learning. When I started my career back in 1975, we still used punch cards and mainframes, programming in Fortran and PL/1. In the 1980s, the promising new technology was applied artificial intelligence. I was fortunate enough to have a great teacher who recognized my abilities in a Lisp class and got me a job with his AI research team, where I not only learned more about software concepts, but also learned the importance of staying on top of cutting edge technologies as they appeared. I devoted myself to a life of constant learning.

世界上没有&quot;走下坡路&quot;这个事情. 人只会脱离时代(becoming irrelevant)。为了跟上时代，我从来没有停止学习。1975年当我开始我的职业历程的时候，我们还在使用打孔卡片和 Fortran以及 PL/1 语言。在80年代，一个很有前景的技术是人工智能。我很幸运，有一个能了解到我 Lisp 能力的老师给我了一份在人工智能研究团队的工作。在那里，我不仅学到了更多软件开发的概念，也学到了紧跟最新技术的重要性。因此我一生都在持续学习

In the mid-1980s I became intrigued with this new thing called object-oriented programming. I learned everything I could about it and wrote my master’s paper on “A Design Methodology for Use with Object-Oriented Programming,” which is probably now buried somewhere in the stacks at Boston University, if universities even still have stacks.

在80年代中期，我被一个叫面向对象编程的东西激发起了兴趣。我尽可能学习了关于它的一切东西，然后写了一份硕士论文《A Design Methodology for Use with Object-Oriented Programming》，现在那篇论文可能在 Boston 大学的某个书库里，如果大学现在还有书库的话

So after ten years of programming in Lisp, in 1990 I moved on to the new object-oriented language at the time, C++. Then a few years after that, the web burst on the scene and I moved into web development, using more new technologies like HTML and JavaScript. Learning, constantly learning, was the key to all these transitions in my career.

在经历了10年的 Lisp 编程之后，我于1990年转向了新的面向对象语言 C++。几年之后，web 开始热门，我开始转向 web 开发，技术则是 HTML和 Javascript。学习，不断地学习，是我的职业履历发生变化的关键

I watched as others my age either moved into management and starting climbing the corporate ladder and others simply became irrelevant and became unemployed or switched to whole new careers. At almost all of my early jobs, my managers would notice that I was a gifted software developer and somehow concluded that I should become a manager. Not knowing any better, I would accept the promotion but then time and again I learned that I hated being a manager. I loved developing software and that’s what I wanted to do. It all became crystal clear one day when my manager walked in my office and saw me working on a program and said, “What are you doing working on software? You’re a manager now!”

我看到很多跟我一样年龄的人，有得转向了管理，在公司里逐步往上爬，而有的人，则脱离了时代，失去了工作，或者转向了全新的职业历程。在我职业生涯的早期，所有我的部门经理，很多都意识到我是一个有天赋的软件工程师，然后得出一个结论就是我应该成为经理/管理者(manager)。在不了解自己的情况下，我可能会接受这些升迁，但是随着时间的流逝，我已经意识到我讨厌成为管理者。我喜欢开发软件。你可以想象得到某天我的 manager 走进我的办公室，看到我在写程序，然后说 &quot;你在干吗呢？你现在已经是个 经理/manager 了! &quot;

I had found what I loved doing, and I was very good at it. So why would I ever want to stop doing that and do something entirely different by becoming a manager? I was advised on many occasions that if I didn’t move up the ranks of the corporation, I would never be able to retire. But every time I tried moving in that direction, I hated it. It caused me a huge amount of stress and, besides that, I felt I was terrible at it. I occasionally tried taking courses to make me a better manager, but they bored me silly. I just wanted to go back to my computer and solve some problems by myself. Finally, I declared one day in 1996 that I would never manage anyone again. I didn’t care if it meant that I could never retire. I thought I’d just figure it out later.

我已经发现了我喜欢做什么，而且对我所喜欢的事情我很擅长。所以我为什么会停止做这个而转成一个经理/manager呢？我经常被人说，如果我不进入公司的上层，我就永远没法退休。但是每次我想转换一个职业方向，我都发现我很不喜欢这么做。它带给我很多压力，此外，我感觉到很糟糕。我不时地去参加一些经理相关的课程，但是它们太无聊了。我只想走回我的电脑，然后自己解决一些问题。最终，我在1996年声明我不再管理任何人。我不再关心这是否意味着我没法退休。而我觉得我应该更早意识到这一点

In 2000, I migrated from Boston to Silicon Valley with my newly acquired PHP skills for the dot-com boom that promptly turned into the dot-com bust right after I arrived. By then I was very used to working alongside people who were half my age. In fact, I loved it. I kept fully employed for ten more months, but then suddenly one day I got laid off.

2000年，我从 Boston 搬到了 硅谷，开始了在一家发展迅速的 dot-com 公司做 PHP 开发。我的工作伙伴年龄只有我的一半，但是我没觉得没什么不习惯。事实上，我很喜欢这样的工作。之后，我在那里工作了10个月，但是突然有一天我被解雇了

I friend of mine sent my resume along with his recommendation to this little company of about 200 employees that seemed to be one of the few companies left that had any promise of success. When Marissa Mayer called me to do my phone interview, I was very clear right up front that in spite of my age, I was not interested in being a manager. She assured me that they would not expect me to move into management. In fact, she said they had just decided that they wanted to hire some people with decades of experience but who did not want to be managers.

我的一个朋友把我的简历和他的推荐信发送到了这个只有200人的小公司(Google)，那个公司似乎是仅存的几个可以承诺成功的公司之一。当 Marissa Mayer 打电话给我做电话面试的时候，我很清楚地告诉她我不想成为一个经理，而她对我保证，他们并不打算让我进入管理的领域。实际上，她说他们已经决定了要雇用有数十年开发经验，而且不想成为经理的人

I got the opportunity of a lifetime precisely because I did not want to be a manager. It confirmed my lifelong belief that if you find what you love to do, then devote yourself to doing it the best that you can, then you will find a way to make that work.

我终于因为我不想成为经理获得了一次机会。这肯定我一生的信念：发掘你喜欢做的事情，然后用一生的时间去尽可能做好它，然后你将会发现这是可行的

Four years later, I retired with a wonderful life. I made many close friends along the way and still feel very close to my colleagues at Google as well as other places I’ve worked. I married the man of my dreams in 2008, before Prop 8 took away that right. We have traveled together, and I took up art, and, yes, I’m still learning new technologies simply because I enjoy it. In the past month, I’ve tackled Ruby and now I’m working on Ruby on Rails, picking up along all the other technologies every good Rubyist ought to know, like git, gems, and bundle. And just in case you haven’t done the math, I am now 69 years old.

四年之后，我退休了。我在 Google 以及其他我工作过的地方认识了很多好朋友，跟工作伙伴也很融洽。 I married the man of my dreams in 2008, before Prop 8 took away that right. 我们一起旅行， 我开始了艺术创作。还有，我依然在学习新的技术，因为我很享受它们。在过去的几个月里，我掌握了 Ruby，现在我正在学习 Ruby on Rails，以及其他优秀的 Rubyist 想要学习的东西，例如git, gems和bundle。对了，你可能还没计算过，我现在已经69岁了.

My advice is to keep doing what you love, never allow yourself to be diverted from it. Always be willing to help others along the way with kindness and generosity of spirit. And you do not ever have to fear becoming irrelevant.

我的建议是，一直去做你所喜欢的，不要离开你所爱的东西。永远保持一颗友好和慷慨的心态去帮助别人。这样你永远不需要去担心自己会脱离时代]]></description>
    </item>
        <item>
        <title><![CDATA[Safari 7.1 added DuckDuckGo]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/311029]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Sat, 04 Oct 2014 00:19:33 +0800]]></pubDate>
        <description><![CDATA[It is a bit surprising that Safari added the DuckDuckGo as one of the search engine options

DuckDuckGo(https://duckduckgo.com/) is a search engine that claims it does not track users. It is founded in 2008 which is really young comparing to Google

Being a search engine option in Safari is a good news to DuckDuckGo.  Definitely because of this much more people will get to know DuckDuckGo

Although 1/5 people in the world will not be able to use DuckDuckGo as it was banned / GFWed by Chinese Gov. safari-duckduckgo.png. safari-7.1.png]]></description>
    </item>
        <item>
        <title><![CDATA[-bash: ./aapt: No such file or directory]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/310238]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Sun, 28 Sep 2014 11:11:58 +0800]]></pubDate>
        <description><![CDATA[I don't know why https://code.google.com/p/android-apktool/ does not release the x64 version of aapt 

# file aapt
aapt: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped

But when you run aapt and seeing that &quot;No such file&quot;, you can simply enable the i386 architecture and install the i386 libs to fix it

Here is how you fix it in Debian / Ubuntu:

dpkg --add-architecture i386
apt-get update
apt-get install libncurses5:i386 libstdc++6:i386 zlib1g:i386]]></description>
    </item>
        <item>
        <title><![CDATA[Short name for apt-get and apt-cache]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/309970]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Fri, 26 Sep 2014 10:12:51 +0800]]></pubDate>
        <description><![CDATA[Are you tired of thinking of choose apt-get or apt-cache? Are you tried of typing the a t p - g e t?

Now in new versions of Debian and Ubuntu(for example 14.04) you got &quot;apt&quot;, where you can use to do all the apt related commands like install and search

Here is the simple command line help:

root@ubuntu1404:~# apt
apt 1.0.1ubuntu2 for amd64 compiled on Jun 13 2014 17:40:05
Usage: apt [options] command

CLI for apt.
Basic commands: 
 list - list packages based on package names
 search - search in package descriptions
 show - show package details

 update - update list of available packages

 install - install packages
 remove  - remove packages

 upgrade - upgrade the system by installing/upgrading packages
 full-upgrade - upgrade the system by removing/installing/upgrading packages

 edit-sources - edit the source information file




And here is the man apt


APT(8)                                                                                                            APT                                                                                                           APT(8)

NAME
       apt - command-line interface

SYNOPSIS
       apt [-h] [-o=config_string] [-c=config_file] [-t=target_release] [-a=architecture] {list | search | show | update | install pkg [{=pkg_version_number | /target_release}]...  | remove pkg...  | upgrade | full-upgrade |
           edit-sources | {-v | --version} | {-h | --help}}

DESCRIPTION
       apt (Advanced Package Tool) is the command-line tool for handling packages. It provides a commandline interface for the package management of the system. See also apt-get(8) and apt-cache(8) for more low-level command
       options.

       list
           list is used to display a list of packages. It supports shell pattern for matching package names and the following options: --installed, --upgradable, --all-versions are supported.

       search
           search searches for the given term(s) and display matching packages.

       show
           show shows the package information for the given package(s).

       install
           install is followed by one or more package names desired for installation or upgrading.

           A specific version of a package can be selected for installation by following the package name with an equals and the version of the package to select. This will cause that version to be located and selected for
           install. Alternatively a specific distribution can be selected by following the package name with a slash and the version of the distribution or the Archive name (stable, testing, unstable).

       remove
           remove is identical to install except that packages are removed instead of installed. Note that removing a package leaves its configuration files on the system. If a plus sign is appended to the package name (with no
           intervening space), the identified package will be installed instead of removed.

       edit-sources
           edit-sources lets you edit your sources.list file and provides basic sanity checks.

       update
           update is used to resynchronize the package index files from their sources.

       upgrade
           upgrade is used to install the newest versions of all packages currently installed on the system from the sources enumerated in /etc/apt/sources.list. New package will be installed, but existing package will never
           removed.

       full-upgrade
           full-upgrade performs the function of upgrade but may also remove installed packages if that is required in order to resolve a package conflict.

OPTIONS
       All command line options may be set using the configuration file, the descriptions indicate the configuration option to set. For boolean options you can override the config file by using something like -f-,--no-f, -f=no or
       several other variations.


       -v, --version
           Show the program version.

       -c, --config-file
           Configuration File; Specify a configuration file to use. The program will read the default configuration file and then this configuration file. If configuration settings need to be set before the default configuration
           files are parsed specify a file with the APT_CONFIG environment variable. See apt.conf(5) for syntax information.

       -o, --option
           Set a Configuration Option; This will set an arbitrary configuration option. The syntax is -o Foo::Bar=bar.  -o and --option can be used multiple times to set different options.

SCRIPT USAGE
       The apt(8) commandline is designed as a end-user tool and it may change the output between versions. While it tries to not break backward compatibility there is no guarantee for it either. All features of apt(8) are
       available in apt-cache(8) and apt-get(8) via APT options. Please prefer using these commands in your scripts.

DIFFERENCES TO APT-GET(8)
       The apt command is meant to be pleasant for end users and does not need to be backward compatible like apt-get(8). Therefore some options are different:

       o   The option DPkgPM::Progress-Fancy is enabled.

       o   The option APT::Color is enabled.

       o   A new list command is available similar to dpkg --list.

       o   The option upgrade has --with-new-pkgs enabled by default.

SEE ALSO
       apt-get(8), apt-cache(8), sources.list(5), apt.conf(5), apt-config(8), The APT User's guide in /usr/share/doc/apt-doc/, apt_preferences(5), the APT Howto.

DIAGNOSTICS
       apt returns zero on normal operation, decimal 100 on error.

BUGS
       APT bug page[1]. If you wish to report a bug in APT, please see /usr/share/doc/debian/bug-reporting.txt or the reportbug(1) command.

AUTHOR
       APT team

NOTES
        1. APT bug page
           http://bugs.debian.org/src:apt

APT 1.0.1ubuntu2                                                                                           25 November 2013                                                                                                     APT(8)]]></description>
    </item>
        <item>
        <title><![CDATA[Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.]]></title>
		<link><![CDATA[https://tech.wodemo.com/entry/309849]]></link>
		<dc:creator><![CDATA[@english]]></dc:creator>
		<pubDate><![CDATA[Thu, 25 Sep 2014 01:53:37 +0800]]></pubDate>
        <description><![CDATA[If you are seeing this in the terminal you need to open the Xcode once to accept the agreement

This is happening probably because you have just upgraded your Xcode. xcode-agreement.png]]></description>
    </item>
    </channel>
</rss>
