本人新手上路,请大家多多指教,路过的请留下您的脚印,个人格言:每天进步一点点。。。

发布新日志

  • 求职者面试时小心语言陷阱

    2008-09-28 15:40:13

     

    求职者面试时小心语言陷阱


    面试极像一次相亲。应聘者希望找到一个能够了解自己优点的老板,用人单位则希望能找到优秀的合作伙伴。当陌生的双方相见后,都想在短短一席话中努力表现出自己的优点、说出聪明话或立即呈现出很棒的反应,以便给对方留下良好印象。面试,双方玩的其实是一场智力游戏。

      面试官为了不致于“选错郎”,也许会在面试中设置种种语言陷阱,以探测你的智慧、性格、应变能力和心理承受能力。面试者只有识破这样的语言陷阱,才能小心巧妙地绕开它,不致于一头栽进去。

      用“激将法”遮蔽的语言陷阱。这是面试官用来淘汰大部分应聘者的惯用手法。采用这种手法的面试官,往往在提问之前就会用怀疑、尖锐、咄咄逼人的眼神逼视对方,先令对方心理防线步步溃退,然后冷不防用一个明显不友好的发问激怒对方。

      如:“你经历太单纯,而我们需要的是社会经验丰富的人”,“你性格过于内向,这恐怕与我们的职业不合适”,“我们需要名牌院校的毕业生,你并非毕业于名牌院校”,“你的专业怎么与所申请的职位不对口?”

      面对这种咄咄逼人的发问,作为应聘者,首先要做到的就是无论如何不要被“激怒”,如果你被“激怒”了,那么你就已经输掉了。那么,面对这样的发问,如何接招儿呢?

      如果对方说:“你经历太单纯,而我们需要的是社会经验丰富的人。”

    你可以微笑着回答:“我确信如我有缘加盟贵公司,我将会很快成为社会经验丰富的人,我希望自己有这样一段经历。”

      如果对方说:“你性格过于内向,这恐怕与我们的职业不合适。”

      你可以微笑着回答:“据说内向的人往往具有专心致志、锲而不舍的品质,另外我善于倾听,因为我感到应把发言机会多多地留给别人。”

      如果对方说:“我们需要名牌院校的毕业生,你并非毕业于名牌院校。”

      你可以幽默地说:“听说比尔·盖茨也未毕业于哈佛大学。”

      如果对方说:“你的专业怎么与所申请的职位不对口?”

      你可以巧妙地回答:“据说,21世纪最抢手的就是复合型人才,而外行的灵感也许会超过内行,因为他们没有思维定势,没有条条框框。”

      如果对方说:“你原单位这么好,你却要走,是不是在原单位混不下去只好挪个窝儿?”

      应聘者若结结巴巴,无言以对,抑或怒形于色,据理力争,脸红脖粗,那就掉进了对方所设的圈套。应聘者碰到此种情况,要头脑冷静,明白对方在“做戏”,不必与他较劲。

      挑战式的语言陷阱。这类提问的特点是,从求职者最薄弱的地方入手。

      对于应届毕业生,面试官会设问:“你的相关工作经验比较欠缺,你怎么看?”对于女大学生,面试官也许会设问:“女性常常会对自己的能力缺乏自信,你怎么看?”

      如果回答:“不见得吧”、“我看未必”或“完全不是这么回事”,那么也许你已经掉进陷阱了,因为对方希望听到的是你对这个问题的看法,而不是简单、生硬的反驳。

      对于这样的问题,你可以用“这样的说法未必全对”、“这样的看法值得探讨”、“这样的说法有一定的道理,但我恐怕不能完全接受”为开场白,然后婉转地表达自己的不同意见。

      面试官有时还会哪壶不开偏提哪壶,提出让求职者尴尬的问题。如:“你的学习成绩并不很优秀,这是怎么回事?”“从简历看,大学期间你没有担任学生干部的经历,这会不会影响你的工作能力”等等。

      碰到这样的问题,有的求职者常会不由自主地摆出防御姿态,甚至狠狠反击对方。这样做,只会误入过分自信的陷阱,招致“狂妄自大”的评价。而最好的回答方式应该是,既不掩饰回避,也不要太直截了当,用明谈缺点实论优点的方式巧妙地绕过去。

      比如说,当对方提出你的学习成绩不很优秀时,你可以坦然地承认这点,然后以分析原因的方式带出你另外的优点。如,在校期间学习成绩之所以不很优秀,是因为我担任社团负责人,投入到社团活动上的精力太多。虽然我花在社团的心血也带给我不少的收获,但是学习成绩不是最优秀,这一点一直让我耿耿于怀。当意识到这一点后,我一直在设法纠正自己的偏差。

      在面试中屡战屡胜的 Michael就有过一次这样的面试经历。 Michael的学习成绩并不算顶尖,面试咨询公司时,这便成了考官发起攻击的要害:“你的成绩好像不太出众哦,你怎么证明自己的学习能力呢?”

      Michael不慌不忙:“除了学习,我还有其他活动。不是只有成绩才能反映人的学习能力的。其实我的专业课都相当不错,如果你有疑问,可以当场测试我的专业知识。” Michael巧妙地绕开了令人尴尬的问题,将考官的注意力引导到他最拿手的专业知识上。

      诱导式的语言陷阱。这类问题的特点是,面试官往往设定一个特定的背景条件,诱导对方做出错误的回答,因为也许任何一种回答都不能让对方满意。这时候,你的回答就需要用模糊语言来表示。

      如:“依你现在的水平,恐怕能找到比我们企业更好的公司吧?”

      如果你的答案是“YES”,那么说明你这个人也许脚踏两只船,“身在曹营心在汉”。如果你回答“NO”,又会说明你对自己缺少自信或者你的能力有问题。

      对这类问题可以先用“不可一概而论”作为开头,然后回答:“或许我能找到比贵公司更好的企业,但别的企业或许在人才培养方面不如贵公司重视,机会也不如贵公司多;或许我能找到更好的企业,我想,珍惜已有的最为重要。”

      这样的回答,其实你是把一个“模糊”的答案抛还给了面试官。

      还有一种诱导式的语言陷阱是,对方的提问似乎是一道单项选择题,如果你选了,就会掉进陷阱。比如说,对方问:“你认为金钱、名誉和事业哪个重要?”

      对刚毕业的大学生来说,这三者当然都很重要。可是对方的提问却在误导你,让你认为“这三者是相互矛盾的,只能选其一”。这时候切不可中了对方的圈套,必须冷静分析,可以首先明确指出这个前提条件是不存在的,再解释三者对我们的重要性及其统一性。

      你可以这样组织语言,“我认为这三者之间并不矛盾。作为一名受过高等教育的大学生,追求事业的成功当然是自己人生的主旋律。而社会对我们事业的肯定方式,有时表现为金钱,有时表现为名誉,有时二者均有。因此,我认为,我们应该在追求事业的过程中去获取金钱和名誉,三者对我们都很重要。”

      与此相类似的还有一种误导式陷阱。面试官早有答案,却故意说出相反答案。若你一味讨好,顺着面试官的错误答案往上爬,面试的结论一定是:此人无主见,缺乏创新精神。自然被列为淘汰之列。

      还有一种测试式的语言陷阱。这类问题的特点是虚构一种情况,然后让求职者做出回答。比如“今天参加面试的有近10位候选人,如何证明你是最优秀的?”这类问题往往是考察求职者随机应变的能力。无论你给自己列举多少优点,别人总有你也许没有的优点,因此正面回答这样的问题毫无意义。你可以从正面绕开,从侧面回答这个问题。

      你可以回答说:“对于这一点,可能要因具体情况而论,比如贵公司现在所需要的是行政管理方面的人才,虽然前来应聘的都是这方面的对口人才,但我深信我在大学期间当学生干部和主持社团工作的经历已经为我打下了扎实的基础,这也是我自认为比较突出的一点。”这样的回答可以说比较圆滑,很难让对方抓住把柄,再度反击。

      有时,面试官还会提出这样的问题:“你对琐碎的工作是喜欢还是讨厌,为什么?”

      这是个两难问题,若回答喜欢,似乎有悖现在知识青年的实际心理;若说讨厌,似乎每份工作都有琐碎之处。因此,按普遍心理,人们是不愿做琐碎工作的(除非特殊岗位,如家庭钟点工),即考官明知故问,我们可以推测出其醉翁之意不在酒,而在“工作态度”。

    我们可以这样表述自己的态度,“琐碎的事情在绝大多数工作岗位上都是不可避免的,如果我的工作中有琐碎事情需要做,我会认真、耐心、细致地把它做好。”

      这句话既委婉地表达了大多数人的普遍心理——不喜欢琐碎工作,又强调了自己对琐碎事情的敬业精神——认真、耐心、细致。既真实可信,又符合对方的用人心理。

      在各种语言陷阱中,最难提防、最具危险的,可能要算“引君入瓮”式的语言陷阱。

      比如,你前去应聘的职位是一家公司的财务经理,面试官也许会突然问你:“您作为财务经理,如果我(总经理)要求你1年之内逃税100万元,那你会怎么做?”如果你当场抓耳挠腮地思考逃税计谋,或文思泉涌立即列出一大堆逃税方案,那么你就上了圈套,掉进了陷阱。因为抛出这个问题的面试官,正是以此来测试你的商业判断能力和商业道德。要记住,遵纪守法是员工行为的最基本要求。

      比如,你正要从一家公司跳槽去另一家公司。面试官问你:“你们的老板是不是很难相处啊,要不然,你为什么跳槽?”也许他的猜测正是你要跳槽的原因,即使这样,你也切记不要被这种同情的语气所迷惑,更不要顺着杆子往上爬。如果你愤怒地抨击你的老板或者义愤填膺地控诉你所在的公司,那么你一定完了,因为这样不但暴露了你的不宽容,还暴露了你的狭隘。

      面试中,面试官也许会设计出各种各样不同的语言陷阱,但是只要看准了,兵来将挡,水来土掩就是了
  • QTP中连接MySQL的方法(数据库验证点和ADO连接)

    2008-08-19 12:55:33

  • Linux内核中的一些基本编程操作

    2008-07-22 12:25:47

     
    本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
    msn: yfydz_no1@hotmail.com
    来源:http://yfydz.cublog.cn

    1. 前言
    本文介绍linux内核中一些常用的数据结构和操作。
    2. 双向链表(list)
    linux内核中的双向链表通过结构 struct list_head来将各个节点连接起来,此结构会作为链表元素结构中的一个参数:
    struct list_head {
    struct list_head *next, *prev;
    };
    链表头的初始化,注意,结构中的指针为NULL并不是初始化,而是指向自身才是初始化,如果只是按普通情况下的置为NULL,而不是指向自身,系统会崩溃,这是一个容易犯的错误:
    #define LIST_HEAD_INIT(name) { &(name), &(name) }
    #define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)
    #define INIT_LIST_HEAD(ptr) do { \
    (ptr)->next = (ptr); (ptr)->prev = (ptr); \
    } while (0)
    最常用的链表操作:
    插入到链表头:
    void list_add(struct list_head *new, struct list_head *head);
    插入到链表尾:
    void list_add_tail(struct list_head *new, struct list_head *head);
    删除链表节点:
    void list_del(struct list_head *entry);
    将节点移动到另一链表:
    void list_move(struct list_head *list, struct list_head *head);
    将节点移动到链表尾:
    void list_move_tail(struct list_head *list,struct list_head *head);
    判断链表是否为空,返回1为空,0非空
    int list_empty(struct list_head *head);
    把两个链表拼接起来:
    void list_splice(struct list_head *list, struct list_head *head);
    取得节点指针:
    #define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
    遍历链表中每个节点:
    #define list_for_each(pos, head) \
    for (pos = (head)->next, prefetch(pos->next); pos != (head); \
            pos = pos->next, prefetch(pos->next))
    逆向循环链表中每个节点:
    #define list_for_each_prev(pos, head) \
    for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
            pos = pos->prev, prefetch(pos->prev))
    举例:
    LISH_HEAD(mylist);
    struct my_list{
    struct list_head list;
    int data;
    };
    static int ini_list(void)
    {
    struct my_list *p;
    int i;
    for(i=0; i<100; i++){
       p=kmalloc(sizeof(struct my_list), GFP_KERNEL);
       list_add(&p->list, &mylist);
    }
    }

    在内存中形成如下结构的一个双向链表:
    +---------------------------------------------------------------+
    |                                                               |
    | mylist         99            98                     0        |
    | +----+    +---------+    +---------+           +---------+   |
    +->|next|--->|list.next|--->|list.next|--->...--->|list.next|---+
         |----|    |---------|    |---------|           |---------|
    +--|prev|<---|list.prev|<---|list.prev|<---...<---|list.prev|<--+
    | +----+    |---------|    |---------|           |---------|   |
    |            | data   |    | data   |           | data   |   |
    |            +---------+    +---------+           +---------+   |
    |                                                               |
    +---------------------------------------------------------------+
    知道了链表头就能遍历整个链表,如果是用list_add()插入新节点的话,从链表头的next方向看是一个堆栈型。
    从链表中删除节点很容易:
    static void del_item(struct my_list *p)
    {
    list_del(&p->list, &mylist);
    kfree(p);
    }
    最重要的宏是list_entry,这个宏的思路是根据链表元素结构中链表头结构list_head的地址推算出链表元素结构的实际地址:
    #define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
    ptr是链表元素结构(如struct my_list)中链表头结构list_head的地址
    member是链表元素结构(如struct my_list)中链表头结构list_head参数的名称
    type是链表元素结构类型(如struct my_list)
    计算原理是根据链表头结构list_head的地址减去其在链表元素结构中的偏移位置而得到链表元素结构的地址。
    例如:
    static void print_list(void)
    {
    struct list_head *cur;
    struct my_list *p;
    list_for_each(cur, &mylist){
       p=list_entry(cur, struct my_list, list);
       printk("data=%d\n", p->data);
    }
    }
    优点:
    这样就可以用相同的数据处理方式来描述所有双向链表,不用再单独为各个链表编写各种编辑函数。
    缺点:
    1) 链表头中元素置为NULL不是初始化,与普通习惯不同;
    2) 仍然需要单独编写各自的删除整个链表的函数,不能统一处理,因为不能保证所有链表元素结构中链表头结构list_head的偏移地址都是相同的,当然如果把链表头结构list_head都作为链表元素结构的第一个参数,就可以用统一的删除整个链表的函数。

    3. HASH表
    HASH表适用于不需要对整个空间元素进行排序,而是只需要能快速找到某个元素的场合,是一种以空间换时间的方法,本质也是线性表,但由一个大 的线性表拆分为了多个小线性表,由于只需要查找小表,因此搜索速度就会线性查整个大表提高很多,理想情况下,有多少个小线性表,搜索速度就提高了多少倍, 通常把小线性表的表头综合为一个数组,大小就是HASH表的数量。
    HASH表速度的关键是HASH函数的设计,HASH函数根据每个元素中固定的参数进行计算,算出一个不大于HASH表数量的索引值,表示该元 素需要放在该索引号对应的那个表中,对于固定的参数,计算结果始终是固定的,但对于不同的参数值,希望计算出来的结果能尽可能地平均到每个索引值, HASH函数计算得越平均,表示每个小表中元素的数量都会差不多,这样搜索性能将越好。HASH函数也要尽可能的简单,以减少计算时间,常用的算法是将参 数累加求模,在include/linux/jhash.h中已经定义了一些HASH计算函数,可直接使用。
    HASH表在路由cache表,状态连接表等处用得很多。
    举例,连接跟踪中根据tuple值计算HASH:
    // net/ipv4/netfilter/ip_conntrack_core.c
    u_int32_t
    hash_conntrack(const struct ip_conntrack_tuple *tuple)
    {
    #if 0
    dump_tuple(tuple);
    #endif
    return (jhash_3words(tuple->src.ip,
                          (tuple->dst.ip ^ tuple->dst.protonum),
                          (tuple->src.u.all | (tuple->dst.u.all << 16)),
                          ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
    }
    // include/linux/jhash.h
    static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
    {
    a += JHASH_GOLDEN_RATIO;
    b += JHASH_GOLDEN_RATIO;
    c += initval;
    __jhash_mix(a, b, c);
    return c;
    }
    4. 定时器(timer)
    linux内核定时器由以下结构描述:
    /* include/linux/timer.h */
    struct timer_list {
    struct list_head list;
    unsigned long expires;
    unsigned long data;
    void (*function)(unsigned long);
    };
    list:timer链表
    expires:到期时间
    function:到期函数,时间到期时调用的函数
    data:传给到期函数的数据,实际应用中通常是一个指针转化而来,该指针指向一个结构

    timer的操作:
    增加timer,将timer挂接到系统的timer链表:
    extern void add_timer(struct timer_list * timer);
    删除timer,将timer从系统timer链表中拆除:
    extern int del_timer(struct timer_list * timer);
    (del_timer()函数可能会失败,这是因为该timer本来已经不在系统timer链表中了,也就是已经删除过了)
    对于SMP系统,删除timer最好使用下面的函数来防止冲突:
    extern int del_timer_sync(struct timer_list * timer);
    修改timer,修改timer的到期时间:
    int mod_timer(struct timer_list *timer, unsigned long expires);
    通常用法:
    struct timer_list通常作为数据结构中的一个参数,在初始化结构的时候初始化timer,表示到期时要进行的操作,实现定时动作,通常更多的是作为超时 处理的,timer函数作为超时时的资源释放函数。注意:如果超时了运行超时函数,此时系统是处在时钟中断的bottom half里的,不能进行很复杂的操作,如果要完成一些复杂操作,如到期后的数据发送,不能直接在到期函数中处理,而是应该在到期函数中发个信号给特定内核 线程转到top half进行处理。
    为判断时间的先后,内核中定义了以下宏来判断:
    #define time_after(a,b)   ((long)(b) - (long)(a) < 0)
    #define time_before(a,b) time_after(b,a)
    #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
    #define time_before_eq(a,b) time_after_eq(b,a)
    这里用到了一个技巧,由于linux中的时间是无符号数,这里先将其转换为有符号数后再判断,就能解决时间回绕问题,当然只是一次回绕,回绕两次当然是判断不出来的,具体可自己实验体会。
    5. 内核线程(kernel_thread)
    内核中新线程的建立可以用kernel_thread函数实现,该函数在kernel/fork.c中定义:
    long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
    fn:内核线程主函数;
    arg:线程主函数的参数;
    flags:建立线程的标志;
    内核线程函数通常都调用daemonize()进行后台化作为一个独立的线程运行,然后设置线程的一些参数,如名称,信号处理等,这也不是必须 的,然后就进入一个死循环,这是线程的主体部分,这个循环不能一直在运行,否则系统就死在这了,或者是某种事件驱动的,在事件到来前是睡眠的,事件到来后 唤醒进行操作,操作完后继续睡眠;或者是定时睡眠,醒后操作完再睡眠;或者加入等待队列通过schedule()调度获得执行时间。总之是不能一直占着 CPU。
    以下是内核线程的一个实例,取自kernel/context.c:
    int start_context_thread(void)
    {
    static struct completion startup __initdata = COMPLETION_INITIALIZER(startup);
    kernel_thread(context_thread, &startup, CLONE_FS | CLONE_FILES);
    wait_for_completion(&startup);
    return 0;
    }
    static int context_thread(void *startup)
    {
    struct task_struct *curtask = current;
    DECLARE_WAITQUEUE(wait, curtask);
    struct k_sigaction sa;
    daemonize();
    strcpy(curtask->comm, "keventd");
    keventd_running = 1;
    keventd_task = curtask;
    spin_lock_irq(&curtask->sigmask_lock);
    siginitsetinv(&curtask->blocked, sigmask(SIGCHLD));
    recalc_sigpending(curtask);
    spin_unlock_irq(&curtask->sigmask_lock);
    complete((struct completion *)startup);
    /* Install a handler so SIGCLD is delivered */
    sa.sa.sa_handler = SIG_IGN;
    sa.sa.sa_flags = 0;
    siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
    do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
    /*
    * If one of the functions on a task queue re-adds itself
    * to the task queue we call schedule() in state TASK_RUNNING
    */
    for (;;) {
       set_task_state(curtask, TASK_INTERRUPTIBLE);
       add_wait_queue(&context_task_wq, &wait);
       if (TQ_ACTIVE(tq_context))
        set_task_state(curtask, TASK_RUNNING);
       schedule();
       remove_wait_queue(&context_task_wq, &wait);
       run_task_queue(&tq_context);
       wake_up(&context_task_done);
       if (signal_pending(curtask)) {
        while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0)
         ;
        spin_lock_irq(&curtask->sigmask_lock);
        flush_signals(curtask);
        recalc_sigpending(curtask);
        spin_unlock_irq(&curtask->sigmask_lock);
       }
    }
    }
    6. 结构地址
    在C中,结构地址和结构中第一个元素的地址是相同的,因此在linux内核中经常出现使用结构第一个元素的地址来表示结构地址的情况,在读代码时要注意这一点,这和list_entry宏的意思一样。
    如:
    struct my_struct{
    int a;
    int b;
    }c;
    if(&c == &c.a){ // always true

数据统计

  • 访问量: 1431
  • 日志数: 3
  • 建立时间: 2008-07-22
  • 更新时间: 2008-09-28

RSS订阅

Open Toolbar