却定是266gao不能在收视率了,首页弹出的wwW266gaocom提示框呢?

11,170被浏览1,050,972分享邀请回答1.2K128 条评论分享收藏感谢收起4.3K540 条评论分享收藏感谢收起271被浏览149,331分享邀请回答youku.com/help/view/fid/8#q20分辨率要求:高清分辨率&=600X480;超清分辨率&=960X720时长要求:时长&=30秒。平均码率要求:1.以下这些视频平均码率&=1Mbps时为高清,&=1.5Mbps时为超清:—H.264/AVC(Advance Video Coding)/AVCHD/X264 通常使用MP4,MKV文件格式, 也有的使用FLV格式—RV40/RealVideo 9, 通常使用 RMVB文件格式—WMV3/WVC1/WMVA/VC-1/Windows Media Video 9, 通常使用WMV文件格式2.以下这些视频平均码率&=2Mbps时为高清,&=3Mbps时为超清:—MPEG-4 Visual/Xvid/Divx, 通常使用AVI,MP4文件格式3.以下这些视频平均码率&=5Mbps时为高清,&=7.5Mbps时为超清:—MPEG-2, 通常使用MPEG/MPG/VOB文件格式—MPEG-1, 通常使用MPEG/MPG文件格式可以发现要点有三:1、高清分辨率&=600X480;超清分辨率&=960X720;2、时长要大于等于30秒,太短的视频哪怕再清晰也不合格;3、相应编码格式的平均码率。所以如果你录制的时候这三项设置好了,问题就解决了。如果无法设置达标,责再考虑视频转换软件,转换参数设置还是围绕那三点来。157 条评论分享收藏感谢收起image.uelitem.com/gif/youku_encoder-4.gif4、点击绿色的播放键就可以开始转码了按照上面的做法应该是没有问题的,祝各位顺利~好了,欢迎大家关注我的微信公众号:小道App(微信号:appeers)6623 条评论分享收藏感谢收起WWW/266GAO/COM〓官方入口【WWW.PP55.IN】↘点百度快照↘WWW/266GAO/COM【人人网 - 分享】
WWW/266GAO/COM〓官方入口【WWW.PP55.IN】↘点百度快照↘WWW/266GAO/COM
分享这个视频的人喜欢
分享这个视频的人也爱看
热门视频推荐
热门日志推荐
同类视频推荐
北京千橡网景科技发展有限公司:
文网文[号··京公网安备号·甲测资字
文化部监督电子邮箱:wlwh@vip.sina.com··
文明办网文明上网举报电话: 举报邮箱:&&&&&&&&&&&&
请输入手机号,完成注册
请输入验证码
密码必须由6-20个字符组成
下载人人客户端
品评校花校草,体验校园广场&p&说下我的面试经验吧,都是亲身经历,不喜勿喷:&/p&&p&我去年12月份从上一家公司离职,一直到今年3月份,基本上都在面试中度过来的。&/p&&p&先交代下背景:坐标上海,做技术开发,我本人求职的职位是linux服务器开发,最倾向的职位是服务器开发主程或技术经理。我本人也是上几家公司的面试官,因为接下来几年面临着成家养小孩,技术上也到了瓶颈期,虽然拿了不少offer,但是想综合比对一下再做决定。于是投递了很多家公司。我先后去了如下一些公司:腾讯、百度、饿了么、爱奇艺、360、携程网、京东、华为、bilibili、上海黄金交易所、东方财富网、zilliz、掌门集团(做无线万能钥匙的那一家)、喜马拉雅听书、UCLOUD、峰果网络、华尔街见闻、万得财经、汇正财经、逗屋网络、朝阳永续,还有数家小规模的公司或创业公司吧。&/p&&p&为了避免引起不必要的纠纷,下面我就不说具体的公司名称了。技术面试的细节我尽量写的详细一点,希望对大家有参考价值,技术面试大致有三种情形:&br&&/p&&p&一、以百度、爱奇艺等为代表的,以数据结构和算法为主,首先是简单地了解下你之前的工作经历和项目经验,然后就是算法和数据结构题目,具体涉及到以下内容:&/p&&p&1. 快速排序(包括算法步骤、平均算法复杂度、最好和最坏的情形),有人说校招要把算法写出来,我是社招,所以描述一下算法过程即可。&/p&&p&2. 写二分查找算法,这个尽管是社招,但是一般也不难,所以要求面试者写出来。但是很多公司,比如不会直接让你写算法,而是结合一个具体场景来提问,然后让你自己联想到二分查找,比如求一个数的平方根。&/p&&p&3. 链表,常见的面试题有写一个链表中删除一个节点的算法、单链表倒转、两个链表找相交的部分,这个一般必须得完全无误的情况下写出来;&/p&&p&4. 自己实现一些基础的函数,例如strcpy / memcpy / memmov / atoi,同样的道理,这些必须完全无误且高效地写出来,比如你的实现中有动态分配堆内存,那么这道题目就算答错。&/p&&p&第3点和第4点的关键点一般在于考察你的代码风格、对边界条件的处理,比如判断指针是否为空,千万不要故意不考虑这种情形,即使你知道也不行,只要你不写,一般面试官就认为你的思路不周详,容错率低;再比如,单链表的倒转,最后的返回值肯定是倒转后的链表头结点,这样才能引用一个链表,这些都是面试官想考虑的重点。&/p&&p&5. 哈希表,对哈希表的细节要求很高,比如哈希表的冲突检测、哈希函数常用实现、算法复杂度;比如百度二面就让我写一个哈希表插入元素算法,元素类型是任意类型。&/p&&p&6. AVL树和B树的概念、细节,比如会问mysql数据库的索引的实现原理,基本上就等于问你B树了。&/p&&p&7. 红黑树,这个基本上必问的一个数据结构,包括红黑树的概念、平均算法复杂度、最好最坏情况下的算法复杂度、、左右旋转、颜色变换。面试官常见的算法套路有:你熟悉C++的stl吗?你说熟悉,ok,stl的map用过吧?用过,ok,那map是如何实现的?红黑树,ok,那什么是红黑树?这样提问,红黑树就开始了。Java的也类似。&/p&&p&&br&&/p&&p&二、以饿了么、bilibli、喜马拉雅、360、携程等为代表的,兼顾算法数据结构和其他开发技术,算法和数据结构部分上文提过了,下面提一下其他技术,大致包括以下东西:&/p&&p&1. 以C++语言为例(不是C++开发的朋友可以跳过这一点),第一类是基础的C++问题,常见的有C++的继承体系中virtual关键字的作用(如继承关系中析构函数为什么要申明成virtual函数,如果不申明为virtual会有什么影响)、&/p&&p&
在涉及到父子类时构造与析构函数的执行顺序、多重继承时类的成员列表在地址空间的排列;static关键字的作用,static_cast / reinterpret_cast / dynamic_cast等几个转换符的使用场景;问的最多的就是虚表的布局,尤其是菱形继承(B和C继承A,D继承B和C)时每个对象的空间结构分布,比如问D有几份虚表,D中B和C的成员空间排布。&/p&&p&
另外,如果你应聘的职位使用C++开发,很多公司会问你一些C++11的东西(或者问boost库,基本上都一样),这个你用过就用过,没有用过就说没用过不要装X,常见的C++11需要掌握的一些技术库我也列举一下吧(JAVA及其他语言的读者可以忽略):&/p&&p&
auto关键字、for-each循环、右值及移动构造函数 + std::forward + std::move + stl容器新增的emplace_back()方法、std::thread库、std::chrono库、智能指针系列(std::shared_ptr/std::unique_ptr/std::weak_ptr)(智能&/p&&p&
指针的实现原理一定要知道,最好是自己实现过)、线程库std::thread+线程同步技术库std::mutex/std::condition_variable/std::lock_guard等、lamda表达式(JAVA中现在也常常考察lamda表达式的作用)、std::bind/std::function库、&/p&&p&
其他的就是一些关键字的用法(override、final、delete),还有就是一些细节如可以像JAVA一样在类成员变量定义处给出初始化值。&/p&&p&&br&&/p&&p&2. 网络通信问题,比如协议栈的层级关系,三次握手和四次挥手的【细节】,注意我说的是细节,比如CLOSE_WAIT和TIME_WAIT状态(bilibili问了这样一个问题,你可以感受一下:A与B建立了正常连接后,从未相互发过数据,这个时候B突然机器重启,问A此时的tcp状态处于什么状态?如何消除服务器程序中的这个状态?&/p&&p&
万得问过流量拥塞和控制机制、腾讯问过tcp和ip包头常见有哪些字段),阻塞和非阻塞socket在send、recv函数上的行为表现,异步connect函数的写法,select函数的用法,epoll与select的区别,&/p&&p&
基本上只要问到epoll,必问epoll的水平模式和边缘模式的区别;一些socket选项的用法,nagle / keepalive / linger等选项的区别;tcp / udp的区别和适用场景;&/p&&p&
通信协议如何设计避免粘包;http协议的get和post方法的区别(问的比较深的会让你画出http协议的格式,参照这篇文章中关于http协议格式的讲解:&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/analogous_love/article/details/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&blog.csdn.net/analogous&/span&&span class=&invisible&&_love/article/details/&/span&&span class=&ellipsis&&&/span&&/a&);&/p&&p&
windows用户可能会问到完成端口模型(IOCP),网络通信方面的问题,我专门开了一个知乎live系统地总结&/p&&p&
了一下,有兴趣的朋友可以看这里:&a href=&https://www.zhihu.com/lives/485120& class=&internal&&&span class=&invisible&&https://www.&/span&&span class=&visible&&zhihu.com/lives/9221108&/span&&span class=&invisible&&&/span&&span class=&ellipsis&&&/span&&/a& 和 这里:&a href=&https://www.zhihu.com/lives/778304& class=&internal&&&span class=&invisible&&https://www.&/span&&span class=&visible&&zhihu.com/lives/9021133&/span&&span class=&invisible&&&/span&&span class=&ellipsis&&&/span&&/a&。&/p&&p&
总之,网络通信问题能搞的多清楚就可以搞的多清楚,最起码把tcp应用层的各种socket API的用法细节搞清楚。&/p&&p&&br&&/p&&p&3. 操作系统原理性的东西&/p&&p&
比如linux下elf文件的节结构,映射到进程地址空间后,分别对应哪些段,相关的问题还有,全局变量、静态存储在进程地址空间的哪里;堆和栈的区别,栈的结构,栈的细节一点要搞的特别清楚,因为一些对技术要求比较高的公司会&/p&&p&
问的比较深入,例如京东的一面是让我先写一个从1加到100的求和函数,然后让我写出这个函数的汇编代码(JAVA开发的同学可能会让你试着去写一点JVM的指令),如果你对栈的结构(如函数参数入栈顺序、函数局部变量在栈中的布局、栈帧指针和栈顶指针位置)不熟悉的话,这题目就无法答对了;栈的问题,可能会以&/p&&p&
常见的函数调用方式来提问,常见的函数调用有如下__cdecl/__stdcall/__thiscall/__fastcall的区别,比如像printf这样具有不定参数的函数为什么不能使用__stdcall;&/p&&p&
还有就是进程和线程的联系与区别,问的最多的就是线程之间的一些同步技术,如互斥体、信号量、条件变量等(Windows上还有事件、临界区等),这些东西你必须熟悉到具体的API函数使用的层面上来,从另外一个角度来说,这是咱们实际工作中编码最常用的东西,如果你连这个都不能熟练使用,那么你肯定不是一个合格的开发者;这类问题还可以引申为什么是死锁、如何避免死锁;进程之间通信的常用技术也需要掌握,常用的通信方式(linux下)有共享内存、匿名和具名管道、socket、消息队列等等,管道和socket是两个必须深入掌握的考察点(与上面网络通信有点重复);&/p&&p&
linux系统下可能还会问什么是daemon进程,如何产生daemo进程,什么是僵尸进程,僵尸进程如何产生和消除(bilibili问过)。&/p&&p&
CAS机制(饿了么二面问过)。&/p&&p&&br&&/p&&p&4. 第四类就是一个使用过的开源技术,比如代表nosql技术的的redis;网络库libevent等等;数据库如mysql的一些东西。这个一般不做硬性要求,但是这里必须强调的就是redis,熟练使用redis甚至研究过redis源码,现在一般是对做后台开发的技术硬性要求或者说不可缺少的部分,&/p&&p&
基于redis的面试题既可以聊算法与数据结构,也可以聊网络框架等等一类东西。我面试的公司中基本上百分之九十以上都问到了redis,只是深浅不一而已,比如喜马拉雅问了redis的数据存储结构、rehash;bilibili问了redis的事务与集群。&/p&&p&&br&&/p&&p&三、只问一些做过的业务或者项目经验,这类公司他们招人其实对技术要求不高(资深及主管级开发除外),只要你过往的项目与当前应聘职位匹配,可以过来直接上手干活就可以了,&/p&&p&
当然薪资也就不会给很多。比如游戏公司会关心你是否有某某类型的游戏开发经验、股票类公司会关心你是否有过证券或者交易系统的开发经验等。我的经验就是这类公司,能去的话可以去,不能去的话就当积累面试经验。&/p&&p&
业务开发哪里都能找到,真正的重视技术的公司,应该是广大做技术尤其是初中级开发的朋友应该值得关心的事情。&/p&&p&&br&&/p&&p&四、不靠谱型公司&/p&&p&
我遇到的大致有四类:&/p&&p&
第一类:装X忽悠型,面试过程冗长繁琐,比如号称每一百份简历中才发一个面试邀请,号称每一个面试者发一个offer,号称硅谷风格,我面试的有一家公司就是这个样子,先是一轮长长的电话面试,然后是五轮技术面试,前三轮是刷leetcode上原题,然后后几轮面试,面试官从基本的操作系统的&/p&&p&
中断、GDT、LDT、分表分页机制问到上层高并发海量数据的架构,说的不好听,真是从外太空聊到内子宫,最后问具体职位做什么时,要么遮遮掩掩要么原型毕露;或者讨论薪资时,要么面露难色要么各种画饼,但是实际就给不了多少薪水的。&/p&&p&
第二类:佛性公司&/p&&p&
面试下来,全程面试官面带微笑,问你的问题你回答的面试官也很赞同,但最后你就没通过,我猜测要么公司不是很缺人,想观望一下是否有合适的人才;要么招聘信息上开的薪资给不到。&/p&&p&
第三类:老奶奶裹脚布型公司&/p&&p&
其特点是面试周期长,往往第一轮面试通知你过了,让你回去等上十天半个月后,给你打电话通知你来第二轮面试,面试要求穿正装,带好各种证件,面试前必须先查验你的身份证、学历证学位证,甚至是四六级考试证等等,麻烦至极,即使你一路过关斩将过了终面,薪资也给不了多少。&/p&&p&
大家都是要养家糊口的,都是忙着找工作,谁有时间和你耗上十天半个月呢?&/p&&p&
第四类:不尊重人类型公司&/p&&p&
我这里说的不尊重人,不是指的是面试过程中对你人身攻击,而是不根据你的工作年限和经验随意安排面试官,举个例子,比如你工作十年,你去面试一个技术总监的职位,对方公司安排一个工作不满两年的部门职员作为面试官,这个面试官如果是走过场可以理解,但是非要和你纠结一个如二进制位移、现代编译器要不要在子类析构函数前加virtual关键字这些技术细节就没必要了。还有一类就是故意问一些刁钻的问题,或者全场都心不在焉、玩手机、漫不经心的面试官,比如问你tcp协议头有多少个字段,每个字段是干啥的。遇到这一类面试官我的经验就是要么婉拒,要么直接怼回去。&/p&&p&&br&&/p&&p&
下面再说下面试中需要注意的一些细节:&/p&&p&
第一,如果你的工作年限不长,尤其是渴望在技术方面有一定的造诣,那么你首先考虑的应该是新的单位是否能有利于你技术上的成长,而不是两份同样的工作,薪资上的上下相差的三五千、五六千。如果&/p&&p&
想转行的同学(比如从客户端转服务器,从C++转JAVA),不要因为薪资突然变低而拒绝这种阵痛,要把目光放长远一点。&/p&&p&
第二,一些公司虽然招聘信息上写了最多能给到多少多少,但实际即使你全程面试下来都很完美,可能最终你也会因为薪资要求达不到不被录取。&/p&&p&
第三,一些根本不想去的公司,如果你有时间的话,去面试积累下经验也不是什么坏事。&/p&&p&
第四,面试的时候,同时也是你在考察面试官,一般面试官问你的问题,你能回答出来的在百分之八十左右,这样的公司可以考虑去入职,你进去的话可能才会在技术上有一些提升。如果你全场秒杀面试官的题目,&/p&&p&
你的技术天花板可能也在那里。&/p&&p&
第五,面试的时候聊清楚你将来的职位内容,避免进去客串一些不想做的工作。&/p&&p&
第六,遇到不会的面试题,不要直接就否定自己,可以尝试着去和面试官沟通一下,或者要求给点提示或者思路。&/p&&p&
第七,不要轻视笔试中的一些数学智力题目,认真作答,试问算法不也是数学智力题吗?&/p&&p&
第八,自信一点,每个人的经历和经验都是独一无二的,面试的时候,一些特定领域的问题,回答不出来也不要太在意。&/p&&p&&br&&/p&&p&
希望对阅读的朋友有所帮助。因为个人经验能力有限,所说的也可能只是一家之言,说的不妥当的地方还请温和地提出建议。&/p&&p&&br&&/p&&p&
因时间有限,很多地方不便详细展开,如果您对于面试有什么细节的地方想和我交流,欢迎关注我的微信公众号『easyserverdev』,进行私人一对一交流。&/p&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-cfac7d78e048b7911c42fdc8bde538e1_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&258& data-rawheight=&258& class=&content_image& width=&258&&&/figure&
说下我的面试经验吧,都是亲身经历,不喜勿喷:我去年12月份从上一家公司离职,一直到今年3月份,基本上都在面试中度过来的。先交代下背景:坐标上海,做技术开发,我本人求职的职位是linux服务器开发,最倾向的职位是服务器开发主程或技术经理。我本人也是…
&figure&&img src=&https://pic2.zhimg.com/v2-f53e95fb5ae86d83ce3da2a634f8c88a_b.jpg& data-rawwidth=&620& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&620& data-original=&https://pic2.zhimg.com/v2-f53e95fb5ae86d83ce3da2a634f8c88a_r.jpg&&&/figure&&p&早在1994年,Gregory Colvin就向C++标准委员会提出了智能指针的提案(&a href=&https://link.zhihu.com/?target=http%3A//www.boost.org/doc/libs/1_54_0/libs/smart_ptr/smart_ptr.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Smart Pointers - 1.54.0&/a&)。但早期的设计并不好用。各个库都有自己的一套智能指针,没有标准化。经过20多年的发展,特别是C++11标准引入shared_ptr和unique_ptr之后,智能指针技术趋于成熟。然而在实践中,大多数项目还在使用自己山寨的引用计数解决方案。智能指针还没有成为C++程序员的常备技能。&/p&&p&像其他技术一样,智能指针有一定学习成本,如果被误用,同样也会带来各种bug。本文简要回顾C++11智能指针shared_ptr/unique_ptr/weak_ptr的核心概念,并试图总结其正确使用方法。&/p&&h2&Ownership Logic&/h2&&p&正确使用智能指针的前提是搞清楚业务逻辑需要。其中最重要的是设计资源管理,即ownership,并据此选择是否使用智能指针,使用哪种智能指针。智能指针有其内在的ownership logic。&/p&&p&所谓own某个指针,意味着有责任在合适的时候释放该指针。获得、引用和使用某个指针,并不一定需要负责释放该指针所指向的资源。&/p&&p&shared_ptr是shared ownership,owner发起释放操作,只是减引用计数,只有所有owner都释放,所指向的对象才真正释放。&/p&&p&weak_ptr不控制对象的生命周期,但是它观察着shared_ptr管理的对象,有办法知道对象是否还活着。&/p&&p&unique_ptr则是unique ownership,对象的管理权可以转移,但是同一时刻只有一个owner,否则编译就会报错。&/p&&h2&shared_ptr, weak_ptr&/h2&&p&shared_ptr在底层使用了两个技术,一个是引用计数,另一个是引入了一个中间层(&a href=&https://link.zhihu.com/?target=http%3A//umich.edu/%7Eeecs381/handouts/C%2B%2B11_smart_ptrs.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&umich.edu/~eecs381/hand&/span&&span class=&invisible&&outs/C++11_smart_ptrs.pdf&/span&&span class=&ellipsis&&&/span&&/a&, &a href=&https://link.zhihu.com/?target=http%3A//www.informit.com/articles/article.aspx%3Fp%3D2085179& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Be Smart About C++11 Smart Pointers&/a&)。&/p&&p&为了管理目标对象,所创建的中间层被称为manager object。其中除了目标对象的裸指针,还有两个引用计数。一个用于shared_ptr,一个用于weak_ptr。当shared count减到0的时候,managed object就会被销毁。只有shared count和weak count都减到0的时候,manager object才会被销毁。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-c8f24db60b58fcb776f17fb_b.jpg& data-rawwidth=&603& data-rawheight=&379& class=&origin_image zh-lightbox-thumb& width=&603& data-original=&https://pic2.zhimg.com/v2-c8f24db60b58fcb776f17fb_r.jpg&&&figcaption&shared_ptr/weak_ptr原理&/figcaption&&/figure&&h2&enable_shared_from_this&/h2&&p&如果涉及到将this指针提升为shared_ptr的情况,直接提升会新建一个manager object。&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&kt&&void&/span& &span class=&nf&&f&/span&&span class=&p&&(&/span&&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span&&span class=&p&&);&/span&
&span class=&k&&class&/span& &span class=&nc&&Thing&/span& &span class=&p&&{&/span&
&span class=&k&&public&/span&&span class=&o&&:&/span&
&span class=&kt&&void&/span& &span class=&n&&foo&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&c1&&//f(shared_ptr&Thing&(this));
//new manager object A&/span&
&span class=&n&&f&/span&&span class=&p&&(&/span&&span class=&n&&shared_from_this&/span&&span class=&p&&());&/span&
&span class=&c1&&//use manager object B&/span&
&span class=&p&&}&/span&
&span class=&p&&};&/span&
&span class=&kt&&int&/span& &span class=&nf&&main&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&sp&/span&&span class=&p&&(&/span&&span class=&k&&new&/span& &span class=&n&&Thing&/span&&span class=&p&&());&/span&
&span class=&c1&&//new manager object B&/span&
&span class=&n&&sp&/span&&span class=&o&&-&&/span&&span class=&n&&foo&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&使用两个manager object管理同一个对象会造成不可预知的后果。为避免这种情况,需要在对象中维护一个weak_ptr。这是通过enable_shared_from_this自动完成的。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-abdd03b3a742e_b.jpg& data-rawwidth=&591& data-rawheight=&186& class=&origin_image zh-lightbox-thumb& width=&591& data-original=&https://pic2.zhimg.com/v2-abdd03b3a742e_r.jpg&&&figcaption&enable_shared_from_this原理&/figcaption&&/figure&&p&当需要在object内部使用this指针时,调用shared_from_this()就可以避免新建manager object。需要注意的是,在构造函数中,对象还未构造完毕,并没有交由shared_ptr管理,即manager object还未创建,所以不能使用shared_from_this。&/p&&h2&unique_ptr&/h2&&p&unique_ptr是对裸指针的简单封装,不需要额外的manager object。和shared_ptr基本用法一致,只是unique_ptr没有引用计数,内部指针要么有效,要么没有。&/p&&p&unique_ptr可以用(unique_ptr rvalue)初始化,但不允许copy construction或copy assignment。这符合其unique ownership语义。所以如果函数参数中有unique_ptr,应该传引用或指针,不能传值。&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&n&&unique_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&create&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&n&&unique_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&ptr&/span&&span class=&p&&(&/span&&span class=&k&&new&/span& &span class=&n&&Thing&/span&&span class=&p&&);&/span&
&span class=&k&&return&/span& &span class=&n&&ptr&/span&&span class=&p&&;&/span& &span class=&c1&&//rvalue&/span&
&span class=&p&&}&/span&
&span class=&n&&unique_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&ptr2&/span&&span class=&p&&(&/span&&span class=&n&&create&/span&&span class=&p&&());&/span&
&span class=&c1&&//unique_ptr&Thing& ptr3(ptr2);
//copy construction&/span&
&span class=&c1&&//unique_ptr&Thing& ptr3 = ptr2; //copy assignment&/span&
&/code&&/pre&&/div&&h2&Race Condition&/h2&&p&c++20将有atomic_shared_ptr/atomic_weak_ptr,这是不是意味着shared_ptr/weak_ptr并不是线程安全的呢?&/p&&p&一般地讲,manager object中的引用计数增减是原子操作,所以是线程安全的。同时读shared_ptr也是安全的。但是如果有线程在读写同一个shared_ptr,就不是安全的(&a href=&https://link.zhihu.com/?target=http%3A//www.boost.org/doc/libs/1_57_0/libs/smart_ptr/shared_ptr.htm%23ThreadSafety& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&shared_ptr - 1.57.0&/a&),这和操作一般指针是一致的。如果两个线程在操作两个shared_ptr,即使他们指向同一个manager object,只要没有访问所管理的对象,就是安全的(&a href=&https://link.zhihu.com/?target=https%3A//mbevin.wordpress.com//smart-pointers/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Lesson #4: Smart Pointers&/a&)。&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&kt&&int&/span&&span class=&o&&&&/span& &span class=&n&&p&/span&&span class=&p&&(&/span&&span class=&k&&new&/span& &span class=&kt&&int&/span&&span class=&p&&(&/span&&span class=&mi&&42&/span&&span class=&p&&));&/span&
&span class=&c1&&// thread A&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&kt&&int&/span&&span class=&o&&&&/span& &span class=&n&&p2&/span&&span class=&p&&(&/span&&span class=&n&&p&/span&&span class=&p&&);&/span& &span class=&c1&&// reads p&/span&
&span class=&n&&p2&/span&&span class=&p&&.&/span&&span class=&n&&reset&/span&&span class=&p&&(&/span&&span class=&k&&new&/span& &span class=&kt&&int&/span&&span class=&p&&(&/span&&span class=&mi&&1912&/span&&span class=&p&&));&/span& &span class=&c1&&//writes p2&/span&
&span class=&c1&&// thread B&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&kt&&int&/span&&span class=&o&&&&/span& &span class=&n&&p3&/span&&span class=&p&&(&/span&&span class=&n&&p&/span&&span class=&p&&);&/span& &span class=&c1&&// OK, multiple reads are safe&/span&
&span class=&n&&p3&/span&&span class=&p&&.&/span&&span class=&n&&reset&/span&&span class=&p&&();&/span& &span class=&c1&&// OK, writes p3&/span&
&/code&&/pre&&/div&&p&需要指出的是,从weak_ptr.lock()提升为shared_ptr是线程安全的。unique_ptr的所有权转让也是安全的。但是使用unique_ptr操作对象是不安全的(&a href=&https://link.zhihu.com/?target=http%3A//www.modernescpp.com/index.php/atomic-smart-pointers& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Atomic Smart Pointers&/a&)。&/p&&h2&智能指针正确用法&/h2&&p&使用shared_ptr/weak_ptr/unique_ptr必须要注意:&/p&&p&1)必须保证所有managed object只有一个manager object&/p&&p&当object第一次创建的时候,就要立刻交由一个shared_ptr管理,其他的shared_ptr和weak_ptr都必须从第一个shared_ptr拷贝或赋值得到。具体来说,就是调用shared_ptr(raw ptr)和make_shared函数。&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&k&&class&/span& &span class=&nc&&Thing&/span&&span class=&p&&;&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p1&/span&&span class=&p&&(&/span&&span class=&k&&new&/span& &span class=&n&&Thing&/span&&span class=&p&&);&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p2&/span&&span class=&p&&(&/span&&span class=&n&&make_shared&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span&&span class=&p&&());&/span&
&/code&&/pre&&/div&&p&其中使用make_shared一次性分配managed object和manager object两块内存,效率更高。而且对于强迫症来说,看到new看不到delete总是感觉挺难受的,还不如连new都不要看到。&/p&&p&2)能用裸指针解决问题的情况下,就不要使用智能指针。&br&
如果决定了用智能指针,那就不要用裸指针管理同一个对象。&/p&&p&虽然通过智能指针get()函数可以得到裸指针,但是尽量不要用。对象一经创建,就应该纳入shared_ptr/unique_ptr的管理之下。为了保证没有裸指针暴露出来,应该只用shared_ptr(raw ptr)/unique_ptr(raw_ptr)和make_shared/make_unique函数创建对象。&/p&&p&3)ownership logic是正确使用智能指针的基础,不要滥用shared_ptr&/p&&p&weak_ptr是为了解决循环引用而引入的。当系统中出现了循环引用,且都是使用shared_ptr管理对象,那么一定是shared_ptr被滥用了。&/p&&p&weak_ptr观察着shared_ptr管理的对象,必须从shared_ptr或weak_ptr创建。其唯一正确的使用方法是先用lock()调用提升为shared_ptr,然后使用shared_ptr。如果直接用shared_ptr(weak_ptr)来构造,可能会在weak_ptr已经expire的情况下抛出异常。&/p&&p&shared_ptr可以用==,!=,&来比较,实际比较的是他们管理的裸指针。&/p&&p&shared_ptr有拷贝开销,作为参数时,应该尽量用const reference。&/p&&p&4) 能用unique_ptr管理的对象,不要使用shared_ptr/weak_ptr&/p&&p&这其实是说尽量在单一的固定地方管理资源,如果不能保证ownership固定,可以转移所有权,尽量保证只有一个owner(&a href=&https://link.zhihu.com/?target=https%3A//www.meetingcpp.com/blog/items/an-overview-on-smart-pointers.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&An overview on smart pointers&/a&,&a href=&https://link.zhihu.com/?target=https%3A//google.github.io/styleguide/cppguide.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Google C++ Style Guide&/a&,&a href=&https://link.zhihu.com/?target=http%3A//www.acodersjourney.com/2016/05/top-10-dumb-mistakes-avoid-c-11-smart-pointers/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Top 10 dumb mistakes to avoid with C++ 11 smart pointers - A CODER'S JOURNEY&/a&)。&/p&&h2&最佳实践实例&/h2&&p&1)main thread拥有对象,加载子线程只管加载。&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&c1&&//main thread&/span&
&span class=&k&&class&/span& &span class=&nc&&Thing&/span&&span class=&p&&;&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p1&/span&&span class=&p&&(&/span&&span class=&n&&make_shared&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span&&span class=&p&&());&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&p1&/span&&span class=&o&&-&&/span&&span class=&n&&getState&/span&&span class=&p&&()&/span& &span class=&o&&==&/span& &span class=&n&&eLoadFinish&/span&&span class=&p&&)&/span& &span class=&p&&...&/span& &span class=&c1&&//use after loading finish&/span&
&span class=&c1&&//loading thread&/span&
&span class=&n&&weak_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p2&/span&&span class=&p&&(&/span&&span class=&n&&p1&/span&&span class=&p&&);&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p3&/span& &span class=&o&&=&/span& &span class=&n&&p2&/span&&span class=&p&&.&/span&&span class=&n&&lock&/span&&span class=&p&&();&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&p3&/span& &span class=&o&&&&&/span& &span class=&n&&p3&/span&&span class=&o&&-&&/span&&span class=&n&&getState&/span&&span class=&p&&()&/span& &span class=&o&&!=&/span& &span class=&n&&eLoadFinish&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&p&&...&/span& &span class=&c1&&//loading&/span&
&span class=&n&&p3&/span&&span class=&o&&-&&/span&&span class=&n&&setState&/span&&span class=&p&&(&/span&&span class=&n&&eLoadFinish&/span&&span class=&p&&);&/span& &span class=&c1&&//set loading finish flag&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&此处不宜使用unique_ptr。虽然在子线程的加载过程中可以上锁,但是对象中途若被主线程释放,将会宕机。&/p&&p&2)拥有者和使用者都在main thread,使用者需要定期对对象做操作。&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&k&&class&/span& &span class=&nc&&Thing&/span&&span class=&p&&;&/span&
&span class=&kt&&void&/span& &span class=&nf&&funcUsePtr&/span&&span class=&p&&(&/span&&span class=&k&&const&/span& &span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&o&&&&/span&&span class=&n&&p&/span&&span class=&p&&){&/span&
&span class=&n&&p&/span&&span class=&o&&-&&/span&&span class=&n&&xxx&/span&&span class=&p&&();&/span& &span class=&c1&&//method call&/span&
&span class=&p&&}&/span&
&span class=&kt&&void&/span& &span class=&nf&&funcPassToUser&/span&&span class=&p&&(&/span&&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&o&&&&/span&&span class=&n&&p&/span&&span class=&p&&){&/span&
&span class=&n&&pUser&/span& &span class=&o&&=&/span& &span class=&n&&p&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&c1&&//owner&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p1&/span&&span class=&p&&(&/span&&span class=&n&&make_shared&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span&&span class=&p&&());&/span&
&span class=&n&&funcUsePtr&/span&&span class=&p&&(&/span&&span class=&n&&p1&/span&&span class=&p&&);&/span& &span class=&c1&&//normal use&/span&
&span class=&n&&funcPassToUser&/span&&span class=&p&&(&/span&&span class=&n&&p1&/span&&span class=&p&&);&/span&
&span class=&c1&&//pass to pUser&/span&
&span class=&c1&&//user&/span&
&span class=&n&&shared_ptr&/span&&span class=&o&&&&/span&&span class=&n&&Thing&/span&&span class=&o&&&&/span& &span class=&n&&p2&/span& &span class=&o&&=&/span& &span class=&n&&pUser&/span&&span class=&p&&.&/span&&span class=&n&&lock&/span&&span class=&p&&();&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&p2&/span&&span class=&p&&)&/span&
&span class=&n&&p2&/span&&span class=&o&&-&&/span&&span class=&n&&yyy&/span&&span class=&p&&();&/span& &span class=&c1&&//method call&/span&
&/code&&/pre&&/div&&p&此处虽然只有一个线程,但也不宜用unique_ptr。试想owner如果中途要释放对象,user是不知道的。此时用weak_ptr维持一个弱引用,当需要的时候检查一下有效性,是比较合理的。&/p&
早在1994年,Gregory Colvin就向C++标准委员会提出了智能指针的提案()。但早期的设计并不好用。各个库都有自己的一套智能指针,没有标准化。经过20多年的发展,特别是C++11标准引入shared_ptr和unique_ptr之后,智能指针技术趋于…
&p&我针对职场新人,谈一下自己的观点。从两方面切入:1)我认为重要的人格品质 2)如何提升代码能力。&/p&&p&&b&我以为,培养优秀的人格品质,同职场规划一样重要:&/b&&/p&&p&权利的游戏S6E10,熊岛小领主Lyanna Mormont在会议上。&/p&&p&你的儿子在红色婚礼上遇害 曼德勒大人 而你拒不奉召。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-18c16e3b1dc04a951fb0c_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic1.zhimg.com/v2-18c16e3b1dc04a951fb0c_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-8de9be3af5d856ca16a5f4d_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic1.zhimg.com/v2-8de9be3af5d856ca16a5f4d_r.jpg&&&/figure&&p&你曾宣誓效忠史塔克家族 葛罗佛大人 但在他们最需要帮助的时刻 你拒不奉召&/p&&figure&&img src=&https://pic4.zhimg.com/v2-248ec851a6c4cf392d3f_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-248ec851a6c4cf392d3f_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-d06bc1e507d36a6fa4fe20cb3a47bfa6_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic3.zhimg.com/v2-d06bc1e507d36a6fa4fe20cb3a47bfa6_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-10da6a45c0cca47dda347_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-10da6a45c0cca47dda347_r.jpg&&&/figure&&p&但莫尔蒙家族永不遗忘 北境永不遗忘 我们不承认除北境之王以外的任何君主&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f2fbd627fbc0ac1e69aadb_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic2.zhimg.com/v2-f2fbd627fbc0ac1e69aadb_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-b297cf902ba89acdb62abb_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-b297cf902ba89acdb62abb_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-cc3ceacffa3e01ed4f69a3_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-cc3ceacffa3e01ed4f69a3_r.jpg&&&/figure&&p&他就是我的君主,自今日起,至死方休。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-ab6533fac67da50ab748_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic1.zhimg.com/v2-ab6533fac67da50ab748_r.jpg&&&/figure&&p&Lyanna作为熊岛的领导,在关键时刻站了起来,展现了自己对于Stark家族的忠诚,即使“Winter has come”,其他家族在考虑如何保住自身。&/p&&p&&b&如果希望成为一位领导,Tech Lead或者Project Manager,自己创业,又或只是想作一名普普通通的程序员&/b&,我们都应该向这位年轻的Lyanna学习:&b&主动承担,勇于奉献。&/b&&/p&&p&我认为这和军队精神相辅相成,因为军队中,冲在在前面的是队长,而不是普通士兵。我们也可以把一个公司比作一支军队。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-eafd55ab178a6bd_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&800& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic2.zhimg.com/v2-eafd55ab178a6bd_r.jpg&&&/figure&&p&《比利·林恩的中场战事》&/p&&p&想起在我职场初期发生的一件事。&/p&&p&两年前某个周六,深夜12点,上海。&/p&&p&“今天不修好这个bug,你明天就别来了!”伴随着老板在微信群里的怒吼,我的脑袋一嗡。&/p&&p&我坐在出租车上,极力让自己保持冷静,脑袋里不停回忆代码。&/p&&div class=&highlight&&&pre&&code class=&language-text&&class NewsController extends ApiController {
public function show(Request $request) {
$requestId = $request-&get('id');
// other stuff
&/code&&/pre&&/div&&p&我用手机打开Github阅读代码期间,微信上叮咚叮咚的消息提醒,敲打着我的神经,我深呼吸着不让自己的思路混乱,去发现代码中的问题。同时我还向产品经理解释发生的一切;期间不停有同事的消息,咨询发生了什么情况。&/p&&p&“I’m so fucked-up!” 我深感绝望。&/p&&p&周一。&/p&&p&我在办公室打开邮箱,看到一封邮件,标题为“周六资讯暂停事故报告”,我心一颤。&/p&&p&我怀着忐忑的心情打开邮件,看到是我老板发的,内容大致如下:&/p&&blockquote&周六,发生了一起重大的事故,我们App中的订阅资讯从下午开始停止更新长达半天时间,这对于我们用户,造成了极其恶劣的影响。&br&事情的起因是爬虫出现了问题,爬虫工程师决定先暂停爬虫,开发工程师在接收到消息后,并没有汇报。在我们恢复爬虫后,接收的API还出现了问题,最终问题在半夜得到修复。&br&&b&对此,我承担全部的责任。同时作为惩罚,我会请所有加班的同事喝咖啡。&/b&&br&同时,我对我在微信群里的失态道歉。&br&我们技术部会引以为戒,并深刻检讨,避免此类事件再次发生。&/blockquote&&p&作为刚入职公司不久,还是职场菜鸟的我,看到这封邮件的时候,震撼和内疚交织在心里,对于我老板的感激之情无以言表。在我搞出如此重大的事故之后,并没有开除我,反而主动承担事故的责任。&/p&&p&在我找老板谈话的时候,关于这次事故,老板并没有多言,“我帮你们抗大招,你们做好自己的事情就行了”。&/p&&p&&b&Watch your colleague’s back,这是从我当时的老板身上学习到的。&/b&&/p&&p&=======&/p&&p&对于职场新人,提升自己的代码能力会伴随着职场生涯。我从面试官的角度谈一下:&b&为何我给了一位三年工作经验No,一位应届生Yes。&/b&&/p&&p&“我前面被地图导航到了隔壁,我看时间来不及,就赶紧翻墙过来了。”这位三年工作经验的男生坐在我对面,还略微喘气。他身材瘦小,带着眼镜,刘海长短适中,穿着休闲的套装,不是特别标准的普通话夹着家乡的口音。“那我想问您,您遇到这样的情况,您会如何处理呢?”&/p&&p&“如果我遇到这样的情况”,我说道,“我肯定不会翻墙,以我的体积去翻墙,我肯定无法参加面试,因为我会被卡住。”我被自己的幽默逗乐了,“我肯定会骑共享单车,甚至打的。”&/p&&p&“哈哈哈。我了解了。”他被我的笑话感染,轻松了一些,然后开始做我出的题目。&/p&&p&面试结束后,我在反馈表上填下了自己的反馈,最后在是否推荐那一栏,我点击了No。&br&&/p&&p&第二天,来了位女生,是应届生,长长的头发带着眼镜,笑容和蔼。&br&在介绍自己和实习经历之后,我给她出题。&/p&&p&面试结束后,我和我的同事说,“她可以的”。&/p&&p&理论上,三年工作经验的程序员,应比应届生在各方面强很多,但最后我却给了那位应届生Yes。&/p&&p&拿一道简单的算法题举例:实现strStr函数,返回一个字符串在另一个字符串中出现的首个位置,如果没有找到,返回-1。先看下面两段代码(并不是面试题,根据当时的问题模拟了下面的代码):&br&&/p&&div class=&highlight&&&pre&&code class=&language-go&&&span class=&kd&&func&/span& &span class=&nx&&strStr&/span&&span class=&p&&(&/span&&span class=&nx&&a&/span&&span class=&p&&,&/span& &span class=&nx&&b&/span& &span class=&kt&&string&/span&&span class=&p&&)&/span& &span class=&kt&&int&/span& &span class=&p&&{&/span&
&span class=&nx&&len1&/span& &span class=&o&&:=&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&nx&&a&/span&&span class=&p&&)&/span&
&span class=&nx&&len2&/span& &span class=&o&&:=&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&nx&&b&/span&&span class=&p&&)&/span&
&span class=&k&&for&/span& &span class=&nx&&i&/span& &span class=&o&&:=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span& &span class=&nx&&i&/span& &span class=&p&&&&/span& &span class=&nx&&a&/span&&span class=&p&&;&/span& &span class=&nx&&i&/span&&span class=&o&&++&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&nx&&haystack&/span&&span class=&p&&[&/span&&span class=&nx&&i&/span&&span class=&p&&:&/span&&span class=&nx&&i&/span&&span class=&o&&+&/span&&span class=&nx&&len2&/span&&span class=&p&&]&/span& &span class=&o&&==&/span& &span class=&nx&&b&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&nx&&i&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-go&&&span class=&kd&&func&/span& &span class=&nx&&strStr&/span&&span class=&p&&(&/span&&span class=&nx&&haystack&/span& &span class=&kt&&string&/span&&span class=&p&&,&/span& &span class=&nx&&needle&/span& &span class=&kt&&string&/span&&span class=&p&&)&/span& &span class=&kt&&int&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&nx&&needle&/span& &span class=&o&&==&/span& &span class=&s&&&&&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&mi&&0&/span&
&span class=&p&&}&/span&
&span class=&k&&if&/span& &span class=&nx&&haystack&/span& &span class=&o&&==&/span& &span class=&s&&&&&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span&
&span class=&p&&}&/span&
&span class=&nx&&haystackLen&/span& &span class=&o&&:=&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&nx&&haystack&/span&&span class=&p&&)&/span&
&span class=&nx&&needleLen&/span& &span class=&o&&:=&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&nx&&needle&/span&&span class=&p&&)&/span&
&span class=&k&&for&/span& &span class=&nx&&i&/span& &span class=&o&&:=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span& &span class=&nx&&i&/span& &span class=&p&&&&/span& &span class=&nx&&haystackLen&/span&&span class=&p&&;&/span& &span class=&nx&&i&/span&&span class=&o&&++&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&nx&&i&/span&&span class=&o&&+&/span&&span class=&nx&&needleLen&/span& &span class=&p&&&&/span& &span class=&nx&&haystackLen&/span& &span class=&p&&{&/span&
&span class=&k&&break&/span&
&span class=&p&&}&/span&
&span class=&k&&if&/span& &span class=&nx&&haystack&/span&&span class=&p&&[&/span&&span class=&nx&&i&/span&&span class=&p&&:&/span&&span class=&nx&&i&/span&&span class=&o&&+&/span&&span class=&nx&&needleLen&/span&&span class=&p&&]&/span& &span class=&o&&==&/span& &span class=&nx&&needle&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&nx&&i&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&那位女生在做我出的第一道题时,在白板上写出了类似第二种的代码,我当时心里就有了些许判断,她的第二题发挥的不是很好,但我还是给了Yes;而第一位候选人的代码,类似第一种,问题在于:&/p&&ol&&li&变量命名不规范&/li&&li&没有考虑边际条件的处理&/li&&li&有潜在的bug&/li&&/ol&&p&因此,他没有列入我的候选名单。&/p&&p&鉴于此,我认为&b&新人需要磨砺自己写出优秀的代码,代码是职场进阶必备的技能点。&/b&&/p&&p&曾经收到过这样一封邮件:&br&&/p&&blockquote&我是xxx公司的小A,我们CEO看到您在github上面的Go代码,觉得您写的非常好,十分欣赏,想跟您彼此了解下,不知您是否在考虑北京的工作机会,或者只是简单的跟您技术交流,方便问下您现在在哪个城市么?希望得到您的回复,谢谢!&br&&/blockquote&&p&&b&优秀的代码给自己带来了工作机会。&/b&&/p&&p&如何提升自己的代码能力呢?我认为可以通过以下方法:&/p&&ul&&li&&b&阅读开源项目的代码&/b&:通过阅读代码,你不仅可以了解到整个社区是如何写代码的,从此不再闭门造车,而且还能理解各个技术的实现方式,比如路由,ORM等的实现。&/li&&li&&b&同事朋友之间code review&/b&:通过互相阅读代码,能获得对方的评论之外,同时还能发现对方代码的优劣,给自己思考的机会&/li&&li&&b&向A+等级的老师学习&/b&:我学习&b&&a href=&//link.zhihu.com/?target=https%3A//cn.udacity.com/course/front-end-web-developer-nanodegree--nd001-cn-advanced& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Udacity前端课程&/a&&/b&的时候,跟着&b&谷歌的工程师&a href=&//link.zhihu.com/?target=https%3A//github.com/igrigorik& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ilya Grigorik&/a&和&a href=&//link.zhihu.com/?target=https%3A//github.com/paullewis& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Paul Lewis&/a&学习浏览器性能优化,&/b&在其他项目比如Canvas中,做了这样一款闯关游戏(如下图),皮卡丘需要跨过所有其他神奇宝贝的阻碍,去到卡比兽的位置。&b&我在面试中直接拿出这个游戏和面试官谈项目经历,给面试官看代码&/b&:&/li&&/ul&&figure&&img src=&https://pic1.zhimg.com/v2-7ef55fbcfbbf0_b.jpg& data-caption=&& data-rawwidth=&800& data-rawheight=&915& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic1.zhimg.com/v2-7ef55fbcfbbf0_r.jpg&&&/figure&&p&&b&我相信通过努力,你,会成为一个更好的程序员。&/b&&/p&
我针对职场新人,谈一下自己的观点。从两方面切入:1)我认为重要的人格品质 2)如何提升代码能力。我以为,培养优秀的人格品质,同职场规划一样重要:权利的游戏S6E10,熊岛小领主Lyanna Mormont在会议上。你的儿子在红色婚礼上遇害 曼德勒大人 而你拒不奉…
&figure&&img src=&https://pic2.zhimg.com/v2-ca2fef3dadd9e011a3b097_b.jpg& data-rawwidth=&537& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&537& data-original=&https://pic2.zhimg.com/v2-ca2fef3dadd9e011a3b097_r.jpg&&&/figure&&h2&&b&一、softmax回顾&/b&&/h2&&p&&b&首先我们给出softma层的回顾。&/b&&/p&&p&&b&softmax用于多分类过程中&/b&,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!&/p&&p&假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个元素的softmax值就&img src=&https://www.zhihu.com/equation?tex=S_%7Bi%7D%3D%5Cfrac%7Be%5E%7Bi%7D%7D%7B%5Csum_%7Bj%7D%5E%7B%7D%7Be%5E%7Bj%7D%7D%7D& alt=&S_{i}=\frac{e^{i}}{\sum_{j}^{}{e^{j}}}& eeimg=&1&&&/p&&p&更形象的如下图表示:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-ece5a177f369b4675e67ef_b.jpg& data-rawwidth=&1328& data-rawheight=&792& class=&origin_image zh-lightbox-thumb& width=&1328& data-original=&https://pic2.zhimg.com/v2-ece5a177f369b4675e67ef_r.jpg&&&/figure&&p&softmax直白来说就是将原来输出是3,1,-3通过softmax函数一作用,就映射成为(0,1)的值为(0.88,0.12,0),而这些值的累和为1(满足概率的性质),那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!&/p&&h2&&b&二、存在问题&/b&&/h2&&p&当我们运算比较小的值的时候是不会有什么问题的,但是如果运算的值比较大的时候&b&,比&/b&如 &img src=&https://www.zhihu.com/equation?tex=x_%7Bn%7D& alt=&x_{n}& eeimg=&1&& 很大或很小的时候,朴素的直接计算会上溢出或下溢出,从而导致严重问题。&/p&&p&举个例子,对于[3,1,-3],直接计算是可行的,我们可以得到(0.88,0.12,0)。&/p&&p&但对于[00],却并不可行,我们会得到&b&inf(这也是深度学习训练过程常见的一个错误,看了本文之后,以后出现inf的时候,至少可以考虑softmax运算的上溢和下溢)&/b&;对于[-,-1000],还是不行,我们会得到-inf。&/p&&p&这是因为你的浮点数只有64位,在计算指数函数的环节,exp{1000} =inf,会发生上溢出;exp{-1000} =0,会发生下溢出。&/p&&h2&&b&三、解决办法&/b&&/h2&&p&&b&解决办法很简单:&/b&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-02b14afaef92e51ba5ba8efb5201813a_b.jpg& data-rawwidth=&676& data-rawheight=&142& class=&origin_image zh-lightbox-thumb& width=&676& data-original=&https://pic3.zhimg.com/v2-02b14afaef92e51ba5ba8efb5201813a_r.jpg&&&/figure&&p&对任意a都成立,这意味着我们可以自由地调节指数函数的指数部分,一个典型的做法是取 &img src=&https://www.zhihu.com/equation?tex=x_%7B1%7D%E3%80%81x_%7B2%7D....x_%7Bn%7D& alt=&x_{1}、x_{2}....x_{n}& eeimg=&1&&中的最大值:a=max{x1,x2.....xn}&/p&&p&&b&这可以保证指数最大不会超过0,于是你就不会上溢出。即便剩余的部分下溢出了,加了a之后,你也能得到一个合理的值。&/b&&/p&&h2&&b&四、正确性证明&/b&&/h2&&p&证明softmax不受输入的常数偏移影响,即&/p&&p&softmax(x)=softmax(x+c)&/p&&p&也就是证明加了偏移c之后,对整个softmax层的作用不起影响。如下:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-6cbcd3b3c6b17e46ac496e_b.jpg& data-rawwidth=&1046& data-rawheight=&274& class=&origin_image zh-lightbox-thumb& width=&1046& data-original=&https://pic4.zhimg.com/v2-6cbcd3b3c6b17e46ac496e_r.jpg&&&/figure&&p&希望对你理解有帮助~&/p&
一、softmax回顾首先我们给出softma层的回顾。softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个元素的softmax值就S_{i}=\frac{e^{i}}{…
&figure&&img src=&https://pic3.zhimg.com/v2-68bcef49d3ecbdcb99d711e7_b.jpg& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&https://pic3.zhimg.com/v2-68bcef49d3ecbdcb99d711e7_r.jpg&&&/figure&&h2&&b&0X000 蒙圈的我&/b&&/h2&&p&几天前,远方的妹纸给我发来微信,说她们组的导师心血来潮要搞Deep Learning,希望快速入门,让我给她指导一下,吖,我是拒绝呢,还是拒绝呢,哦?所以此系列文章,诞生了!&/p&&p&妹纸:花花,我们导师要我们弄深度学习,主要是图像的分类,最近我看了一些卷积神经网络的基本知识,你能给我讲讲常见的CNN架构吗,还有怎么写代码吖。&br&花花:唔,那我们从头最简单的架构讲起吧。(天哪,其实我也啥都不会啊,捂脸)&/p&&ul&&li&考虑到妹纸刚刚入门,我给她推荐了tensorflow,&/li&&li&又考虑到tf也不好写,我给她推荐了更high-level的Keras&/li&&li&用来学习的dataset,选用了&a href=&https://link.zhihu.com/?target=https%3A//www.cs.toronto.edu/%7Ekriz/cifar.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cifar-10&/a&. 原因有二,一是资料量足,二是image大小不会太大,训练起来时间不至于太久,写完代码很快能看到训练的效果。&/li&&/ul&&p&&br&&/p&&blockquote&&b&1. 所有代码都在
&a href=&https://link.zhihu.com/?target=https%3A//github.com/BIGBALLON/cifar-10-cnn& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Github&/a& 上 &/b& &br&&b&2. 介于妹纸需要学习的资料,我刚好整理了一下
&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&请戳我&/a&&/b& &/blockquote&&p&&br&&/p&&h2&&b&0X001 从LeNet开始&/b&&/h2&&p&花花:首先我们来讲第一个CNN Architecture : &a href=&https://link.zhihu.com/?target=http%3A//yann.lecun.com/exdb/lenet/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeNet&/a& ,它的架构图如下:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-623fcd6e365c88c4f52cfff4b83d8c3e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&877& data-rawheight=&240& class=&origin_image zh-lightbox-thumb& width=&877& data-original=&https://pic1.zhimg.com/v2-623fcd6e365c88c4f52cfff4b83d8c3e_r.jpg&&&/figure&&ul&&li&&b&input: &/b&在原始的架构中,神经网络的输入是一张 &img src=&https://www.zhihu.com/equation?tex=32%5Ctimes32& alt=&32\times32& eeimg=&1&& 的灰度图像,不过这里我们选用的dataset是cifar10,是RGB图像,也就是 &img src=&https://www.zhihu.com/equation?tex=32%5Ctimes32%5Ctimes3& alt=&32\times32\times3& eeimg=&1&& 噢&/li&&li&&b&conv1: &/b&第一层是一个卷积层啦,卷积核(kernel size)大小 &img src=&https://www.zhihu.com/equation?tex=5%5Ctimes5& alt=&5\times5& eeimg=&1&& ,步长(stride)为 &img src=&https://www.zhihu.com/equation?tex=1& alt=&1& eeimg=&1&& ,不进行padding哦,所以刚才的输入图像,经过这层后会输出6张 &img src=&https://www.zhihu.com/equation?tex=28%5Ctimes28& alt=&28\times28& eeimg=&1&& 的特征图(feature map)&/li&&li&&b&maxpooling2:&/b& 接下来是一个降采样层,用的是maxpooling哦,stride为 &img src=&https://www.zhihu.com/equation?tex=2& alt=&2& eeimg=&1&& , kernel size为 &img src=&https://www.zhihu.com/equation?tex=2%5Ctimes2& alt=&2\times2& eeimg=&1&& ,恩,所以很明显subsampling之后,输出6张 &img src=&https://www.zhihu.com/equation?tex=14%5Ctimes14& alt=&14\times14& eeimg=&1&&的feature map哦&/li&&li&&b&conv3: &/b&第三层又是一个卷积层,kernel size和stride均与第一层相同噢,不过最后要输出16张feature map哦&/li&&li&&b&maxpooling4:&/b&第四层,恩,又是一个maxpooling&/li&&li&&b&fc5:&/b&对,第五层开始就是全连接(fully connected layer)层了哦,把第四层的feature map摊平,然后做最直白的举证运算哦,输入是120个结点&/li&&li&&b&fc6:&/b&输出是84个结点哦&/li&&li&&b&output:&/b&我们的dataset是cifar10,刚好也是10类哦,所以就是接一个softmax分成10类哦&/li&&li&如果你看不太懂为什么卷积核是这样计算的,下面是两个非常不错的教程&/li&&ul&&li&&a href=&https://link.zhihu.com/?target=http%3A//cs231n.stanford.edu/slides/2017/cs231n_2017_lecture5.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Convolutional Neural Networks&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//cs231n.stanford.edu/slides/2017/cs231n_2017_lecture9.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CNN Architectures&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=https%3A//www.youtube.com/watch%3Fv%3DLxfUGhug-iQ%26list%3DPLkt2uSq6rBVctENoVBg1TpCC7OQi31AlC%26index%3D7& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&YouTube 视频&/a&&/li&&/ul&&/ul&&p&妹纸:恩,这个架构看起来还是比较简单,你讲得我大概懂了哦,那代码要怎么写呢?&br&花花:恩,我准备了4份代码,一一来看吧,shy&/p&&p&&br&&/p&&h2&&b&0X002 第一份简单的代码&/b&&/h2&&div class=&highlight&&&pre&&code class=&language-python3&&&span&&/span&&span class=&kn&&import&/span& &span class=&nn&&keras&/span&
&span class=&kn&&from&/span& &span class=&nn&&keras&/span& &span class=&k&&import&/span& &span class=&n&&optimizers&/span&
&span class=&kn&&from&/span& &span class=&nn&&keras.datasets&/span& &span class=&k&&import&/span& &span class=&n&&cifar10&/span&
&span class=&kn&&from&/span& &span class=&nn&&keras.models&/span& &span class=&k&&import&/span& &span class=&n&&Sequential&/span&
&span class=&kn&&from&/span& &span class=&nn&&keras.layers&/span& &span class=&k&&import&/span& &span class=&n&&Conv2D&/span&&span class=&p&&,&/span& &span class=&n&&Dense&/span&&span class=&p&&,&/span& &span class=&n&&Flatten&/span&&span class=&p&&,&/span& &span class=&n&&MaxPooling2D&/span&
&span class=&kn&&from&/span& &span class=&nn&&keras.callbacks&/span& &span class=&k&&import&/span& &span class=&n&&LearningRateScheduler&/span&&span class=&p&&,&/span& &span class=&n&&TensorBoard&/span&
&span class=&n&&batch_size&/span&
&span class=&o&&=&/span& &span class=&mi&&128&/span&
&span class=&n&&epochs&/span&
&span class=&o&&=&/span& &span class=&mi&&180&/span&
&span class=&n&&iterations&/span&
&span class=&o&&=&/span& &span class=&mi&&391&/span&
&span class=&n&&num_classes&/span&
&span class=&o&&=&/span& &span class=&mi&&10&/span&
&span class=&n&&log_filepath&/span&
&span class=&o&&=&/span& &span class=&s1&&'./lenet'&/span&
&span class=&k&&def&/span& &span class=&nf&&build_model&/span&&span class=&p&&():&/span&
&span class=&n&&model&/span& &span class=&o&&=&/span& &span class=&n&&Sequential&/span&&span class=&p&&()&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&Conv2D&/span&&span class=&p&&(&/span&&span class=&mi&&6&/span&&span class=&p&&,&/span& &span class=&p&&(&/span&&span class=&mi&&5&/span&&span class=&p&&,&/span& &span class=&mi&&5&/span&&span class=&p&&),&/span& &span class=&n&&padding&/span&&span class=&o&&=&/span&&span class=&s1&&'valid'&/span&&span class=&p&&,&/span& &span class=&n&&activation&/span& &span class=&o&&=&/span& &span class=&s1&&'relu'&/span&&span class=&p&&,&/span& &span class=&n&&kernel_initializer&/span&&span class=&o&&=&/span&&span class=&s1&&'he_normal'&/span&&span class=&p&&,&/span& &span class=&n&&input_shape&/span&&span class=&o&&=&/span&&span class=&p&&(&/span&&span class=&mi&&32&/span&&span class=&p&&,&/span&&span class=&mi&&32&/span&&span class=&p&&,&/span&&span class=&mi&&3&/span&&span class=&p&&)))&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&MaxPooling2D&/span&&span class=&p&&((&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&mi&&2&/span&&span class=&p&&),&/span& &span class=&n&&strides&/span&&span class=&o&&=&/span&&span class=&p&&(&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&mi&&2&/span&&span class=&p&&)))&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&Conv2D&/span&&span class=&p&&(&/span&&span class=&mi&&16&/span&&span class=&p&&,&/span& &span class=&p&&(&/span&&span class=&mi&&5&/span&&span class=&p&&,&/span& &span class=&mi&&5&/span&&span class=&p&&),&/span& &span class=&n&&padding&/span&&span class=&o&&=&/span&&span class=&s1&&'valid'&/span&&span class=&p&&,&/span& &span class=&n&&activation&/span& &span class=&o&&=&/span& &span class=&s1&&'relu'&/span&&span class=&p&&,&/span& &span class=&n&&kernel_initializer&/span&&span class=&o&&=&/span&&span class=&s1&&'he_normal'&/span&&span class=&p&&))&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&MaxPooling2D&/span&&span class=&p&&((&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&mi&&2&/span&&span class=&p&&),&/span& &span class=&n&&strides&/span&&span class=&o&&=&/span&&span class=&p&&(&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&mi&&2&/span&&span class=&p&&)))&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&Flatten&/span&&span class=&p&&())&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&Dense&/span&&span class=&p&&(&/span&&span class=&mi&&120&/span&&span class=&p&&,&/span& &span class=&n&&activation&/span& &span class=&o&&=&/span& &span class=&s1&&'relu'&/span&&span class=&p&&,&/span& &span class=&n&&kernel_initializer&/span&&span class=&o&&=&/span&&span class=&s1&&'he_normal'&/span&&span class=&p&&))&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&Dense&/span&&span class=&p&&(&/span&&span class=&mi&&84&/span&&span class=&p&&,&/span& &span class=&n&&activation&/span& &span class=&o&&=&/span& &span class=&s1&&'relu'&/span&&span class=&p&&,&/span& &span class=&n&&kernel_initializer&/span&&span class=&o&&=&/span&&span class=&s1&&'he_normal'&/span&&span class=&p&&))&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&Dense&/span&&span class=&p&&(&/span&&span class=&mi&&10&/span&&span class=&p&&,&/span& &span class=&n&&activation&/span& &span class=&o&&=&/span& &span class=&s1&&'softmax'&/span&&span class=&p&&,&/span& &span class=&n&&kernel_initializer&/span&&span class=&o&&=&/span&&span class=&s1&&'he_normal'&/span&&span class=&p&&))&/span&
&span class=&n&&sgd&/span& &span class=&o&&=&/span& &span class=&n&&optimizers&/span&&span class=&o&&.&/span&&span class=&n&&SGD&/span&&span class=&p&&(&/span&&span class=&n&&lr&/span&&span class=&o&&=.&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&n&&momentum&/span&&span class=&o&&=&/span&&span class=&mf&&0.9&/span&&span class=&p&&,&/span& &span class=&n&&nesterov&/span&&span class=&o&&=&/span&&span class=&kc&&True&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&compile&/span&&span class=&p&&(&/span&&span class=&n&&loss&/span&&span class=&o&&=&/span&&span class=&s1&&'categorical_crossentropy'&/span&&span class=&p&&,&/span& &span class=&n&&optimizer&/span&&span class=&o&&=&/span&&span class=&n&&sgd&/span&&span class=&p&&,&/span& &span class=&n&&metrics&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'accuracy'&/span&&span class=&p&&])&/span&
&span class=&k&&return&/span& &span class=&n&&model&/span&
&span class=&k&&def&/span& &span class=&nf&&scheduler&/span&&span class=&p&&(&/span&&span class=&n&&epoch&/span&&span class=&p&&):&/span&
&span class=&n&&learning_rate_init&/span& &span class=&o&&=&/span& &span class=&mf&&0.02&/span&
&span class=&k&&if&/span& &span class=&n&&epoch&/span& &span class=&o&&&=&/span& &span class=&mi&&80&/span&&span class=&p&&:&/span&
&span class=&n&&learning_rate_init&/span& &span class=&o&&=&/span& &span class=&mf&&0.01&/span&
&span class=&k&&if&/span& &span class=&n&&epoch&/span& &span class=&o&&&=&/span& &span class=&mi&&150&/span&&span class=&p&&:&/span&
&span class=&n&&learning_rate_init&/span& &span class=&o&&=&/span& &span class=&mf&&0.004&/span&
&span class=&k&&return&/span& &span class=&n&&learning_rate_init&/span&
&span class=&k&&if&/span& &span class=&n&&__name__&/span& &span class=&o&&==&/span& &span class=&s1&&'__main__'&/span&&span class=&p&&:&/span&
&span class=&c1&&# load data&/span&
&span class=&p&&(&/span&&span class=&n&&x_train&/span&&span class=&p&&,&/span& &span class=&n&&y_train&/span&&span class=&p&&),&/span& &span class=&p&&(&/span&&span class=&n&&x_test&/span&&span class=&p&&,&/span& &span class=&n&&y_test&/span&&span class=&p&&)&/span& &span class=&o&&=&/span& &span class=&n&&cifar10&/span&&span class=&o&&.&/span&&span class=&n&&load_data&/span&&span class=&p&&()&/span&
&span class=&n&&y_train&/span& &span class=&o&&=&/span& &span class=&n&&keras&/span&&span class=&o&&.&/span&&span class=&n&&utils&/span&&span class=&o&&.&/span&&span class=&n&&to_categorical&/span&&span class=&p&&(&/span&&span class=&n&&y_train&/span&&span class=&p&&,&/span& &span class=&n&&num_classes&/span&&span class=&p&&)&/span&
&span class=&n&&y_test&/span& &span class=&o&&=&/span& &span class=&n&&keras&/span&&span class=&o&&.&/span&&span class=&n&&utils&/span&&span class=&o&&.&/span&&span class=&n&&to_categorical&/span&&span class=&p&&(&/span&&span class=&n&&y_test&/span&&span class=&p&&,&/span& &span class=&n&&num_classes&/span&&span class=&p&&)&/span&
&span class=&n&&x_train&/span& &span class=&o&&=&/span& &span class=&n&&x_train&/span&&span class=&o&&.&/span&&span class=&n&&astype&/span&&span class=&p&&(&/span&&span class=&s1&&'float32'&/span&&span class=&p&&)&/span&
&span class=&n&&x_test&/span& &span class=&o&&=&/span& &span class=&n&&x_test&/span&&span class=&o&&.&/span&&span class=&n&&astype&/span&&span class=&p&&(&/span&&span class=&s1&&'float32'&/span&&span class=&p&&)&/span&
&span class=&n&&x_train&/span& &span class=&o&&/=&/span& &span class=&mi&&255&/span&
&span class=&n&&x_test&/span& &span class=&o&&/=&/span& &span class=&mi&&255&/span&
&span class=&c1&&# build network&/span&
&span class=&n&&model&/span& &span class=&o&&=&/span& &span class=&n&&build_model&/span&&span class=&p&&()&/span&
&span class=&nb&&print&/span&&span class=&p&&(&/span&&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&summary&/span&&span class=&p&&())&/span&
&span class=&c1&&# set callback&/span&
&span class=&n&&tb_cb&/span& &span class=&o&&=&/span& &span class=&n&&TensorBoard&/span&&span class=&p&&(&/span&&span class=&n&&log_dir&/span&&span class=&o&&=&/span&&span class=&n&&log_filepath&/span&&span class=&p&&,&/span& &span class=&n&&histogram_freq&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&change_lr&/span& &span class=&o&&=&/span& &span class=&n&&LearningRateScheduler&/span&&span class=&p&&(&/span&&span class=&n&&scheduler&/span&&span class=&p&&)&/span&
&span class=&n&&cbks&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&n&&change_lr&/span&&span class=&p&&,&/span&&span class=&n&&tb_cb&/span&&span class=&p&&]&/span&
&span class=&c1&&# start traing &/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&fit&/span&&span class=&p&&(&/span&&span class=&n&&x_train&/span&&span class=&p&&,&/span& &span class=&n&&y_train&/span&&span class=&p&&,&/span&&span class=&n&&batch_size&/span&&span class=&o&&=&/span&&span class=&n&&batch_size&/span&&span class=&p&&,&/span&&span class=&n&&epochs&/span&&span class=&o&&=&/span&&span class=&n&&epochs&/span&&span class=&p&&,&/span&&span class=&n&&callbacks&/span&&span class=&o&&=&/span&&span class=&n&&cbks&/span&&span class=&p&&,&/span&
&span class=&n&&validation_data&/span&&span class=&o&&=&/span&&span class=&p&&(&/span&&span class=&n&&x_test&/span&&span class=&p&&,&/span& &span class=&n&&y_test&/span&&span class=&p&&),&/span& &span class=&n&&shuffle&/span&&span class=&o&&=&/span&&span class=&kc&&True&/span&&span class=&p&&)&/span&
&span class=&c1&&# save model&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&save&/span&&span class=&p&&(&/span&&span class=&s1&&'lenet.h5'&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&花花:main函数里面的东西你先不要管哦,就是用来读取training data以及进行训练的,&br&我们先来看build_model()这个函数。&/p&&ul&&li&最开始有一个Sequential模型,中文好像叫做序贯模型??它用于多个网络层的线性堆叠,也就是“一条路走到黑”,所以我们后面都在用model.add来添加新的layer啦。&/li&&li&紧接着就是Conv2D,这个是keras内建的卷积层哦,具体的参数你可以在&a href=&https://link.zhihu.com/?target=https%3A//keras.io/layers/convolutional/%23conv2d& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&官方文档&/a&里面找到噢,当然,还有某群聚聚们写的&a href=&https://link.zhihu.com/?target=https%3A//keras-cn.readthedocs.io/en/latest/layers/convolutional_layer/%23conv2d& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Keras中文文档&/a&哦。你可以看到我这里设置了输出卷积核的数目,卷积核的大小,移动的步长,激活函数等等哦。&/li&&li&再来就是MaxPooling2D,池化层啦,也很简单哦,按照我们前面介绍的架构来写参数就对了。&/li&&li&最后是用Flatten层来将输入“压平”,然后用最常用的全连接Dense层啦,记得最后的激活函数是softmax哦。&/li&&li&然后我们需要确定我们的目标函数,以及我们的优化器,并用compile把它们编译起来(这里我们的loss是cross entropy,opt是SGD,嗯嗯)&br&这样,整个model就完成啦,就才几行,是不是很简单!&/li&&/ul&&p&妹纸:恩,代码只有不到60行,还是很容易看懂的。&br&花花:恩,这份代码很“朴实”,没有加其他任何trick,不过它的效果不太好噢。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6ec4c95c636aad244d27deb4_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&534& data-rawheight=&380& class=&origin_image zh-lightbox-thumb& width=&534& data-original=&https://pic3.zhimg.com/v2-6ec4c95c636aad244d27deb4_r.jpg&&&/figure&&p&花花:刚才的代码&a href=&https://link.zhihu.com/?target=https%3A//github.com/BIGBALLON/cifar-10-cnn/blob/master/1_Lecun_Network/LeNet_keras.py& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeNet_keras.py&/a&,我们训练180个epoch,在GTX980TI上仅仅需要6分36秒的时间。但是它的testing准确度只有&b&53.87%(图中的桔黄色线)&/b&,好低啊。&/p&&p&&br&&/p&&h2&&b&0X003 一点点修改:数据预处理(data prepossessing)&/b&&/h2&&p&我们只对第一份代码改一个地方:&br&&a href=&https://link.zhihu.com/?target=https%3A//github.com/BIGBALLON/cifar-10-cnn/blob/master/1_Lecun_Network/LeNet_keras.py& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeNet_keras.py&/a& &img src=&https://www.zhihu.com/equation?tex=%5Crightarrow& alt=&\rightarrow& eeimg=&1&&&a href=&https://link.zhihu.com/?target=https%3A//github.com/BIGBALLON/cifar-10-cnn/blob/master/1_Lecun_Network/LeNet_dp_keras.py& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeNet_dp_keras.py&/a&&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span&&/span&&span class=&n&&mean&/span&
&span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&mf&&125.307&/span&&span class=&p&&,&/span& &span class=&mf&&122.95&/span&&span class=&p&&,&/span& &span class=&mf&&113.865&/span&&span class=&p&&]&/span&
&span class=&n&&std&/span&
&span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&mf&&62.9932&/span&&span class=&p&&,&/span& &span class=&mf&&62.0887&/span&&span class=&p&&,&/span& &span class=&mf&&66.7048&/span&&span class=&p&&]&/span&
&span class=&k&&for&/span& &span class=&n&&i&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&mi&&3&/span&&span class=&p&&):&/span&
&span class=&n&&x_train&/span&&span class=&p&&[:,:,:,&/span&&span class=&n&&i&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&p&&(&/span&&span class=&n&&x_train&/span&&span class=&p&&[:,:,:,&/span&&span class=&n&&i&/span&&span class=&p&&]&/span& &span class}

我要回帖

更多关于 收视率 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信