本周掘学 2019六月第一周

一个全端、全栈兼运维的打杂工程师的工作日志,20190603-0606。


面试

项目扩张比较快,最近招很多新人,说说面试的事。面试我通常会问四类问题,一是算法和数据结构,二是对应编程领域(比如前端、Java或Android)的基础,三是聊下项目,四是聊聊职业。毕竟小公司要求也不能太高,这四个方面其实都没有硬性要求,算法和编程基础两个中有一个过关就行,项目不要求有特别成绩,能关注到一些细节有过思考就行,职业这个基本是确定能力可以了才会聊,主要看看面试者的心态和价值观。

算法和数据结构这块八成面试者是一塌糊涂的,排序算法大多只知道冒泡和快排,快排的具体过程很少有人能说清楚的,时间复杂度和空间复杂度以及稳定性这些指标知道的人就寥寥无几了。这个反应了两个问题,一是这些人基本没有做面试准备,二是他们的基础真的很差。

编程领域的基础这块通常表现就会好些,毕竟都是每天做业务的,大部分基础问题还是能回答得七七八八,不过也会有两个阶层的区分,一部分是只知道用法,没有全局概念也不懂原理,另一部分就多多少少知道一些。懂原理的人通常也是对算法和数据结构比较了解的人。比如问面试Java或Android的人Java里的集合有哪些,基础差的人就会答有ArrayList和HashMap,基础好点的会答有两个顶层接口Collection和Map,Collection下又分为List、Set和Queen。然后问HashMap内部的数据结构,基础差的人是答不上来的,有的人迷迷糊糊还会说出HashMap内部是List的话来,感觉拉都拉不回来。

前面两部分表现欠佳的人还是会继续聊聊项目,说实话大部分业务主导的项目中都是重复在写很基础的代码,经过测试也是能上线运行的,有些擅长处理业务问题的人编程基础还真不一定过关。项目这块就是看人发挥,会让面试者聊聊整体项目情况,有哪些工作职责,遇到过什么难题等等,然后就面试者聊的一些技术点或者实现方案做进一步探讨,在探讨的过程中考察他的逻辑思维、业务分析、处理问题等的能力。这部分最尴尬就是遇到那种觉得自己所有项目都很平庸的人,有面试者直接说他做的项目都很简单,没啥好聊的,这种人只好请他先回家了。

综合前面三部分觉得还行的人就会继续跟他聊聊职业,听听他对工作的期待、对职业的规划、对职场的一些问题的看法等等,这部分主要看气质是否吻合,进到团队的人还是要三观接近点会更融洽。


MySQL

买了《极客时间》上的MySQL课程,断断续续在看,这里总结下锁的内容。InnoDB里的锁分为全局锁、表锁和行锁。

全局锁比较好理解,锁了之后只能读,什么写操作都要等待,这个用得很少,做数据库备份可以用到,但做备份有更好的方案,因为InnoDB支持MVCC(多版本并发控制),能够做到在不影响数据库正常使用的同时做数据库备份。因此全局锁一般很少用到。

表锁其实是分两类:一类是普通的表锁,这个比较好理解,加锁才能对表进行操作;另一类是元数据锁(MDL),这个是隐式支持的。在做查询时,就会自动加上表读锁,做修改时会加表写锁,读写、写与写是互斥的,读可以并发进行。InnoDB支持表的MVVM,每个事务在对表进行操作时会创建一个一致性视图(inconsistent read view),事务多了就会创建一连串的视图,同时每个视图会有一条回滚操作指向上一个视图,这样一来通过当前值和回滚日志就能知道某个视图对应的值了。InnoDB对不同事务级别的支持就与这个MVCC有关,如果事务等级是“可重复读”,就在事务启动时创建视图,整个事务期间都用这个视图,如果事务等级是“读提交”,那么就在每个SQL语句开始执行时创建。

行锁更复杂。首先要知道两阶段锁协议:行锁在需要的时候才加,等到事务结束时才释放。然后是死锁,当并发线程出现循环资源依赖时,会导致进入无限等待的状态,就形成了死锁。不过InnoDB中默认会开启死锁检测,在开始事务时会先进行检测,防止出现死锁。在设计业务时特别要注意这一点,如果出现大量客户端竞争修改同一行数据时,可能会因死锁检测成本过高导致爆CPU。另外行锁跟MVCC还有关系,InnoDB里每个事务有一个唯一的事务ID,叫做trx_id,按照数据递增。当事务更新数据时,会给修改的行记上row trx_id,行状态变化会行程一个链。InnoDB为每个事务构造了一个数组,保存了事务启动时当前正在“活跃”的所有事务ID,当前事务操作数据时,就可能遇到row trx_id的多种情况,如果row trx_id是已提交事务才对当前事务可见。除了这些之外,还有一个特别要注意的点:更新数据是先读后写,读只能读当前值,称为“当前读”(current read),由于当前读的存在,会并发写数据操作看上去不那么符合可重复读。


编程

左耳朵耗子的《编程的本质》的文章,初看标题觉得可能是篇大而空的文章,看了之后觉得获益匪浅。文章的核心观点是“有效的分离Logic、Control和Data的编写好程序的关键”,这里面Data比较好理解,数据结构通常会独立设计,最容易混淆的是Logic和Control,差的代码就是把这两者混在一起写,文中的例子:

// 摘自《极客时间》https://time.geekbang.org/column/article/2751
function check_form_x() {
    var name = $('#name').val();
    if (null == name || name.length <= 3) {
        return { status : 1, message: 'Invalid name' };
    }
 
    var password = $('#password').val();
    if (null == password || password.length <= 8) {
        return { status : 2, message: 'Invalid password' };
    }
 
    var repeat_password = $('#repeat_password').val();
    if (repeat_password != password.length) {
        return { status : 3, message: 'Password and repeat password mismatch' };
    }
 
    var email = $('#email').val();
    if (check_email_format(email)) {
        return { status : 4, message: 'Invalid email' };
    }
 
    \.\.\.
 
    return { status : 0, message: 'OK' };
 
}
复制代码

如果用DSL+解析器,可以写成:

// 摘自《极客时间》https://time.geekbang.org/column/article/2751
var meta_create_user = {
    form_id : 'create_user',
    fields : [
        { id : 'name', type : 'text', min_length : 3 },
        { id : 'password', type : 'password', min_length : 8 },
        { id : 'repeat-password', type : 'password', min_length : 8 },
        { id : 'email', type : 'email' }
    ]
};
 
var r = check_form(meta_create_user);复制代码

这样对比一下非常明显,下面的代码就是大家常说的好代码,上面的是垃圾。一般文章会讲要做代码优化、要封装、要抽象、高内聚低耦合、SOLID、DRY等等理论,包括十几种设计模式,归结起来真的就是将Logic和Control分离,Control抽离出来就是模式,留下Logic去实现业务。


end


转载于:https://juejin.im/post/5cfd1617e51d45590a445b15

猜你喜欢

转载自blog.csdn.net/weixin_33766168/article/details/93168798