2017秋高级软件工程学习总结-冯涛

来源:互联网 发布:口袋妖怪mac 金手指 编辑:程序博客网 时间:2024/05/19 17:03

学习心得

        在这个秋季学期内,我有幸选到了孟宁老师的高级软件工程,通过一个学习的学习后,我感受颇深。在这门课的学期计划里,分为线上和线下两个课程。
        线上部分除了真实课堂上老师讲授的软件工程思想外,还有一门老师自己录制的网易云课程《C编码实践》,虽然我在本科阶段已经学过C编码,但是这门课还是给我一种别样的体验。这门课并不是简单的教习C语言编程,而是通过一个个小实例将软件工程的架构思想融入到代码中,让参与者可以有更深的体验,比如后期的callback函数的设计方法,利与弊,线程安全的重要性,封装抽象的利弊等等,都给学习者一种别样的感受。在学习的过程中老师要求我们必须使用类linux的开发环境,我是相当认同的,因为开发者需要对这个开源系统有一定了解,未来在涉及后端开发时可以如鱼得水,另外,系统的开源特性也使得它十分灵活,而熟练终端也是开发者的必备技能之一。我认为这种学习方式非常的高效,也没有传统C课程那般无聊,因为它的重心根本就不是对语法的纠结,而是上升到了架构的层次。
        线下课堂主要是深入理解Vue.js及其应用开发,老师通过几次线下实验带我们体验了vue.js的生态环境和核心实现,当然,对于有些没有基础的同学,学习起来可能十分困难,但是老师也提供了很多学习资料,这只能依赖于平时多多练习了。我本人曾在本科阶段使用过vue.js1.0版本开发过网站前端,当时的使用体验不是很好,但是通过老师的这次课程后,我发现主要还是由于自己对于vue.js的理解不够透彻,对最新标准的js不熟悉,老师的深入双向绑定实验使我对于vue.js的核心实现有了很深的体会,通过自己实现一个微缩版本的vue,我们对于vue的技术细节了然于心,以后在使用vue的过程中也会有不一样的体验。
        以下是令我收获颇丰的几个实验内容:

  • Vue背后如何实现的双向数据绑定?
  • 基于vue的技术栈范例,包括vuex、axios、RESTful API (express和express-rest)、mongoose和mongoDB
  • 可重用模块的接口设计(callback函数)
  • 函数的可重入性(reentrant)及线程安全浅析
  • 子系统的可重用设计
  • 代码背后的设计思想

收获颇丰代码部分(配有我自己做的注释)

C实验部分代码:

/* * C实验关键代码,指针转型,搜寻节点 * Search a LinkTableNode from LinkTable * int Conditon(tLinkTableNode * pNode,void * args); */tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode,void * args),void * args){    if(pLinkTable == NULL || Conditon == NULL)    {        return NULL;    }    tLinkTableNode * pNode = pLinkTable->pHead;    while(pNode != NULL)    {            if(Conditon(pNode,args) == SUCCESS)        {            return pNode;                           }        pNode = pNode->pNext;    }    return NULL;}/* * C实验关键代码,比较节点,配合上面函数使用 */int SearchCondition(tLinkTableNode * pLinkTableNode, void * args){    char * cmd = (char*) args;    tDataNode * pNode = (tDataNode *)pLinkTableNode;    if(strcmp(pNode->cmd, cmd) == 0)    {        return  SUCCESS;      }    return FAILURE;        }

Vue.js实验部分代码:

// Observer.js// 在Observer原型上增加defineReactive方法Observer.prototype.defineReactive = function (data, key, value) {    // dep.subs为当前元素的监听列表    var dep = new Dep();    Object.defineProperty(data, key, {        enumerable: true,        configurable: false,        get: function () {            console.log("intercept get:" + key);            // 挂载监听器            if (Dep.target) {                //JS的浏览器单线程特性,保证这个全局变量在同一时间内,只会有同一个监听器使用                dep.addSub(Dep.target);            }            return value;        },        set: function (newVal) {            console.log("intercept set:" + key);            if (newVal == value) {                return;            }            //利用闭包的特性,修改value,get取值时也会变化            //不能使用data[key]=newVal            //因为在set中继续调用set赋值,引起递归调用            value = newVal;            //监视新值,此处与下方的observer(value)并不冲突            observer(newVal);            //通知所有监听该数据的Watcher对象            dep.notify(newVal);        }    });    //递归处理    observer(value);};// Watcher.jsWatcher.prototype = {    get: function () {        Dep.target = this;        /*        this.getter是parseExpression根据exp生成的差不多这样的一个函数        function anonymous(scope) {            return  scope.b.c+1+scope.message;        }        个人理解: this.vm作为scope传入anonymous后执行的过程中会触发元素的get拦截从而将当前Dep.target绑定到元素的监听器列表中        而每次调用update中的Watcher的get()操作时都会重新逐级访问触发元素的get操作从而完成重新注册        这里的访问会逐级触发get,有两个作用        1.在Watcher初始化时调用get,会逐级将自己添加到对象的监听列表中,如要监听a.b.c,则a、a.b、a.b.c的监听列表中都会添加这个Watcher         这样做的目的是,在上级数据被修改时,也能接收到通知,如a.b = {c:1}时,原c元素被覆盖,不会发出变动通知,而b则会;        2.同样是上述情况,新添加的c元素,需要添加监听原来c元素的Watcher到自己的监听列表中,在这个Watcher接收到b过来的通知时,会去取a.b.c的值        与原值比较是否发生变动,         这个取的过程中,触发新的c的get,就会添加到c的监听队列        */        var value = this.getter ? this.getter(this.vm) : '';         Dep.target = null;        return value;    },    update: function () {        var newVal = this.get();        if (this.value != newVal) {            this.cb && this.cb(newVal, this.value);            this.value = newVal;        }    }};// Compiler.js// 视图层的直接关联处,此对象包含的方法能够将在watcher中监听到的数据层变化同步到对应的DOM节点中,真正的双向绑定实现处var CompileUtil = {    textUpdater: function (node, newVal, oldVal) {        node.textContent = newVal;    },    handleEvent: function (node, vm, event, exp) {        var fn = parseExpression(exp).get;        node.addEventListener(event, function () {            if (fn) {                fn(vm);            }        });    },    valueUpdater: function (node, newVal, oldVal) {        node.value = newVal ? newVal : '';    }};

实验报告作业链接

  • [ 第一次实验博客 ]
  • [ 第二次实验博客 ]
  • [ 第三次实验博客 ]
  • [ 第四次实验博客 ]
  • [ 第五次实验博客 ]
  • [ 第六次实验博客 ]
  • [ Github代码库]

总结部分

        在学完整个秋高软件工程后,我个人感觉收获还是颇丰的,从上面我列举的每次实验报告和实验内容上基本可以看出。每次实验我都是非常认真完成的,并没有枯燥烦人的点,多是些有趣的挑战和体验,而具体的收获内容我已在上面的学习体验中讲述了,这里就不再赘述。
        不过我个人认为还是有些许遗憾的,上学期由于个人原因,需要备考托福,花费了大量精力在英语上的我没有太多的时间去深究高软这门课,老实说高软这门课学到多少东西取决于自己,老师只是一个引路人,孟老师给的课程范围非常之光,每个细节都可以深究,而没有太多时间去也是我唯一的遗憾吧。

                                                                                                                      软设1班 SA17225078 冯涛