精华内容
下载资源
问答
  • 大学生在校这么学习,毕业不愁找不到高薪工作!

    前言

    大家好,我是龙叔,一直以来都有一些大学生粉丝私聊向我“取经”,可以看得出来很多人对前路多多少少都有些迷茫,我把大家的问题总结了一下,并对每个问题都做了我自己的见解,高频出现的问题有以下6个:

    1.国内程序员的薪资是怎么样的?
    .
    2.互联网行业真实前景有那么好吗?
    .
    3.我现在的情况适合做程序员?
    .
    4.大学期应该学哪些技术才能脱颖而出?
    .
    5.程序员那么多种,我适合哪种?
    .
    6.快毕业了,是去工作还是去考研?

    如果你有相同的疑虑,那么请认真读完我这篇文章,你一定会有所收获,在程序员这条道上少走很多弯路。话不多说,我们进入正题。
    在这里插入图片描述


    一、程序员的薪资是怎么样的?

    这是大学生非常关心的点,作为应届生出来之后,程序员的薪资是怎么样的?根据我这些年的经验和见闻,程序员的薪资可以分为3类,并且都跟所在城市级别有关:

    1.一线城市一线大厂超过1.5万/月。
    作为应届生,能进入华为、京东、阿里这样的国内顶尖企业,就职薪资一般会在1.5万/月,但不同于其他公司的是这些公司会是16薪、18薪和20薪的形式,一般的公司是12薪,每个月都发差不多的工资,那么在16薪的公司工作,也就是说在年终或者某个月,你可以拿到多4个月的薪资。

    像我没退休之前的公司,14薪的标准,跟一线大厂有一定差距,但比同行业来讲,在程序员的待遇上算还可以的。

    2.一线城市一般公司1~1.5万/月。
    应届生的能力有限,一线大厂不是谁都能进的,但还是有很多毕业生会选择待在一线城市,因为那里的薪资也不错,一般的毕业生薪资会在1~1.5万/月。

    毕业了去一线打拼是大多数程序员的选择,如果能在一线城市扎稳脚跟,那么你就能在起跑线上超过了很多小伙伴,一线城市的机遇也很多,若是赶上风口那飞起来一点也不夸张;你也可以选择工作三五年之后积累了较为可观的资本后退出一线城市,去节奏慢一点的地方发展。

    所以我的建议是,毕业想当程序员的小友,尽量不要回家,先去一线去打拼一波是最有益的。
    在这里插入图片描述
    3.二~~五线城市平均5000~8000/月。
    二线城市的薪资相对于一线城市是少了很多,不过生活成本也相对低很多,生活节奏也会慢很多,应届生的平均工资在5~8K,我这里指的是平均工资,其实2千工资的程序员我也听过,不过你为什么拿两千,你去对比一下那些拿正常薪资的人你就知道差距了。


    二、互联网行业真实前景有那么好吗?

    互联网行业毫无疑问是很有前景的一个行业,中央在2019年提出的中国制造和5G建设目前还处于发展中,远的不说,5年是需要的,5年之后风口在哪我不知道,但我觉得互联网行业依然是未来的重头戏。

    大学生如果想专攻某个互联网领域的话,未来比较推荐的互联网领域有大数据、VR、AR以及面向5G开发,根据我的经验,人工智能不建议大学毕业生进入,这个领域基本上招聘的人才需求都是顶尖学历(比如博士)和顶尖人才(多年工作的技术专家),对于大学生来讲一般很难应聘上。

    如果你觉得上面所说的互联网领域离你比较遥远,也可以尝试目前主流的开发岗位,比如前端、后端开发、网络安全、嵌入式开发等等,找个薪资不错的工作是没有问题的。
    在这里插入图片描述


    三、我现在的情况适合做程序员?

    这是一个比较常见的问题了,很多人甚至是学计算的人,他们都会问我说“我到底适不适合做程序员”,那么对于这个问题,基本上接触了编程1年左右的时间就能判断出来,主要通过以下几种:

    1.喜欢用代码决胜千里之外的人,适合做程序员

    不管你是不是科班出生,如果你喜欢敲代码的感觉,喜欢用代码构建世界,喜欢通过代码决胜千里之外的成就感,那么我觉得你很适合当程序员,而且只要不断努力,你必定能在互联网行业有所建树。

    2.抵触写代码的人,不适合做程序员

    如果你看到代码或者想到写代码就很抵触、反感,甚至看到代码就想吐,那么你是不适合当程序员的。

    讲个我身边的例子,我大学刚出来的时候跟我室友一起去同一家当实习生,在实习期间要学的东西很多,每天都是跟代码、算法打交道,我室友就特别反感写代码,那时候我们俩能在网吧玩传奇玩一整个通宵,但是他在座子上坐不到1个小时就得出去抽烟,他不是烟瘾很重的人,他就是出去待着,他说看到代码就头晕和反感,结果最后他没待到1个月就辞职了去其他公司做运营岗位了。

    如果说你也是这么害怕和反感写代码,你觉得你趁早去学你感兴趣的东西、做你喜欢的行业。
    在这里插入图片描述

    3.对代码不抵触但也谈不上喜欢的人,可试试“日久生情”

    这种情况是最常见的,自己对写代码这个事情并没有很反感,多多少少有一些念想或者小成就在支撑,但也谈不上很喜欢,因为写代码讲究思维、烧脑子,又或者是因为技术之路感觉长路漫漫,那么这种情况,我建议是你坚持学下去。

    只要通过你自己的不断学习,那些你觉得陌生的东西,慢慢就会熟悉了,不管你是冲着月薪上万,还是想做一个酷酷的技术高手,你只要试着跟它相处久了,你会逐渐跟它“日久生情”,最后找到喜欢的感觉。


    四、大学期间到底应该学些什么?

    在回答这个问题的时候,我突然想起了我大学刚毕业的时候,那时候刚进入工作岗位,很拼,但之余留给我的学习时间不多,而我要学的东西还有很多很多,就特别后悔我自己,为什么大学不好好学,浪费了那么时间,去做了很多没有多大用处的事情。

    如果让我的大学重来一次,我必定会这么去学习:

    1.文化课

    千万不要小瞧文化课,比如我们的英语、高数、统计学和概率学等等,一定要打好基础,程序员的很多项目资料、技术文献都是用英语写的,很多算法是需要高数等知识。

    举个例子,很多小伙伴因为英语基础不好,所以在安装开发环境的时候喜欢用破译的中文版软件,我是不建议这么做的。我都建议大家用英文版的,千万别汉化,就好比学车学自动挡还是手动挡,学了手动挡的人,你去开自动挡是没有什么问题的,但学自动挡的人去开手动挡就不行,软件也是一样,用惯了破译的中文版软件,你对英文原版的软件将会束手无策。

    还有,千万别挂科。
    在这里插入图片描述

    2.选1门语言精通

    不管是Java、Python、还是PHP,又或者是GO语言还是其他的什么语言,都是可以的,你只要选择1门语言深入学习,直到你掌握了90%以上,你就精通了,千万不要什么都会一点但又不精通,这样你不仅没有优势,而且没有趁手的工具(语言),你很难干成什么事情。

    3.掌握好数据结构和算法

    在你掌握了1门语言之后,这2个是你最应该去掌握的东西。在程序员界有一句流传的话“好程序=数据结构+算法”,就算你精通语言的API,但那都是表层东西,数据结构和算法才是里层东西,如果你的里层(除开硬件不讲)很垃圾,你表层再厉害你也挡不住1亿的并发。

    这个东西在大学的时候要好好掌握,你出来之后想学不一定会有,市面上那些培训机构很少有把数据结构和算法讲得很透彻的,还是大学的时候去学习是最稳妥的,大学的学习资源是很丰富的,要好生利用。
    在这里插入图片描述

    4.掌握数据库

    无论是SQL数据库还是NoSQL数据库,建议你都精通1个,就算是人工智能和大数据方面,数据库都是必不可少的,都需要数据库来进行数据存储,而在一个公司里面,跟数据打交道的程序员薪资都比较高,就好比做前端的薪资没有DBA高。

    如果你精力和时间允许的情况下,建议你选择一个热门数据库去学习并精通,比如MySQL。

    5.学好网络原理

    虽然说这只是原理,并且在最开始工作的时候你可能用得不多,但并不代表它可有可无,而是你技术层面还没达到,当你的技术层面达到了,你会发现这玩意儿它真的很重要,而1个优秀的程序员或者说1个技术高手,对网络原理是很熟悉的。

    网络原理涉及的知识有很多,比如七层结构,比如LP规划、HTTP、DNS等等理论知识,掌握好了之后才能让软件具备较高的性能,比如说做出来的直播软件没有卡顿。如果你不懂得网络原理或者一知半解,那么你写出来的程序员并不会很好用。
    在这里插入图片描述

    6.做1个可持续维护的项目

    与其说这里找1个速成的项目做或者那里找1个源码看看效果,倒不如你自己认真地去做1个可持续维护的项目,这样你才能持续地巩固知识、见证自己的成长,并且能自信地拿得出来。

    比如说你去做1个类似CSDN的博客网站,在一开始你学习前后端的时候掌握的技术不是很多,你做出来的web网址很low,但没有关系,你继续学习,学到了之后自己去给它添加更多模块,比如说给它添加视频模块,比如说给它添加24小时热度排行榜的功能等等。

    记住,这个项目不要去找开源的,那对你来说没什么意义,你要自己去写代码,不断地完善和维护这个网站,最后你会因为这个成果感到有成就感,到最后我相信,你一定会比一般的毕业生优秀很多。
    在这里插入图片描述


    五、程序员那么多种,我适合哪种?

    很多还没工作的小伙伴可能对外面的程序员岗位的种类不是很了解,什么这个工程师啊那个高级工程师之类的,很多头衔,搞得自己都眼花缭乱,根本不知道自己以后想成为哪种程序员。

    那么我来给你们总结一下,看完之后你自己可以做个判断,目前社会上工作的程序员主要分为以下几个方面:

    1.算法工程师

    这类程序员相当于“程序员界的科学家”,技术相当牛逼,基本都是华为、阿里、百度等顶尖名企工作,他们的工作主要就是跟算法打交道,比如说机器学习、图形图像处理、自然语言处理等等,不用说也知道,这种程序员的薪资是最高的。

    算法工程师比较适合于爱研究的人、喜欢研究数学且耐得住寂寞的人,像我之前从一家上市公司挖过来的一个算法工程师,他就特别喜欢做研究,天生就如此,脑子对数学和算法这种东西就特别敏感。

    2.客户端开发工程师

    这是目前市面上需求量最大的工程师,比如说IOS开发、安卓开发、开发前端网页、开发桌面系统等等,他们就可以统称为客户端开发工程师。

    目前不管是机构培训出来的,还是从学校毕业出来的,大多数人都是做这类职业,工作也不是很难找,毕竟目前市场上还是供不应求。
    在这里插入图片描述

    3.研发工程师

    研发工程师跟上面的客户端开发工程师有点类似,但是不同的是,研发工程师做的都是后端的东西,用户看不着的东西,比如用C、C++或Java去做搜索引擎系统的程序员,这类程序员也会用到算法,属于公司的核心人才。

    研发工程师的需求量也很大,架构师的很大一部分都是研发工程师转换升级而来。

    4.数据研发工程师

    跟字面意思差不多,就是跟数据打交道,这种程序员基本是整个公司薪资最高的,不过它不是每个程序员都能做的,它不光需要你是一个程序员,而且需要你有统计学背景,二者缺一不可。

    5.测试工程师

    这个就很有意思了,之前有小伙伴问我说“测试工程师是不是不用写代码?”测试工程师跟很多人想的不一样,测试工程师也需要写代码,它的工作内容就是通过自己写的代码来检验前端、后端等程序员写的代码有没有BUG,所以它并不是很多人眼里那样拿着手机或电脑玩玩游戏、测试下游戏bug这种样子。

    不过我个人不太建议大家去做这个,风险比较大,一般小公司花钱去一个测试工程师做代码测试,一般都要求前后端的程序员自己会写代码测试BUG,不过看公司规模和产品要求,有的公司对产品很看重,会有专门的测试工程师,但我建议大家作为1个辅助技能就好了。
    在这里插入图片描述

    6.安全工程师

    安全工程师是1类很博学的程序员,他们往往需要精通多门语言,主要工作是处理安全隐患来保证系统的安全运行。

    网络安全工程师要学的东西比较多,基础的黑客知识是必须掌握的,比如漏洞测试工具和远程工具RATS;技术基础也要扎实,AWVS、Nmap、Web安全基础、Malego建议都了解或掌握;Web安全漏洞分析和防御也很重要。攻击、Kail渗透、安全开发、Android安全、系统内核攻防,都是网络安全需要学习的技术。

    这是1个很酷的职业,比较适合有极客精神的人。

    7.UED工程师

    UED工程师与UI平面设计师是不同的,UED工程师又叫用户体验设计,UED是进行产品策划的主力之一,他们用自己的知识、经验、设计能力拿出设计方案。UED不只是互联网专家,还是行业专家。能够用自己的互联网知识来设计出行业专家想实现的操作,而付诸于商业营销。
    例如一个产品做出来,大家不知道用户是不是喜欢这个产品,这个时候,就需要UED来针对用户的需求,对产品进行改造。把产品设计为用户喜欢的样子,从而更好的迎合市场。
    在这里插入图片描述
    UED工程师还是比较适合女孩子去做的,女生比较心细,而且薪资也很不错,行业内也有一些牛逼的UED工程师。


    六、快毕业了,是去工作还是考研?

    “能考研肯定是要去考研的。”
    这一点我从来都是这么坚定地回答。互联网行业现在不像十几年前没学历有技术也不愁工作,现在如果你是高中或者中专学历,你基本没戏,学历是互联网行业的敲门砖,不管是顶尖大厂还是普通公司,给高学历人才开的薪资普遍比低学历高。

    但我得提醒大家一句:有了学历不代表长久高薪,程序员更看重的是动手能力。

    所以考上研之后你更要好好学习。

    在这里插入图片描述

    文章到这里就结束了,感谢你的观看,只是有些话想对读者们说说。

    我退休后一直在学习如何写文章,说实在的,每次在后台看到一些读者的回应都觉得很欣慰,对于自媒体我是个刚入门的人,还是个中年大叔…为了感谢读者们,我想把我收藏的一些编程干货贡献给大家,回馈每一个读者,希望能帮到你们。

    干货主要有:

    ① 2000多本Python电子书(主流和经典的书籍应该都有了)

    ② Python标准库资料(最全中文版)

    ③ 项目源码(四五十个有趣且经典的练手项目及源码)

    ④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

    ⑤ Python学习路线图(告别不入流的学习)

    如果你用得到的话可以直接拿走,看我的个人介绍。

    在这里插入图片描述

    展开全文
  • 蓝牙开发经验总结

    千次阅读 2017-01-15 17:45:15
    蓝牙开发经验总结

    文章部分转自
    https://my.oschina.net/oywk/blog/701362
    http://www.cnblogs.com/shang53880/p/4624955.html
    https://github.com/xiaoyaoyou1212/BLE

    1、不能使用BluetoothAdapter.startLeScan(UUID[] serviceUuids, LeScanCallback callback)函数扫描自定义UUID的蓝牙模块。亲测了很久,网络上也没有解决方案,源码上也追踪不到
    这里写图片描述
    源码如下
    这里写图片描述
    这里我用的UUID是从pc串口中更改好之后读出的
    这里写图片描述
    这里写图片描述
    http://blog.csdn.net/u010800708/article/details/52243359

    备注:BluetoothAdapter.startLeScan(UUID[] serviceUuids, LeScanCallback callback)的解决办法BluetoothDevice.connectGatt()在连接成功之后有一个BluetoothGattCallback回调接口,在BluetoothGattCallback回调接口中有onConnectionStateChange回调方法,这个方法在设备与app连接好之后会执行,而且相关蓝牙的服务在此可以获取bluetoothGatt.discoverServices();本人认为,由于没有产生连接所以不会返回蓝牙服务,所以BluetoothAdapter.startLeScan(UUID[] serviceUuids, LeScanCallback callback)过滤指定UUID设备的做法也就不行了,所以需要在onServicesDiscovered回调方法这里采用BluetoothGattService bluetoothGattService = bluetoothGatt.getService(UUID.fromString(Constant.UUID_STR));来获取蓝牙的tx,rx通道,并过滤指定UUID蓝牙设备。

    2、在使用 BluetoothDevice.connectGatt() 或者 BluetoothGatt.connect() 等建立 BluetoothGatt 连接的时候,在任何时刻都只能最多一个设备在尝试建立连接。如果同时对多个蓝牙设备发起建立 Gatt 连接请求。如果前面的设备连接失败了,后面的设备请求会被永远阻塞住,不会有任何连接回调。
    开发建议:如果要对多个设备发起连接请求,最好是有一个同一个的设备连接管理,把发起连接请求序列化起来。前一个设备请求建立连接,后面请求在队列中等待。如果连接成功了,就处理下一个连接请求。如果连接失败了(例如出错,或者连接超时失败),就马上调用 BluetoothGatt.disconnect() 来释放建立连接请求,然后处理下一个设备连接请求。

    3、对BluetoothGatt 操作 (read/write)Characteristic(), (read/write)Descriptor() 和 readRemoteRssi() 都是异步操作。需要特别注意的是,同时只能有一个操作,也就是等上一个操作回调(例如onCharacteristicWrite())以后,再进行下一个操作。
    开发建议:把这写操作都封装成同步操作,一个操作回调之前,阻塞主其他调用。或者用标志位来标志状态

    4、BLE设备的建立和断开连接的操作,例如 BluetoothDevice.connectGatt(), BluetoothGatt.connect(), BluetoothGatt.disconnect(),BluetoothGatt.discoverServices()等操作最好都放在主线程中,否则你会遇到很多意想不到的麻烦。
    开发建议:对 BluetoothGatt 的连接和断开请求,都通过发送消息到 Android 的主线程中,让主线程来执行具体的操作。例如创建一个 new Handler(context.getMainLooper());,把消息发送到这个 Handler 中。

    5、Android 作为中心设备,最多只能同时连接 6 个 BLE 外围设备(可能不同的设备这个数字不一样),超过 6 个,就会连接不上了。现在 BLE 设备越来越多,其实并不够用,所以在开发的过程中,需要特别的谨慎使用。
    开发建议:按照需要连接设备,如果设备使用完了,应该马上释放连接(调用BluetoothGatt.close()),腾出系统资源给其他可能的设备连接。

    6、发起蓝牙Gatt连接 BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback),这里有一个参数autoConnect,如果为 true 的话,系统就会发起一个后台连接,等到系统发现了一个设备,就会自动连上,通常这个过程是非常慢的。为 false 的话,就会直接连接,通常会比较快。同样,BluetoothGatt.connect()只能发起一个后台连接,不是直接连接。所以这个地方需要小心。

    展开全文
  • python kivy 开发经验总结

    万次阅读 多人点赞 2018-01-19 19:09:05
    python kivy 开发经验总结 kivy 是一款 python 的GUI开发框架,特点是样式可以和代码分离,绘图功能基于OpenGL编写,可以用来开发比较炫的界面,并且可以打包为Android、iOS等移动应用,还能运行在Linux、Windows、...

    python kivy 开发经验总结

    kivy 是一款 python 的GUI开发框架,特点是样式可以和代码分离,绘图功能基于OpenGL编写,可以用来开发比较炫的界面,并且可以打包为Android、iOS等移动应用,还能运行在Linux、Windows、MacOS上。

    这篇博客将记录我使用kivy开发的经验,所以会持续更新,且篇幅较长,是一篇kivy开发的技术笔记,欢迎大家留言交流。

    缘起-项目介绍

    我们塔尔旺科技有限公司准备开发一款能对图片进行画框标注的程序,因为是内部使用,所以选用 python kivy 作为GUI框架。之前从网上已经得知 kivy 虽然有专业团队支撑,但是框架不如 pyQt 或者 wxWindow 成熟,由于太容易上手,并且很喜欢kivy的样式分离的模式,所以依然决定使用一次。

    入门

    首选需要阅读 kivy 入门教程,读一遍Introduction 和 Programming Guide,写几个小例子,基本就差不多了。

    kivy 中的几个概念还是比较容易理解,如果做过 android 开发,会发现和 android 程序的开发模式很相似。例如都有 app 生命周期,通过重写 app 的 on_start() 等方法可以在各种生命周期状态下执行操作。

    主要的概念有:
    1. Application
    2. Widget
    3. Event
    4. Property
    5. KV Design Language
    6. Layout
    7. OpenGL Drawing Instructions

    上面这些内容,都可以在 kivy 入门教程 中找到。

    下面记录的就是我们在开发中积累的一些经验了。

    Layout 相关经验总结

    关于 FloatLayout

    这个布局,会看子 Widget 的 pos_hintsize_hint,依据他们来计算子 Widget 的位置和大小,还可以用子 Widget 的 pos 属性来指定自己的位置 (用的是窗口坐标系)。

    pos_hintsize_hint 这两个属性的取值都是 0 到 1,并且 size_hint 默认值是 1 , 所以可以用 FloatLayout 实现完全填充父容器的效果。

    因此,可以简单的理解为:
    1. FloatLayout 的子 Widget 可以定位到任意位置
    2. FloatLayout 的子 Widget 大小可以充满整个父容器,或为父容器的几分之一。

    关于 AnchorLayout

    这个布局需要注意,它只能设置一种位置关系,所有的子容器都使用该关系进行定位。

    定位的参数要靠 AnchorLayout 对象的 anchor_x 和 anchor_y 属性来确定,而不是像其他的 Layout 类,依靠子 Widget 的 pos_hint 属性来设置Widget的位置。这给使用带来了不便,也是容易误解的一大问题。

    小技巧:可以用 FloatLayout + AnchorLayout 来实现居中的效果。例如下面的KV language:

    <MainWindow>: # float layout
        AnchorLayout:   # 小技巧,居中子Widget
            LabelManager: # relative layout
                id: label_manager
                size_hint: None, None
                size: '800dp', '800dp'
    #            canvas:
    #                Color:
    #                    rgb: 0, 1, 0
    #                Rectangle:
    #                    pos: (0, 0)         # relative 的容器,位置要使用0,0,对自己的canvas已经使用了局部坐标系
    #                    size: self.size
                ImageWidget:
                    id: image
                    label_manager: label_manager
                    pos_hint: {'x':0, 'y':0}
                    size: self.parent.size
        Button:
            pos_hint: {'x':0, 'y':0}
            size_hint: None, None
            size: '150dp', '50dp'
    
            text: '打开图片目录'
            font_size: '16sp'
            color: .5, .7, .9, 1
            on_press: root.show_load()
    

    当然,我们还有一个更简单的居中方法:

    <MainWindow>: # float layout
        LabelManager: # relative layout
            id: label_manager
            size_hint: None, None
            size: '800dp', '800dp'
            center: self.parent.center
    

    关于 RelativeLayout

    RelativeLayout 可以让子Widget的定位坐标原点变成Widget的左下角,而不是顶层窗口的左下角;当RelativeLayout的位置移动时,子Widget的位置会联动,以保持父子位置不变。

    触控点的坐标:如果一个Widget的父容器有RelativeLayout、ScatterLayout、Scatter 和ScrollView 那么当触控(touch)事件传递到这些容器的子容器时,坐标点会被转换为容器坐标系的数值,而不再是顶层窗口的坐标了。要注意的是,对于这些特殊容器而言,触控坐标不会转换,只有他们的子Widget会收到转换后的坐标。

    文档中用三种坐标系统来描述这些关系,分别是:

    1. Window Coordinates 窗口坐标系
      是最顶层窗口的坐标系,以窗口的左下角为原点。

    2. Parent Coordinates 父坐标系
      距离本Widget最近的一个特殊父容器的局部坐标系。

    3. Local / Widget Coordinates 局部或Widget坐标系
      以本Widget的左下角为原点的坐标系。

    Widget 类提供了4个方法来对这三种坐标系进行转换,分别是:

    1. to_widget()接收窗口坐标,返回局部坐标。
    2. to_window()接收局部坐标 ,返回窗口坐标。
    3. to_parent()接收局部坐标,返回父坐标。
    4. to_local()接收父坐标,返回局部坐标。

    关于键盘输入

    关于 Clock 的几种调度机制

    kivy 的 Clock 类提供了几种时钟调度机制,分别是 Clock.scheduled_once(), Clock.schedule_interval()Clock.create_trigger()
    使用的例子:

    def my_callback(dt):
        pass
    
    // call my_callback every 0.5 seconds
    event = Clock.schedule_interval(my_callback, 0.5)
    
    // call my_callback in 5 seconds
    event2 = Clock.schedule_once(my_callback, 5)
    
    event_trig = Clock.create_trigger(my_callback, 5)
    event_trig()
    
    // unschedule using cancel
    event.cancel()
    
    // unschedule using Clock.unschedule
    Clock.unschedule(event2)
    

    遇到的问题和解决方案

    自定义的 Kivy Widget size 设定无效

    原来是因为把自定义的Widget 放到了 FloatLayout 下,FloatLayout 会根据 size_hit 管理子 Widget 的大小,所以自己修改的 size 不起作用。解决的方法是设置子widget的size_hit 为 (None, None),需要在创建对象时作为构造函数的参数传入,例如:

    BBox(size_hint=(None, None))
    

    但是不能是设置 pos_hint=(None, None) 否则报错,想想也对,因为 FloatLayout 的主要作用就是能根据子Widget的 pos_hint 来定位,如果不用这个属性,那干脆就不用 FloatLayout 好了。

    如何设置 kivy desktop app 启动时全屏显示?

    分下面几步即可实现:
    1. 重写 App.on_start() 方法
    2. 在其中调用 self.root_window.maximize() 即可。
    代码如下:

    def on_start(self):
        self.root_window.maximize()
    
    展开全文
  • Erlang 游戏开发经验总结

    万次阅读 2016-03-20 22:43:55
    现在回头看下这个问题,总结下erlang 游戏开发经验。就当是,为我过去一段时间的erlang开发经历,画上一个小句号。在写这篇文章前,我看过孔庆泉同学写过的Erlang 性能优化总结,字里行间有一点自己的体会,使得我...
    早早就想写这篇文章,但这段时间忙于工作的事情,就不自觉地给了自己各种懒惰的理由。现在回头看下这个问题,总结下erlang 游戏开发经验。就当是,为我过去一段时间的erlang开发经历,画上一个小句号。

    在写这篇文章前,我看过孔庆泉同学写过的Erlang 性能优化总结[2],字里行间有一点自己的体会,使得我心血来潮,好像重新做回了erlang开发的感觉。所以,现在回过头,整理下游戏开发对erlang的使用。

    1. 架构设计

    很多人都说Erlang天生分布式,归结原因是erlang分布式这块实现比较完善。节点间的通信是透明的,无论是节点内的进程,还是不同节点的进程,都可以使用 erlang:send/2 发送消息,而且数据不需要做任何转换。
    所以,很多项目会选用多节点架构,可以通过横向拓展(增加机器数量)来支撑更多负载,把性能压力大的子系统分配到不同的节点,这样,就可以支持更多的在线玩家。
    这样做的出发点是好的,但会引起一系列的问题:
    1、业务逻辑的问题:
      跨节点逻辑变得复杂,玩家数据同步、一致性问题,节点断开及重连的处理等
    2、语言局限性问题:
      节点间消息通讯要序列化和反序列化,原子传输要转成字符串,二进制复制

    那架构选择单节点,还是多节点?
    没有绝对,这要看游戏而定。假如你的游戏像页游那样,分服而且各个服之间交互较少,单节点会比较适合。但如果像lol那种对战玩法的游戏,多节点会比较合适,登录和玩法在不同的节点,玩家对战时选择集群内压力较小的节点做战斗计算。

    单节点,好处是玩家数据容易保证一致,运维方便。以常见的MMORPG游戏,单节点在16G内存,8核心CPU,可以支撑2k人稳定在线,考虑非活跃玩家,达到5000也是可能的。当然,游戏的框架要合理设计,做一些妥协,比如玩家寻路不能在服务端做,地图九宫格的设计,排行榜不实时刷新,控制同屏玩家数量等。现在,单节点做游戏服,还有一个重要原因是,现在的机器性能相较以前高很多了,加上erlang无锁的Actor设计在并发场合下解放了cpu,从某种程度上讲提高了cpu的运算能力。

    单节点的设计:


    多节点的设计:


    erlang节点注意一个问题,默认erlang节点是全联通的,也就是当一个节点加入集群时,集群其他所有节点会和新加入的节点建立联系。全联通带来的问题,集群节点间两两连接,随着节点增加,连接数量呈N*(N-1)/2增长,越发恐怖,连接本身占用了端口资源。更坏的是,为了检测节点的存活,erlang会定期发心跳包检查,即使一分钟一个tick,节点多的话也会造成大量的网络风暴。
    解决方法就是在集群中隐藏节点,就可以避免全联通,只要erlang启动加个参数即可 -hidden

    2. 数据库

    数据库io向来都是游戏的主要性能瓶颈,处理不好容易导致游戏卡顿,甚至崩溃。而通用的持久化策略就是,内存读写+定时持久化。玩家上线时,加载玩家频繁用到的数据到内存,玩家大多时候就是在读写这些数据。然后定时把这些数据从内存刷到磁盘,在玩家下线时也做一次持久化。

    说下erlang自带数据库 - mnesia
    实际上,erlang已实现了这样一套持久化机制,也就是 mnesia数据库。
    mnesia数据存储是基于ets和dets实现,对于ram_copies表使用ets;disc_copies表同时使用ets和dets,数据读写使用ets,dets做持久化;而disc_only_copies表使用的是dets
    这里先讨论 disc_copies的情况,mnesia启动时,会将 disc_copies表所有数据加载到ets表中,每次读数据都是读ets,写数据则会先写到ets,然后再写一份到日志文件中,等待定时(或定量)持久化刷到dets。
    通常disc_copies表可以满足我们的业务需求,但使用mnesia要注意一个问题。前面也提到了,mnesia启动会将表中的数据加载到ets,假如你的表过大,就会导致内存被急剧消耗掉。(特征就是,ets所占的内存比率过大)
    所以,使用mnesia表时,经常都是要disc_copies表和disc_only_copies表配合使用。那问题来了,什么时候使用disc_copies表,什么时候disc_only_copies表。

    最简单的就是,对玩家数据动刀。玩家数据默认用disc_copies表,如果长时间没登录后将这个玩家的数据移到disc_only_copies表,等到他下次登录时再将数据移到disc_copies表。
    之所以可以这么做,理由有两个:
     1. 游戏中玩家数据所占的比例较大,调整玩家数据可以获得明显收益。
     2. 玩家流失后回到游戏的可能性很小,就算有的话比例也不大。
    这么做的弊端就是玩家流失后重新登录的时间较长,但通过这种方式减少的内存很可观。

    mnesia的使用,还要注意3个问题:
    1. mnesia单个表2G文件大小限制,所以要自己分表,或者使用表分片
    2. mnesia集群功能,过多的人说有坑,但我没有这方面的经验,就不做讨论
    3. mnesia事务并发性太差,尽可能不用mnesia事务,多脏写;事务可利用进程实现,保证数据安全


    3. 进程

    每个玩家一个进程的设计已经成为了erlang游戏开发的潜规则了。这个没什么好讲,玩家进程修改自己的数据,进程消息同步处理机制保证数据一致性。可能有些游戏还会将玩家进程和scoket进程独立开,负责连接的建立和维护,协议封包解包,甚至做攻击的防范等。但如果玩家进程和socket进程同在一个节点内,显然整合在一个进程较好,erlang消息基于复制,中间多了一个进程,一次前后端交互要多了2次内存复制。

    那么,除玩家外,其他进程怎么确定?
    1. 地图进程
    每个玩家都是独立的进程,玩家pk要交换两个进程的私有数据,就要发消息给另一个进程处理。假如是强pk的游戏,同时有N个玩家一起打斗,消息就会繁多。因为数据一致性问题,进程间的并发机制就会弱化成同步机制,增加了战斗时延。
    所以,这里会引入地图进程,通常以一个地图一个进程。玩家进入地图时,会同步战斗相关数据到地图进程,玩家离开地图时,再将战斗数据同步回玩家进程。而在玩家进入地图到离开前的这段时间,一切的战斗计算都由地图进程完成。
    或者有人会有疑惑,就算有了地图进程,还是有同步问题,地图进程还是要同步处理pk请求,无法并发处理,玩家进程还是要等待地图进程操作完成。
    其实,对于玩家的pk请求,处理至少有两个过程,第一个过程是验证攻击的合法性,如是否有这个技能,技能cd,等等。第二个过程才是战斗计算,玩家进程检查合法性,再由地图进程做核心的战斗计算。另外一个,玩家进程除了战斗请求外,还有其他业务逻辑上的消息,容易出现进程挂起的情况,这时候,玩家进程不可能处理到战斗计算,就会导致战斗卡顿。

    2.公共进程
    公共进程指的是那些提供公共服务的进程,比如:
     1. 社交类,有好友、帮派、组队等,这些服务管理着多数玩家的数据,都需要一个进程来管理。
     2. 计算类,这类有一定的计算量,比如说排行榜,要有一个进程来承担计算。
     3. 广播类,有聊天室、世界聊天、帮派聊天、地图广播等
     4. 开关类,有活动系统,比赛系统等等,控制游戏活动的开启和关闭

    erlang进程虽然廉价,但是不要太过随意创建进程,比如创建一个临时进程异步传输数据等等。虽然这在某种程度上提高了并发性,但进程的创建和销毁需要一定的系统消耗,而且会导致项目中进程数量不可控,可能系统莫名其妙多了很多进程,这些维护起来也麻烦。再说,erlang同时存在的进程有最大数量限制


    4. 进程字典与ets

    进程字典是erlang游戏开发中最为常用的数据记录方式,理由很简单,因为它够快,差不多比ets快了一个数量级。但是,进程字典的数据为所在进程私有,无法跨进程直接get到进程字典的数据,而且,在进程被销毁时,进程字典的数据也会被回收。
    再说下ets,对比进程字典,ets的适用场景是跨进程读写数据。遇到一个数据频繁被多个进程读到,就要考虑使用ets了。另外,ets有归属进程,但归属进程销毁时,ets的数据就会被系统回收。

    对比进程字典和ets的实现,区别如下:
    1. 锁方面,进程字典为无锁操作,ets是读写锁
    2. 数据方面,进程字典数据在进程中,查询没有多余的复制操作;而ets,因为数据不在进程中,查询时会复制一份到进程。

    所以,进程字典通常是最优先的选择。假如玩家的数据是存储在mnesia,特别是玩家的核心数据,就有必要从mnesia读到放在进程字典中。前面讲到了mnesia是利用ets和dets实现的,玩家上线时将核心数据读到进程字典,这样,读写都在进程字典,就可以利用进程字典带来的性能提升。这个提升是很可观,毕竟快了一个数量级。

    前面提到了ets归属进程销毁时,ets数据也会被回收?
    那么如果预防数据丢失的问题,ets也提供了方法,通过设置继承者进程就可以了。
    ets:new(person, [named_table, {heir, HeirPid, HeirData}])
    当归属进程崩溃时,继承者进程就会收到信息 {'ETS-TRANSFER', Tid, FromPid, HeirData},并且,ets的归属权就会转交到继承者进程。


    5. 消息广播

    消息广播是游戏中的性能消耗大头,主要包括地图的行走、战斗广播,世界聊天广播。世界聊天广播可以通过控制玩家发送时间间隔来限制,地图中的广播包,比如行走和战斗包的广播实时性高,只需发给视野内的玩家就可以,不用全地图广播。所以常见的处理方式是,玩家的视野通过九宫格划分,玩家的地图广播只发送给九宫格内的玩家。

    如何在服务器压力大时,进一步优化广播消息:

    针对时效性高的数据包,不重要的广播包,可以选择性丢弃:
    1、挂机玩家不发送战斗包,特别是战斗buff。
    2、每N个包丢弃一个
    挂机玩家的判定,前端以玩家长时间没动作来判定,或者将游戏切到后台运行时判定。等玩家在游戏内点击鼠标,或键盘时解除挂机状态。

    这里再谈下,消息广播还可能进一步优化。通常,后端发数据给前端都会对协议数据进行序列化(封包),然后再发给前端反序列化(解包)。而广播数据,对于每个玩家可能都是一样的,没必要每个玩家发给前端时都各自序列化一次,就只要序列化一次,然后每个玩家拿到数据后直接发给前端。

    erlang消息广播要注意什么问题?
    1、reduction计数
    通常会启动一个消息管理进程,这个进程就负责把广播消息转发给对应的所有玩家进程。启用管理进程的一个好处是,进程发消息会扣除reduction,而且这个reduction扣除大小还受到接收者进程影响。假如直接在地图进程做消息广播,就会导致地图进程受到的调度极度减少,影响战斗计算。
    2、消息复制
    erlang消息发送基于复制,但对于比较大的二进制数据,则会优化成二进制引用,减少二进制复制带来的开销。所以,当一个消息要发给多个进程,特别是协议数据(发给前端也要先转成二进制),可以先转成二进制再发送。


    结束语

    文章到这里就结束了,这是我做 Erlang 游戏开发经验总结的一些经验,后续,我还会找时间总结更多的开发经验。最后呢,建议大家少上复制网站,如红黑联盟,这些网站复制了还会把文章来源网址删了,然后给了搜索引擎几个钱就排到前面去了。这样带来的问题是,文章我一开始写错了,但后来改过来了,这些网站是不会更新的,看到的人还以为原来的内容是对的。


    最后补充下,庆亮同学在知乎上提到的 erlang 游戏开发的情况:

    1. 捷游的梦幻飞仙在线人数峰值过了 4700(不分线、回合制)

    2. 明朝的仙落凡尘在线人数峰值到了 4300(不分线、ARPG)

    有兴趣的同学不妨看看这篇知乎讨论, 为什么一些网页游戏喜欢用Erlang做服务端 


    参考:

    [1] http://blog.csdn.net/mycwq/article/details/50939354

    [2] http://www.kongqingquan.com/archives/221

    展开全文
  • 开发经验和屁股的关系

    万次阅读 多人点赞 2012-03-17 08:39:32
    昨晚为CSDN俱乐部的同学们做了一个讲座《微博开发、云平台及一个微博...按照预先的准备,要讲如何在校积累开发经验,突然冒出了批评某些官员“屁股决定脑袋”的观点,也就将屁股和开发经验放在一起发挥了一下。  当
  • ONVIF开发经验总结

    千次阅读 2016-05-10 15:19:51
    学习ONVIF技术也有一个月了,实现了发现网络摄像机、获取设备信息、获取RTSP流地址并播放RTSP视频这些工作,借鉴了很多网上的大牛的开发经验,主要借鉴的有两个:http://my.csdn.net/ghostyu、...但是我在这里做一
  • 泛微OA ecology8的一些开发经验汇总

    千次阅读 2020-03-19 15:15:19
    ecology8二次开发经验总结
  • Unity游戏开发经验点滴

    千次阅读 多人点赞 2019-10-07 18:26:03
    游戏开发中会遇到各种各样的问题,只有经历过了才会深刻,这里就游戏开发的一些经验点滴给读者分享一下,先从代码说起。 从事IT行业这么多年了,写过或者看过很多代码,有的项目代码写的不错的,大家经过多年的努力...
  • BAE 百度开发经验

    千次阅读 2015-05-23 10:20:30
    BAE 百度开发经验谈 1.及时查看BAE通告 例如:BAE2.0已经在2015年3月下线,开发时还根据2.0版本文档,怎么能正常使用呢? BAE2.0迁移BAE3.0说明 ...
  • [分布式]到底啥是分布式系统开发经验

    万次阅读 多人点赞 2019-03-28 10:46:32
    5、一句话总结:什么是分布式系统设计和开发经验 6、补充说明:中间件系统及大数据系统 前言 现在有很多Java技术方向的同学在找工作的时候,肯定都会去招聘网站上找职位投递简历。 但是在很多职位JD上往往会...
  • IM开发经验

    千次阅读 2015-08-06 20:26:05
    已经连续写了7天的代码了。现在应该可以叫做有点经验开发人员了。 脑子有点乱乱的,明天再写。。。
  • 多年大数据开发经验总结

    千次阅读 多人点赞 2018-08-24 10:02:23
    多年工作经验总结 初入行,搞大数据开发。得高人指点,先学mapreduce,不足一年,tez兴,后入此道。朝夕不倦,发愤图强,才能略知一二。无奈后浪推前浪,tez被spark拍在沙滩上,遂投spark之怀。继而抖擞精神,奋袂...
  • 微信小程序开发经验总结(五)

    千次阅读 2017-09-19 11:24:55
    微信小程序开发经验总结 常用组件button image input swiper scroll-view form 常用API phone loading Storage
  • public class DateBean { public DateBean(int id, int num, String startTime, String endTime) { this.id = id; this.num = num; this.startTime = startTime;... this.endTime = endTime;...
  • 软件开发经验总结(容错性)

    千次阅读 2018-03-09 16:00:44
    20180206 软件开发经验总结(容错性)容错性:容错性是指软件检测应用程序所运行的软件或硬件中发生的错误并从错误中恢复的能力,通常可以从系统的可靠性、可用性可测性等几个方面来衡量。可靠性对于火箭发射之类关键...
  • 只有2~3年左右的开发经验,为什么年薪就可以达到50万+?
  • 嵌入式GPS导航系统开发经验

    千次阅读 2011-01-21 14:00:00
    嵌入式GPS导航系统开发经验 一.地图数据篇 1.地图数据引擎与界面显示的代码分离; 2.地图数据与符号显示也就是地图数据显示分离(类似XML与XSL,XSLT关系); 3.地图数据要分层:如街道,国道,小区,...
  • 中南大学FYT机器人战队超级电容开发经验记录及分享(ROBOMASTER)概述robomaster18赛季robomaster19赛季robomaster20赛季FYT超级电容整体方案19赛季方案总体:电流监控及供电状态切换板充电模块板控制板理想二极管防...
  • 乐Phone开发环境搭建及开发经验分享

    千次阅读 2010-11-08 13:33:00
    乐Phone开发环境搭建及开发经验分享安装JDK下载JDK,下载完成后安装。安装Eclipse下载 Eclipse ,解压缩,后边会运行目录中的eclipse.exe 安装乐PhoneSDK 下载 乐PhoneSDK,解压到一个文件夹。记住解压后的文件夹...
  • 大众点评点餐小程序开发经验 - 源码解析https://juejin.im/post/58bb7be861ff4b006cedc849 大众点评点餐小程序开发经验 - 逻辑层https://juejin.im/post/58b7eb2aac502e006bcbb6fd 大众点评点餐
  • QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec();

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,223
精华内容 48,089
关键字:

开发经验