因为这些书的某页某行,无形中影响着我,让我变得不一样,我会因此记住这几本书。
BGM:我很爱的一首小众古典曲:《Figlia del cielo III》
原文链接: 2023年读的书-公众号 AwesomeYang 原文有书的直接购买链接,手机打开。
2023 年是变化的一年:角色转变,意外发生,见证过生与死,感受着聚又散,哭泣与吵闹,喜庆与欢乐,热闹与落寂;似乎每个可以穷尽的情绪都要来袭扰一遍;而这些经历又塑造着我的每一分思考,成为我的一部分。
这一年庆幸看到了自己由内而外的改变,这一年由内在驱动的读更多的书、认识更多的人、尝试不同的事情;虽然不知道自己的一些坚持是否有意义,却已然成为了习惯,即使现在不是最好的,但我希望比昨天要好一点就已然知足。
当然也有三分钟的热度的时候:没有读完的书,没有兑现的承诺,浅尝辄止的知识…都是见证。后来看了一些书,遇到一些人,却奇妙的与自己和解了,不再追求完美与傻傻坚持:我告诉自己人都会犯错,只是前路模糊,我需要先走两步才能看到前方,而正确的做一件事变的很重要。
今年虽没有读几本书,但我觉得对我来说意义重大:因为这些书的某页某行,无形中影响着我,让我变得不一样,我会因此记住这几本书。就像你会因为生命中某个瞬间影响着自己而感动一样,这或许就是阅读的意义所在。
好吧,写作新手总是陷入讲道理的误区,我也不例外。所以上面的你可以当没看见,但我的感受是真实的。
谢谢下面这些书给了我力量,知识,情绪,思考。
这本书在书单里很久,最早应该是 18 年的时候就在书单了,但是读了几页就罢了,有段时间陷入深深的迷茫与空虚中,在我姐的推荐下又读完了这本书,虽然书翻译起来很绕口,但不影响核心的观点表达,阅读完让我对自卑、情绪、人际关系、他者期待、勇气与自我接纳有更多的思考(部分):
健全的自卑感不是来自与别人的比较,而是来自与“理想的自己”的比较。
愤怒是可以捏造的,一切情绪都是,都是出于某种目的的捏造
课题分离:一切烦恼皆源于人际关系,而人际关系的矛盾多是因为别人对自己课题的妄加干涉或自己对别人课题的妄加干涉;课题分离可以远离很多烦恼。
我们并不是满足别人的期待而活着的,不需要非得别人认可,对认可的追求,失去了自由,放在认可欲。
有时不一定非要设定目标,当下的片刻都应该认真去过,活在当下;不要迷失在过去与太久的未来当中。
这本书说来也巧,我是正宗的“差生文具多”,我经常折腾笔记软件,但很少真正留下自己的思考,多是摘录收藏。后来通过 浮墨笔记 ,再到现在经常写的 墨问便签 ,随手写点东西已然成为一种自主习惯,但是卡片笔记写作法,如果要完整的实践下来需要不断坚持练习,才能真正创造出知识的复利。
这个方法强调:把闪念和阅读时的触动点用自己的话记下来,不要只是简单的摘抄,持续积累和回顾;定期整理成永久笔记。去实践去输出,输出不用倒逼输入,积累到一定量级,笔记之间会自然联系,好的想法也会自然浮现。
大多数人苦于写作的原因都差不多,就是因为他们相信或者被迫相信写作是从一张空白页开始的;但如果持续思考记录笔记,那就构建了良好基础。
池老师的书,池老师是多年的互联网老兵了,以前在锤子做研发总监,后来在极客邦做了极客时间这款产品,写作十几年;现在创业做 墨问便签 结合科技与人文,他是真的将爱好做成了产品,或者说将产品做成了自己喜欢的样子,用他的话说这就是创作者的品味。
书里的内容我实际上忘记的差不多了哈哈(老池别打我),但我记得关于沉没成本与坚持给了我不少力量:很多时候你并不知道那些沉没的成本是否真正沉没了,你只能沉默地坚持,希望坚持到最后的水落石出。
他还谈写作与思考,Mac 技巧,编程,职场…文风轻松幽默,没有专业领域的阅读压力,值得一读。
当我读完 《MackTalk 人生元编程》之后,开始关注池老师,后来加入池老师的社群开始阅读社群里推荐的书籍。这应该是社群共读第一本我感兴趣的书。
微信背后的产品观实际是 2012 年的时候龙哥的内部演讲内容,书中从用户、需求、设计、气质、UI多个方面 表达微信的产品观念。很多观念从现在来看也相当超前,龙哥说:
用户究其根本是人,而人是环境的反应器,人是懒惰的、不爱学习的、没有耐心的;要找到人需求之中的心理诉求。
作品可以打败一些功利性的产品。
如果产品没有自然增长,就不必推广了。
我独自度过了太多时光,沉默已经成为了一种习惯。
一个女性在那个年代,独自开飞机穿越非洲,不被定义的女性力量,一本平和的非洲飞行生涯自述。
即便在有航道的地区,即便有仪器的帮助和无线电的指引,夜航依旧是种孤独的工作。而飞越牢不可破的黑暗,没有冰冷的耳机陪伴,也不知道前方是否会出现灯光、生命迹象或标志清晰的机场,这就不仅仅是孤独了。有时那种感觉如此不真实,相信别人的存在反而成了毫无理性的想象。
书中说:“如果你必须离开一个地方,一个你曾经住过,爱过,深埋着所有过往的地方,无论以何种方式离开,都不要慢慢离开,要尽你所能决绝的离开,永远不要回头,也永远不要相信过去的时光才更好。因为他们已经消亡。”
这本是今年意外读的一本书,最开始是墨友(子杨)的推荐、解读(墨问便签小程序搜:遥远的救世主解读)让我产生了浓厚的兴趣,正好后来在公司同事的桌上发现了这本书,就借来读了起来。
有的人在书中读到了不可多得的爱情价值,有的人读到行走于世的智慧,文化属性的寻味,有的人则认为是垃圾文学的堆砌。 那到底是本怎样的书,可得读了才知道不是。
作者是著名的创业孵化器YC创始人保罗·格雷厄姆,我阅读的是阮一峰老师翻译中文版,我读下来没有记住太多东西,记得书里强调黑客精神,谈成长与创业,谈作品与品味,谈编程语言…。而本书实际是保罗·格雷厄姆博客文章的汇总。
黑客与画家的共同之处,在于他们都是创作者。与作曲家、建筑师和作家一样,黑客和画家都试图创作出优秀的作品。 他们本质上都不是在做研究,虽然在创作过程中,他们可能会发现一些新技术。
优秀作品的秘诀就是:非常严格的品味,再加上实现这种品味的能力。
乔布斯本人唯一授权的官方传记,我断断续续读了一个月才读完。
乔布斯当时或许是别人眼里的疯子,但却是我们心中的天才,只有疯狂到认为自己可以改变世界的人,才能真正改变世界。
乔布斯是一个复杂的天才;但对乔布斯而言,一个人不是白痴就是天才;没有人能逃脱乔布斯的现实扭曲力场,他会凝神激励人,或骂狗屎一样训斥人。
有一种人读了这本书,就觉得自己就像乔布斯(只要别人做得不对,他就会说他是垃圾,所以他觉得自己像乔布斯)但乔布斯太复杂了,压根没有一个词能够概括的,要是有的话那就是复杂。
毕加索不是说过吗?优秀的艺术家模仿创意,伟大的艺术家窃取灵感;正是乔布斯对施乐帕克的灵感窃取成就了 Mac,图形个人电脑之后便迅速发展。
科技与人文的交汇处,乔布斯总能迸发出火花(如iMac、iPod,iPhone,iPad,iCloud…等颠覆性产品),更令我想不到的是:甚至于迪士尼的 《XX 总动员》系列动画电影,都是乔布斯的动画电影制作公司皮克斯制作的。
很久以前,有人给我谈励志,谈认知,我是嗤之以鼻的;我总觉得那是从中学的一摞书里挑出了也青年文摘,并用诗意的文字告诉我该如何生活。
但这本《认知觉醒》还真就没那么多空洞,他没有制造焦虑,很切实的去剖析生活、学习、认知上的现象。从大脑构造出发,从底层原理出发。让人看完没有鸡汤的快感,而是得了认知的平静。道理很多,但也会讲怎么去具体落地,没有刻板的教学说教;先内观自己摆脱焦虑、再外观世界借力前行。
要在舒适区与困难区中间的拉伸区持续不断地练习,太难或者太容易都会容易放弃坚持。
万字长文池,只取一瓢水;读书不是目的,是过程,不要纠结读了几本书,落地实践才是目的,改变才是目的。
保持专注,感受当下感受当下做任何事情,吃饭就专注于味道,跑步就专注于跨步摆动,睡觉就感受平静的呼吸,觉知行动的每一步,而不是思绪乱飞。
为什么我们听了很多道理仍旧过不好这一生,因为没有反思、练习、行动。那就没有真正内化为自己的觉知,那道理只会是徒劳的爽感;知道又做不到只是徒增烦恼。
这是认知觉醒的姐妹篇,关于如何做成一件事,作者从“心法”再到“技法” 一一进行传授,而这其中:创造价值是最主要的。
有时候我们急于求成,收效甚微;那是大脑的问题不是你的问题,因为大脑天生懒惰。
要为他人提供价值则意味着,你需要保持耐心并坚守,因为价值是经得起实践和时间考验的;机会总是属于那些 “看的清且做得到的人”
想要得到一样东西,最好的方法是让自己配的上它。
作品思维,只要你用作品示人,你就会想办法打磨它。尽管创造的过程会让你感到有些困难,但最终换来的正反馈会让你在精进的路上乐此不疲。
要搞点薯条就先做成一件具体的有价值的事儿。
好吧,还有很多读了一半的书,我暂且就没有放在这里了,之后继续分享,认知觉醒和认知驱动,是我在2024年阅读的,但中国人总是以春节为界限来区别一年,我也是的哈哈哈(为自己的拖延症找了个完美的理由)。
原文链接: 2023年读的书-公众号 AwesomeYang
]]>这是 2024 年的第一个工作日在公司进行的有关 LLM 的落地用例解析分享,本文基于培训纪要集结成文。
(本文不涉及大模型底层原理,主要讲解应用案例,适合小白了解 大模型的典型用例如何落地的,也可以让大家知道那些 AI 套壳网站是如何工作的)
近 9 千字,内容干货可重复阅读,大白话讲如何实践应用。
主要讲解:
1、关于公司内部基于 GPT 的落地用例
2、了解大模型的基础常见的应用场景
3、常见场景的大致原理( langchain 示例)
4、讨论:大模型的落地要点是?
5、关注的大模型相关资源分享?
…
你可以学习到的内容:
• 如何从 0 开始开发一个自定义的聊天机器人?
• 如何开发一个基于 GPT 的智能 BI 系统?
• 如何突破 LLM 上下文的限制?
• 为何向量数据库如此重要?
• 还有哪些落地场景可以去尝试?
• ChatDOC、ChatPDF 的原理是怎样的?
• 怎样写一个简单的AI + 知识库问答?
为什么要了解 LLM&ChatGPT?这是一组数据
1、在 2022 年 9 月至 2023 年 8 月期间,排名前 50 的人工智能工具吸引了超过 240 亿次访问。
2、ChatGPT 以 140 亿次的访问量遥遥领先,占分析流量的 60% 以上。
3、过去一年,人工智能行业的月均访问量为 20 亿次,最近 6 个月激增至 33 亿次。
…
分析来源:AI Industry Analysis: 50 Most Visited AI Tools and Their 24B+ Traffic Behavior
过去一年,国内大模型和 GPT 也在不断升级,过了很多哇塞时刻,现在更多的是冷静落地,如果你现在还没有了解相关的发展,是时候了解一下,如果你了解如何使用,是时候更进一步。
我先来说说在公司内部去实践的一些场景,也是业界落地比较多的场景,后面我会拆解这些场景是如何实现的。
集成在 IM 上,全公司都可以去使用的一个典型 ChatBot,可以进行任意内容聊天对话,没有做任何微调以及其他处理;可以满足因为网络问题而导致的无法访问问题。
基于 GPT 的任务理解能力和提示词/角色/任务预设能力,将场景固化为特定的专家,去解决工作中的零散问题,这也是互联网上最多的用例(自定义角色)。
这里面还有一部分是使用外部工具而非自研,比如代码生成插件,经过评测:免费的推荐 Codeium、付费推荐 GitHubCopilt。
对于一些企业中结构化的数据,通过自然语言对话进行数据查询并直接将数据返回,得到分析图表,对数据进行分析建议等等。
示例中查询不同存储方式的商品占比是多少?只需要问出去,其他的都交给大模型。
…剩余内容,请购买后阅读。
想了解大模型(如 ChatGPT)典型用例实践的同学不要错过了,#墨问西东 创始人老池推荐。几块钱买下来,然后拿出十来分钟阅读一下(9 千字),有条件再花点时间实践一遍。
一来节约你搜罗几天相关信息时间。
二来有完整理论指导和实践案例,可以照着做。
三来如果你不理解我可以给你解答。
扫下方二维码或点此链接购买阅读全文
余下内容目录…
含示例
含示例
含示例
含示例
…
]]>被看见:去表达才意味着被看见,我脑海里每一次表达都想着力求准确,但总怕无法发挥到最好而藏在墙角。但那是无法被人发现的,以往的表达更多是自己在代码上的表达,倾注于屏幕前的自我感动,但这无法让外界了解到一个准确立体的我。而这个表达可能是从进入墨问开始的,也可能是参加了球姐的喜宴开始的,或者做出了让大家相互推荐的小工具。每一次表达都预示着我撕破原来的自己,让别人看到自己才有更多机会,也能让自己看到更多另外的可能。
第三届南山小论坛圆满结束,非常有幸在这届小论坛以代言人,舞者和圆桌论坛成员的身份参与到其中。
这过程中非常感谢我家罗总对我的无条件支持和鼓励;同时也非常感谢球球姐作为小论坛的发起人对我寄予的信任与成全,让我有机会多样化的表达自己,哟嚯。
这届小论坛由溪桥作为执行总导演,要面对如此多繁杂的流程,各种突发状况,以及很多看不到的细节。一场100人的会议,没有参与其中执行是无法感受到这中间的不易。像球球姐之前说的,小论坛已经从蹒跚学步到了亭亭玉立;而这次由溪桥带着她往前继续狂奔。
因为前面两次没有参加,但看了很多之前的分享,明显感觉这一次不一样了,全新的品牌LOGO,多位大咖的分享,都给这一届论坛注入更多的可能。
这次论坛收获很多,二爷千里迢迢跑来深圳,为我们讲《关于产品和创业的阶段性小心得》,分享的心法很多。二爷或许试图把他的全部秘籍都分享出来,让我们也能练成神功。
二爷说的一些印象比较深刻的点:
还有帅气的Yoga总导演分享的《知识付费产品的商业化设计》,虽然我听到一半去练舞了,但第二天我依旧看了一遍回放。
知识付费虽然已经很多年,而这一年是我最能理解的知识付费的一年,通过付费去屏蔽低质量内容,获得优质的信息渠道,而还有的是为了情绪价值。
而作为知识付费生产者,如何去做知识付费的商业化,Yoga会给出答案:
对帅红的记忆是在喜宴介绍江西菜,实际他是一个会做好菜的产品经理。这一次小论坛,帅红向我们阐述职业经历《如何从野生产品经理成长为大厂项目负责人》,意气风发洋洋洒洒,他爱好广泛:会江西菜,爱民谣,爱摄影,也是一个有准确定位和自我认识的产品经理,多多学习。
而后面几位大佬讲到品牌,讲到出海,讲到亚马逊。虽然对这些不是特别了解,但也让我了解到更多商业的内容,拓展了眼界;总是需要商业去撬动理想的嘛,尤其现在更加重要了,所以多多学习。
之前也参加过很多论坛和线下活动,却很少有晚宴环节,一起吃烧烤,嗨歌,解了一天的疲惫。
这一次与很多在喜宴见到的朋友见了第二面,第三面;也有的是第一次见到的,比如帅气的总导演 Yoga,一直拍照的阿无,坐我前面的启明,球姐好友Tina…,当然还有这期的重磅嘉宾二爷,也是全场偶像。
说到这里,又不得不说如何与这群人结缘了:
墨问,问就是创作。我在 4、5 月份加入到以墨问便签为载体的创作群,断断续续更新了100来篇便签,也认识了很多优秀的创作者,而这中间一些活跃的创作者,比如 子杨 是我最早关注到的,他写的《遥远的救世主》解读一定得看看。我也因此买了这本书来品读。
墨问的订阅机制,让我在子杨得便签里发现了 墨球球 这样一个特别的人,一种名为 “球球姐家宴” 的活动形式。也正是这些让我了解,哦,在深圳有这个一个人,她可能不认识你,但叫你明天去她家吃饭哈哈哈。
国庆前的三个月,事务缠身,墨问也几乎少有更新,因为国庆就是我与罗总大喜的日子了,搞完了这一趴;某个中午就收到了球姐的邀请:
球球:“这周六,晚,来家里吃饭吧?”
我:“好叻”
于是有了喜宴的相聚,搭着溪桥的风,巧巧的落在舞台正中央沦为其中的主角之一。
喜宴后我以为一切都止步于此了,但没想到墨问的付费专栏机制,让我在大家眼里更加立体了。
后来又单独去了球姐家蹭了一顿饭,百香果牛肉是一绝的存在,小宝和罗总玩的很开心,还和姐夫一起喝了两杯。球姐和我聊了很多,关于墨问创作是一种生活是如何影响她的、职业生涯、如何保持精力与持续输出、南山小论坛是如何诞生又是如何走到如今亭亭玉立、以及生活、创业,虽然是第二次见,但尤见真诚。
后来也顺理成章,做了南山小论坛的代言人、和大家一起跳舞、让我作为嘉宾上圆桌;这些最主要的都是希望我能和大家人相互链接熟络,勇敢的表达自己,去发现去实现自己的价值,引发更多思考。
表达:子杨前些天让我帮忙整理文字稿,正好是我那场圆桌的文字稿,不得不说子杨很明智啊;我那麻花一样的表达逻辑让我都羞红了脸哈哈哈(虽然罗总鼓励我说比以前要好很多),自己意识到进步空间空前巨大,准备采取行动了,最近在公司计划了一些培训,刻意练习一下。表面上表达的欠缺是表达能力的不足,而实际更多是在于心理的放开,以及知识的储备和梳理。
被看见:去表达才意味着被看见,我脑海里每一次表达都想着力求准确,但总怕无法发挥到最好而藏在墙角。但那是无法被人发现的,以往的表达更多是自己在代码上的表达,倾注于屏幕前的自我感动,但这无法让外界了解到一个准确立体的我。而这个表达可能是从进入墨问开始的,也可能是参加了球姐的喜宴开始的,或者做出了让大家相互推荐的小工具。每一次表达都预示着我撕破原来的自己,让别人看到自己才有更多机会,也能让自己看到更多另外的可能。
被影响:南山小论坛、深圳405、墨问便签让我认识了很多似乎有着神奇魔力的人。有些人在线上你觉得是网友,遥不可及,可能在下一个周末就能一起坐在桌前一起畅聊,可能大家都有着各自的圈子,形形色色,各有所需。商业机会、情感需要、表达、改变、同好… 或许就在下次相遇。这些人影响着我去从不同角度看问题,从不同行业中去探索学习,遇到的人最终都会作为自己的一部分或多或少的碎片。
保持平衡:加入一个组织,成为一个创作者,去写一个付费专栏,看书学习,工作,婚姻,生活,现实种种;这一年形成了和以前不一样的自己,但不时也有惶恐和想要逃离的感觉,复杂的情绪与心理,冲突的事务与时间,无不在脑海挣扎徘徊。谁又不是纠结的个体,但时间有限,时间又是从来不服从管理的,这要我分轻重缓急,需要拒绝,需要自我接纳,需要平衡工作生活,更需要保持清醒。
我是一名程序员,5 月份的时候开始使用墨问便签,持续记录了生活琐碎、工具、读书笔记总共100+篇。
墨问便签引发的一系列链式反应,感谢自己在此还没有完全断掉,不时记录,好的想法自然浮现。
之后我还是会继续记录,也欢迎各位订阅我哟嚯
我的合集:
(拉长周期)100年不断更的读书笔记,永久6元:
关注墨问,还有一个效率工具合集,欢迎订阅,完全免费,不时更新新工具。
]]>这里我暂时假设两张图片都是像素大小差不多标准化的图像,内容只有细微差异
(想一下如果差异太大,那还对比啥呢?)
大胆猜测一下大概率用于生产过程中的质量控制或者分类等场景;只要找到些许不同,人眼应该就能一眼判断是否需要继续下一步操作,所以找到不同之处之后还需要标记
。
这不就是以前我们常玩的游戏找不同吗?
因为没有专门学习这方面的知识,所以尝试问了一下 ChatGPT ,并检查它生成的代码是否能直接运行。
需求:
输入两张图,对比差异,标记差异
由于我的确不知道需要使用什么库去做就不限定使用库了,直接说需求。
问:请使用 Python 编写一个程序,对比两张图片,并在后一张图上标记出差异
ChatGPT答:要使用Python比较两张图并在后一张图上标记差异,你可以使用OpenCV和Matplotlib库。下面是一个简单的示例代码:
1 | import cv2 |
请确保已安装所需的库(OpenCV和Matplotlib),并将image1.png和image2.png替换为你要比较的实际图像的文件路径。此代码将显示两张原始图像以及第二张图像上标记出的差异。
1、拷贝程序代码到脚本文件,命名为diffimg.py
2、安装必要的依赖库,主要是 OpenCV
进行图像 diff
1 | pip3 install opencv-python |
3、找一张图拷贝一份,并对任意一张图像做任意修改,并分别命名为程序所需命名 image1.png
和 image2.png
4、执行脚本 diffimg.py
1 | python3 diffimg.py |
5、增加点难度,找一个找不同游戏里的照片进行对比,看看答案是否正确
改一改就能用了哦吼。
我是 StruggleYang,感谢关注
]]>ILLA Cloud 是一个开源低代码开发者工具,去年 9 月在 Github 上线以来已经收获了 6千多个 Star。
其主要亮点是拖拉拽的方式通过组件库构建页面布局,并且支持多页面布局,其有丰富的UI组件,比如表格,图表,地图等,绝对能满足你的各类业务需求。
还可以通过页面操作的方式来快速链接多样的数据源,比如 PostgreSQL
、MySQL
、ClickHouse
、Elastic Search
等常见数据源。
在页面可以通过 AI 结合你提供的 语言描述 生成需要的 SQL 语句,提高数据开发效率。
值得一提的是:工具支持 Hugging Face API 的接入,可以快速调用多种大模型,从而实现有AI能力的工具快速开发。
ILLA Cloud 还有领先的协作功能,用户可以在这里通过协作方式快速构建页面布局;另外它还提供了丰富的页面模板和专业的文档。支持 云端体验和私有化部署
如果你对 ILLA Cloud 感兴趣,就赶快点击下面的链接,免费使用吧,让我们的开发更高效!
我是 StruggleYang,关注我了解更多有价值的内容
]]>AI大模型这场风暴来的很快,每天更新迭代的速度已经让人赶不上了,之前开始做视频、公众号内容也是看AI工具眼花缭乱,可以吸引大家的眼球。
我整理成了墨问便签 的合集 (墨问便签:AI书签合集),大家就随便看看进入对应合集即查看所有链接,点击里面链接即可复制,浏览器粘贴链接即可访问,所以尽量电脑操作,预览图片,后续我会更新到此站点:
没有对比的话可能看不出来,现在的对话大模型几乎都存在胡编乱造的问题,还有就是计算和逻辑基本上都有所欠缺,不是那么准确。
由于受限的条件,没有感受过GPT4的魔力,但是其他能体验的模型基本上也都玩了一遍;
这还得感谢 ChatAll🔗 这个项目把市面上几乎所有的大模型都放到一起,我才有机会让他们PK,看看哪个更准确。
(⬆️上图说点正确的废话)
(⬆️《遥远的救世主》-豆豆)
(⬆️这个问题星火也没答对)
准确性来说肯定是 Bing 结合在线搜索会准确一些,但是那晚给团队分享时一个乘法运算 Bing 给我算错了,有点出乎意料,话说它后面真的由 GPT4 驱动吗。所以大家问的时候悠着点。
值得关注的是:Claude 已经成为 OpenAI 的强劲对手,从问答体验上来说不输 ChatGPT,并且据网上各位大佬的体验反馈,其多轮对话能力很强,经常需要手动清除会话,不然上下文他记得太清楚了,但此时你的上下文可能已经变了。
据了解,由AI写作再次出圈的 Notion AI 貌似也是由 Claude 驱动。
这个问题我不是专业的,所以我也不知哈哈哈。
最近看到一个新闻说,有个人用AI绘画出了一本漫画,但是为了保持风格一致费了不少劲;而且有些生成的图不能直接使用,需要二次加工。但是这或许会真的改变了很多内容的创作方式。
以后看到漫画和动画怕是很多由AI生成了;之前用 SD 也生成了一些图,对于不是设计师的人来说,满足了那种创造欲,而且 SD 插件丰富,可玩性很高。
可以参考我之前的SD文章,一起体验下: 本地白嫖AI绘画 ,Stable Diffusion 初探!
(⬆️SD 生成的图,比熊穿着铠甲威风凛凛的站在阳光下)
AI 写作和 ChatGPT 对话一样,有时候你能看到很多正确的废话和啰嗦的总结,但是有时候的确是可以给你提供一些想法和思路,比如有些事情你就是找不到更好的词来描述,也许他知道怎么去描述。
AI 写作这样的场景,我个人觉得是对接大模型最简单的场景,因为只需要预设置好角色提示语和问题的摘要,总能给出一系列答案,这些答案也总有能有一部分击中你需求,实在不行就让 AI 多写几遍嘛。
下面使用的是 Notion AI
还推荐另一个:写作猫
(⬆️Notion AI 写作,这个言论是之前在一个群里其他人发起的讨论|不代表个人立场)
除了AI写作,日常的工作、生活、学习,打交道最多的就是文字、文档,以及各种资料书籍。自从 ChatGPT 火爆之后,围绕其探索产品就层出不穷
比如 ChatDoc、ChatPDF 等等,基于文档问答和信息汇总的工具,很受研究、学习的人欢迎
文档对话和分析的 ChatDOC 和 ChatPDF 实现原理也大同小异(这类应用基本上都离不开:llama-index 和 langchain,但我不是这方面的专业人士哈哈,就不误导了),就看谁体验更好,更准确。
以及智能生成 PPT,比如 MindShow,很多人通过 GPT 生成 PPT大纲再让 MindShow 渲染,省去排版和美化的麻烦。挺方便
(⬆️MindShow 生成的 PPT)
还有一些场景是企业需要接入这类大模型,做私有知识库的文档或者智能客服,但是企业的隐私数据又不想发送给这些大模型平台,这样的数据安全问题也是值得考虑的。
那怎么做呢,实际上我也在找,对于一些商用大模型,一些人在观望,一些人已经达成合作;
还有一些在做开源尝试。
langchain-ChatGLM 这个开源项目,是我最近比较关注的一个开源项目,他就是本地知识库的开源尝试,LLM 默认选用的是清华大学的 ChatGLM-6B:
项目地址:https://github.com/imClumsyPanda/langchain-ChatGLM
(⬆️langchain-ChatGLM 项目 README)
AI编程不用说了,作为程序员,这个效率工具高低得整一个吧。片头提到的书签合集里包含了编码相关的几个插件,几乎都试用过了哈,编程效率的确提升了不少,主要是一些体力活和常见的逻辑他能及时给你提示,免去你费力敲一堆的代码。
我现在主力使用的 ChatGPT 生成完整代码,主要是独立的脚本这类 + Github Copilot 基于注释自动补全一些逻辑代码,GPT API 快到期了,后续准备使用 Claude、Bing 继续白嫖。
不过说实话,一站式的 AI 代码还得是 Cursor 给力,但是我对付费这件事很谨慎,没有搞,谁搞了可以交流下效果。
(下面是很早前的版本了,现在已经改版,可能不再适用)
这个问题实际上不好,因为卖货能不能卖和是不是数字人没关系,我有需求就会买,数字人可以增加直播间的活跃度,毕竟只要有电和设备就能7x24一直播,不过平台要全是数字人,可能那时候大家更希望能看到真人直播,互动性肯定比数字人要强。
但是群体就是很奇怪,总是有人买单的,所以无所谓数字人,也无所谓什么网红,只要能给平台带来利润,或许热度就是第一位的。平台希望你卖的越多越好。我管你是不是数字人还是真人。
在技术上,在数字人、AI影片也有很多解决方案,比如:
甚至于开源的解决方案也有很多,比如
基于图片+音频就能生成一张会说话的视频,如下视频所示:
(科技真神奇啊)
就这吧,不想写了,睡觉,记得关注我,然后一键三连,在看、点赞、加星标。
这样我才有动力继续更新嘛哈哈哈。
]]>人在不同场景下会做出不同的反应,不同的思考,比如此时外面蝉鸣鸟叫,烈日炎炎。看了一会书有点困了;睡下前那一刻又写了这一篇。
我想聊的是记录;随时随地的记录。
“随时随地” 就是一个不停变化的环境,以前很少有这样的感受:要把这一刻记录下来,才有意义。
最近使用 墨问便签 开始随手记录之后,逐渐感受到,如果不记录,你刚才那一秒的思考可能会就这样丢失了。
你记录下这关键的思考,上下文有可能被记录下来。以后你再翻到也许可以想起这一刻产生更多新的反应和思考。
以前一直说写文章,但因为工作原因(找的借口),一直都只是空想,或者提笔不知如何继续多次反复就作罢了。
现在想想,在当时的场景下,也许那些文章是有意义的,不论是技术,方案,代码。但是过去那么久之后,那些可能早已过时;
所以为什么不就在那一刻就写下来,那时环境还在、土壤依然肥沃。
好在,你随时都可以有新想法,随时都会处于一个新环境,就在接下来这一秒开始也不晚,记录此刻,无问西东。
—— 2023年5月28日 下午 3:29 老杨
同时发布在公众号,点此前往
同时发布在墨问便签,推荐使用墨问便签,扫图底部二维码进入:
不过这次我特意让理发师给我剪的成熟一点哈哈哈,和理发师也聊了不少关于发型、关于理发店,很快,哗啦啦的20来分钟就剪完了,一个多月没剪的头发,一下清爽了不少。
剪完头发一看手机,还有一个多小时才开始考试,但这时考场还是封闭状态,没有办法进入;外面很热,只能到树荫下乘凉刷手机。
中午的这个点,放到平常上班都在睡午觉了,天气太热不停的喝水,所以当时我很想做两件事:上厕所和睡觉
没一会,距离考试还有30来分钟了,可以进场了,快步跑上三楼右拐的卫生间上个厕所;
卧槽!!!怎么没有小便池? 慌乱中才发现跑到了女厕所,太尴尬了,还好及时发现,不然刚好碰到人出来就尴尬了(那我岂不是要被当变态抓起来?)
赶紧快步跑出,老脸微红;这时候出门刚好碰到女生进来(感觉有点尴尬,人没说啥,略带微笑?)
解决完急事,还有20来分钟时间开始考试,我选择了进入考场吹风扇;外面真的热化了
进入考场我坐在那适合小学生的凳子小桌,显得格外拥挤,手机上交了很无聊,困意来袭趴在桌子上就睡着了…zzzz
不知何时,猜想应该睡了十分钟吧:
惺忪抬头懵逼四下张望,看到整齐划一的桌椅板凳,写着粉笔字的黑板上方是八个励志大字,我已经记不太清楚写的什么。
黑板右侧是值日表和班规张贴的地方,周围还扎了一圈艳色的花。
头顶有四扇大风扇像无人机的螺旋桨要把教室抬飞
有那么一瞬间觉得自己回到的学生时代午睡醒来的教室,所以我开始仔细观察起来周围:
我那张课桌上写满了横七竖八的字,有的是刻在上面的,有的是签字笔写的,还有些英文:
我依稀记得这么几句:
xxx 我老婆
坂田黑长直天花板
My King Never Die!!!
萝莉YYDS
额,这是小学生的课桌吗?怎么像B站的弹幕?
左右两边边的墙上挂着那种名人名言曰:
左:
宝剑锋从磨砺出
梅花香自苦寒来
右:
努力到无能无力
拼搏到感动自己
左边的像是我那个年代引用的话,但右边的怎么更像网络名言?
感动自己这件事,说起来有点褒贬半参。结果不会因为感动自己而改变,现在的我越发觉得方法更加重要。
转眼来到右边墙上,贴满了一墙名为“让愿望起飞”的每个学生的愿望,每个学生有一张照片和几行愿望整齐地排列成了三排。
我只记得两个:
A:瘦下来、希望拥有一台iPhone、希望能上英才班、期望有毕业旅行
B:希望有一台手机、考上好的中学 ….
我左手撑着沉重的脑袋,就在想,小时候我那些愿望有没有都实现,似乎已经完全遗忘在小时候了。
时间的浪潮推着我们走了很远很远了,模糊不清的时光你还记得清吗?
想这一会,时间过去的也差不多了,头顶的风扇还在呼啦啦的吹,渐渐我的困意也被这清凉消除了,这时候铃响了。又要迈向下一场,下一场
“好,大家看一下啊,这个试卷是没有拆封的啊…”
广播:“开始考试。”
1、人们在职业生涯中的迷茫和困惑背后,其实很大程度上源于没有找到自己真正擅长的领域
2、人生一世,如果想充分发挥自己的潜能,就要找到自己最强的那百分之一擅长的技能和基因
3、每个人都该问问自己,你比别人强的那百分之一到底是什么?找到它,然后再这个方向上做出百分之百的努力
4、德鲁克在《21世纪的管理挑战》“自我管理“一章中说到:”要发现自己的长处,唯一的途径就是反馈分析法(feedback analysis)“
5、反馈分析法:每当你做出重要决定和改变时,事先记录下对结果的预期。在一个周期结束(一年左右的光景)后,分析实际结果是否符合预期,是达成还是超标,或者是偏离。
6、这种方法或许耗时良久,但或许在比较短的时间里找到自己的长处,或许两到五年;把这三五年放到你漫长的一生来看,只是一小段时间;而这段时间可以帮你找到一生中最重要的东西:长处;事实上你什么也不做,这三五年也是一晃即逝
7、通过反馈分析法,你能知道当前在做的事情,哪些发挥了自己的专长,哪些是你不擅长的;然后再根据反馈分析法的结果采取相应的行动
7.1、行动1:去做能够发挥自己长处的工作,加强你的长处。补足短板是困难和痛苦的,但是加强长处往往突飞猛进。
7.2、行动2:了解自己的缺陷,并且知道哪些是需要弥补改进的,并明确划分出来,哪些自行弥补,哪些需要别人协助优化
7.3、行动3:进行行为矫正,比如影响你的工作效率和工作表现的行为,分析具体原因,并加以矫正
7.4、行动4:不要做什么,每个人都有许多毫无天分的领域,再这些领域我们可能连平庸都达不到,不要再这些领域浪费时间,去学习你的第二技能,而不是第十八技能
8、在未来,技术、产品、设计、人,都会连接再一起,持续学习新的知识技能,可以让我们的长处得到充分发挥。
9、好的创意能够移动大山,但是真正移动大山的是推土机,创意不过是为推土机指引方向;任何步骤都需要落到实处。
10、反馈分析法并不是总结,也不是复盘。反馈分析法的触发点是生活中的重大改变或者做出的重大决定。
11、一个人不知道自己擅长做什么,就很容易被安排到一个不合适的岗位上。能力定位的错位,无论对自己还是对公司都是很大的损失。你的长处和职场定位决定你成为战神还是别人的炮灰。
其中的内容框架和老池的播客差不多,老池提炼的更加精炼。文中提到更多的例子来举证,比如举例🇺🇸美国在二战后期的几任总统在自我管理方面的差异和分别造成怎么样的格局,等等,以下是一些和上面没有的内容
1、在充满变革的时代,人们的平均工作年限很可能长达50年(这不快实现了),特别是知识工作者,而成功企业的平均寿命只有30年;(我理解我们不可能在一家公司或者组织待一辈子,大家都需要自我管理以更好找到自己擅长的方向,在任何地方都能发挥作用)
2、即使是资质平庸的普通人也需要学会自我管理,知识工作者面临全新的要求:
2.1、一:他们需要问自己是谁?自己的优势是什么?自己如何工作?
2.2、二:他们需要问自己属于哪里?
2.3、三:他们需要问我能做出什么贡献?
2.4、四:他们需要承担维系人际关系的责任。
2.5、五:他们需要为他们的下半生做好规划。
3、自己是谁&优势是什么: 文中提到反馈分析法的重要性,以及通过反馈分析法能体现什么样的问题;这在上面老池播客已经提到过:可以找到长处、缺陷、短板
4、特别提到了关于井底之蛙的傲慢倾向,人们常常在某一领域突出而对其他领域不屑一顾,甚至傲慢地觉得其他的都是扯犊子;需要克服这种傲慢倾向。
5、做事方式:有的人善于阅读,有的人善于倾听,但很多人不知道自己是哪一类人。每个人有适合自己的做事方式,不用模仿他人,在过程中修正自己的做事方式,通过反馈分析找到适合自己的做事方式。
6、属于哪里:少数人很早就知道他们所属的位置,例如数学家、音乐家和厨师通常在四五岁时就已经定型了,医生通常是在十几岁时已经决定要当医生了,但是大多数人,实际上在25岁以前都不知道他们将来要干什么
7、做出什么贡献:如果问我能做出什么样的贡献,就意味着要将知识转化为行动,我们不能问我“想”做出什么样的贡献,不能问组织“要我”做出什么样的贡献,我们要问我“应该”做出什么样的贡献。
8、对于应当作出什么贡献还应该问,这种贡献与我的优势相称吗?这是我想做的事情吗?做出这种贡献值得吗?有激励作用吗?
9、做事的价值观:在企业或组织中,需要从自身优势出发,从个人价值观与组织价值观相结合,做出可量化的成绩
10、做什么,从哪里开始,如何开始,要设定什么样的目标和最后期限。
11、人际关系:下属的责任就是让老板做老板该做的工作,这样他们就需要了解老板,并问他的优势是什么,它如何工作和做事,他的价值观是什么,事实上,这就是管理老板的秘诀
12、人际关系:每个人的做事方式可能各不相同,发挥出效率的第一个秘诀是了解与我们共事的人如何工作的。因为大多数人都需要与不同职能的人相互合作。
13、每当我们走到同事的旁边说,这就是我擅长做的工作,这就是我工作的方式,这些是我的价值观,这就是我集中精力准备做的贡献和别人希望我取得的成绩,我们得到的回答总是:“这对我非常有帮助,但是为什么不早告诉我呢?” (我理解:让别人了解你的做事方式与价值观,可以更好的让他们知道你的底线与职责,而减少冲突与不必要的沟通)
14、知识社会中,我们希望每个人都是成功者,但是这显然是不可能的,对于大多数人来说,能避免失败就是最大的成功
15、自我管理是人事上的革命,它要求个人特别是知识工作者展现出全新的面貌和做出史无前例的事情,这是因为他实际上要求每个知识工作者都从 CEO 的角度思考问题和做事情,它还要求知识工作者抛弃我们中的大多数人仍旧想当然的思维方式和行为方式,要求他们的思维和行为发生几乎180度的大转弯,毕竟,知识工作者第一次大量出现只有一代人的历史
这是我一直问自己无数次的问题 “我擅长什么?”,但是问出这个问题没有做出实际的行动,按部就班的生活和工作节奏牵着自己一直向前,无尽的迷茫时常侵袭灵魂。
回望一下已工作6年,一路走虽然鲜有重大坎坷与波澜,但也算是经历了各种风风雨雨,如今有一份工作但又时常觉得如履薄冰和迷茫。说到底还是没有完全找到自己的长处并在工作中持续践行和加强。
18岁以前对世界的认知太有限了,后来面对花花世界感到无比好奇,对于很多事情浅尝辄止,所以积累不足。渐渐的感受到这种情况带来很多问题,后面应该做减法,去聚焦,并分析自己的优势与缺陷,避免在短板上发力,而是发扬自己的长处!!!加油
人的精力的是有限的,我们时常需要面临杂乱的工作。如何保持专注就成了问题。
但如果过于专注,久坐不起也对身体有害。
那就需要专注与健康相互结合,番茄工作法是一个不错的选择,专注时认真冲刺工作或者学习,休息的时候就撒开了放松。
比如工作过程中,定半小时写代码,短休息5分钟后继续。这样的成效不断训练,肯定会培养这过程中的专注力。
不过建议提前排除一些干扰,比如手机勿扰,否则专注被打断再次专注可能会有点吃力。
我期待下一次的冲刺。
敬请观看视频版!
Just Focus 是一款免费且 Apple 全平台支持的的番茄钟与休息提醒软件;软件简洁,配置自由度很高,多端同时使用效果更佳;
其将时间切成小段,比如25分钟,在这段时间内专注冲刺工作;冲刺结束进行短暂休息以便恢复精力。 (著名的番茄工作法)
Mac的配置界面可以设置每个番茄钟的时长与休息时长,休息又分短休息与长休息,如果你怕控制不住自己工作的热情,可以把不允许中断休息打开效果更佳。
你可以给休息界面配置文字,图片;或者使用Unsplash上的高清大图,在线的每日一句等等,当然你也可以自定义文字提醒自己必须要开始休息了
除设置自定义的快捷键,更有方便的是,软件支持Alfred Workflow,点击安装后即可通过 Alfred 快捷开始番茄钟或休息,这对于我来说非常方便。
如果你想强制自己休息,可以把不允许中断休息打开,我很建议你这样做。当然你精力充沛,也可以将其关闭,手动停止时会给你更多的选项。
]]>举例子:
chatGPT:chatGPT的确很强,我经常用来编写脚本、修改代码或者是查找一些问题的答案。
他可以作为提高效率的工具,但是首先得有思考,它不能代替我思考。
我有一个chatGPT账号,但是我能拿他做什么很重要。有他我不会有三头六臂。
他有无限的知识,那我也能有无限的知识吗?
还有就是需要分辨信息,这些是需要认知和知识提升才能分辨,多看多学
抓住领域,深入了解,工具辅助,提升为自我认知。
]]>本文摘录自 “卖桃者说”
如何有效地学习?
第一步是要有学习的意愿。如果不想学习,说再多也没用,外界有那么多诱惑,主要还是自控力。
第二步是要明确学习的目标。如果只是一设定一些宽泛的,比如说就学英语,学为服务这样的含服的目标,大概率半途而废,比如说最近呀。想什么都想,学一点什么chatGPT呀,什么人工智能啊,但这些太大了,学起来很费劲。实力在这里啊。
那这个学习的目标应该怎么设定最好呢?这里说到就是要在自己日常的工作或者生活中能够用得到,那你学起来可能会更有一些目标和动力。
嗯,这里发散一下,现在什么都想学,什么都想看一下,信息太混杂了。那我觉得还是要先从工作的内容入手吧,看最近的工作需要学一些什么东西,把这些东西巩固一下。
然后就到第三步。第三步就是学了之后怎么去实践。因为如果只学。然后又不不去做的话,那可能就只是停留在想法阶段了,嗯,说实话这种情况很多啊,比如说有个东西学了之后就忘了不去做,也不做个DEMO出来。就光是诶学完感觉嗯还可以,那这样不行,要把它输出出来。这种输出可能有几个方面吧。一种是。分享出去,比如说以文章。然后或者是视频。还有或者是教别人,这样子以教代学可能会更巩固一点。
然后就是在实践的阶段,有一个很重要的东西,就是拆解目标。如果上来就对着大大目标去搞。可能还没被还没攻控目标的话,就被目标搞怕了,所以目标先搞小一点,从一个小目标再到到目标慢慢的跨越,嗯,这样的效果可能会更好。然后针对每个小目标呢,搞一些。奖励。这种奖励可以刺激多巴胺去分泌,然后让我们更爱上学习,嗯,加加大乐趣。看看电影。吃个饭。或者是买个小东西。还有就是把这个时间固定。比如说早上。早上工作日一般没时间。像这种周末呢,一般。都休息。那工作日那总要留点时间吧,那就下班之后了。这个要规划一下,然后周末呢。周末也要不能完全玩,或者有其他事故处理,要把这个时间留出来,嗯。
刚才说的。固定时间。这样子有个好处就是。因为有个洋习惯的养成。比如说。这下像每天早上上班。这个时间就是固定的。每天早上我醒的时候。差不多到就是那个点。都不选那种了。所以这个学习如果在固定时间去进行的话,那可能。更好的养成习惯,保持专注。嗯,避免杂食打乱。
那上面的三步做完之后呢,这是第四步。就是这些东西啊,不管什么东西啊,学完呀,还要产出。
就是一个观点是这样说的,就人有生产者和消费者两种角色,如果没有产出的话,只学习本身是一种消费。那每天忙着读书。学习,学这学那,看起来可能很忙,付出了很多,就感觉很努力,很辛苦。但如果没有产出。工作和生活也没有什么改变。那和我们玩会儿手机,看会儿电影,本质上没有太大区别,
可能就是另一种娱乐,所以一定要产出一些作品,比如说什么呢?解决一个工作中的难题。或者说做出来一些DEMO样例,然后帮别人解决了问题。或者这过程中的思考分享出去。还有就是教别人。像这样子以教代学,然后这样子的话增长更快。总之就是一定要有产出。不要记住答案。要让他们自己去生成的。产出就是自己生成答案的一个过程。
总结一下有效的学习。四个点。
意愿;这个是很重要嘛,没有这说再多都没用了。
目标;一个细化的目标,然后最好是跟工作生活有关联的目标。
实践;然后。去把我们的东西付诸实践。在实践阶段,最重要的是拆解目标。
产出;各种形式都可以。
本人经常分享有价值的生产力工具、技术、好物与书籍,可关注公众号并设为🌟星标,第一时间获得更新
Github Copilot 是一个AI编程助手,其使用 OpenAI CodeX 在你的编辑器中实时建议代码或给你实现整个功能。
比如我让他在 Python 中写一个插入排序,当写完注释按下 TAB 键方法就已经快完成了,多次按下 TAB,验证代码都给你写好了;
除了在 Jetbrains 全家桶的 IDE 中使用,还支持大佬们最喜欢的 VScode 中使用
比如让他在JS中编写一段代码获得 Github 的Top100仓库,TAB几下后便完成了我们的方法。
除了这个关键的插件,VScode上还有个叫 Copilot Labs 的附加插件,它能帮助我们解释翻译代码,生成测试代码、修复bug等快捷操作
另外,Github Next 项目还推出了 Copilot Voice 项目,不用键盘就可以写代码了,可以关注一下。(真一句话需求?)
Copilot 的确方便好用能提高效率,但是官网的价格实在太高了,10美刀一个月,有没有办法以更低的成本获得呢?
那肯定有啊,现在联系我一顿饭钱解决,需要的开发大佬可以在评论区留言或者私信我,我来帮助你。赶紧使用起来让编码效率提升吧。
Stable Diffusion 是 2022 年 8 发布的深度学习文本到图像生成模型。它主要用于根据文本的描述产生详细图像,官方项目其实并不适合新手直接使用,好在有使用 Stable Diffusion 封装的 WebUI 开源项目,可以通过前端页面来使用 Stable Diffusion,大大降低了使用门槛,本文主要是介绍 Github 作者为 AUTOMATIC1111 的 stable-diffusion-webui;易用,插件丰富。
下面可能简称 Stable Diffusion 为 SD。
▲ 图1-封面,国风模型盲盒
img1 | img2 | img3 |
---|---|---|
▲ 组图2,模型 meinamix_meinaV8
▲ 图3-生成界面(使用了汉化插件)
MacBook Pro 14寸
芯片:Apple M1 Max
内存:32G
系统:MacOS 13.3.1
Python:Python3.8
出图速度(默认参数下):快的时候9s,有其他调整的时候稍慢
▲ 图4-出图速度
尝试 Docker
开始准备使用各位大佬推荐的 Docker 搭建,便于一键安装,但是发现无法支持 Mac ,无奈放弃!!!
▲ 图5-Docker 安装 FAQ
如果配置吃得住的 Windows 用户可以试试 Docker 搭建,流程不复杂,直接拉仓库,一键就可以自动安装了,主要使用 docker-compose 进行安装。
Docker 安装可参考:stable-diffusion-webui-docker [1]
本地运行 stable-diffusion-webui
苹果芯片安装文档参考[2]很详细建议看原文档
这里简单介绍下大致流程:
1、如果安装了 Homebrew 可以跳过此步,否则需要到 https://brew.sh 安装Homebrew 便于安装一些必要软件
2、通过 Homebrew 安装一些必要的程序(由于我本地有 Python 和 Git,所以我安装时去掉了这两个,Python 版本不知道是否有隐患?):
1 | brew install cmake protobuf rust python@3.10 git wget |
3、将 WebUI 仓库克隆下来
1 | git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui |
4、下载模型,将 SD 的基础模型(也称之为checkpoint)下载下来放到模型目录stable-diffusion-webui/models/Stable-diffusion,可直接下载 SD 的官方预训练好的模型先试试,也就是文档中下图所指示位置(下个最新的咯),这个官方模型出图效果一般,可以摸清功能后再去试试其他的模型(关于模型相关的介绍下面会提到)
▲ 图6-模型下载
如果下载好了模型,接下来执行启动 UI 的命令,他会自动设置好环境,下载所需的一切依赖
1 | cd stable-diffusion-webui |
1 | ./webui.sh |
初次运行期间我遇到的问题主要是下载慢(Github),开一下代理,再次执行启动命令就好了。
如果是 pip 依赖下载慢,可以尝试切换 pip 源为清华源或者阿里等国内源。
上面步骤如果都完成能成功启动,在左上角模型选择(参照图3-生成界面)就有模型可以选择。这时试试给一些提示生成图片了 ,可以愉快的玩耍了 🎉。
▲ 左上角则是基模选择项,一次只能使用一种基模
汉化UI界面
stable-diffusion-webui-chinese[3]
看不懂英文没关系,直接装插件汉化一下就 OK 咯:
在 SD 中,基于训练方式的不同,最常用的两类模型:本人了解有限,不对的地方恳请指正!checkpoint ?
checkpoint 是基础模型,也简称基模,比如上面安装 WebUI 过程中可下载的官方模型就是 SD 预先训练好,是完整模型的常见格式,模型体积较大,一般单个模型的大小在2~7G 左右;模型后缀一般为 .ckpt 或者 .safetensors
如果下载了 checkpoint,放到 models/Stable-diffusion 目录即可
上面的 SD 1.5 、SD 2.0、SD 2.1,有人说 1.5 的模型比 2.x 的模型效果要好?
下面是一些比较火的三方模型,通常是模型作者基于另外的一些基模(可能是 SD 官方的基模或其他开源的基模)加自己的数据训练出来的模型,一般都是特定风格和一些优化;比如脸型,肤色等等(取决于训练者的数据样本😂)
chilloutmix**[4]**、chilloutmix_NiPrunedFp32Fix**[5]**
… 生成真人的模型,由于其生成的图片风格很适合亚洲人,所以在国内应该是最火的模型,下面会给下载链接
meinamix_meinaV8[6]
,动漫混合型模型,生成的图片多是动漫风格,文中组图2就是其生成
**GuoFeng3[7]
、3Guofeng3_v33[7]
**,中国风模型,图1封面图由其生成
LoRA ?
LoRA 模型作用主要是微调,可以理解为在基础模型的前提下,做一些风格增强,因为他固定一些参数和权重,比如有些 lora 模型是专注 亚洲脸调整的参数,有的是古风、动漫风等等不同风格。
它们通常不会超过 1G,必须与 checkpoint 模型一起使用。
如果下载了 lora,放到 models/Lora 目录即可,随后你可以在界面看到它们,写提示词时,点击对应的 Lora 或按照 lora:lora模型名:1 书写即可使用:
下面是使用 chilloutmix_NiPrunedFp32Fix 基模+几个 LoRA 在相同提示语下生成的效果,为了区别不同模型的差异,可以给模型设置预览图:
▲ 不同 LoRA 在相同提示语下的风格差异便于区别
怎么区别基础模型 checkpoint 和 Lora?
比较大的一般就是基础模型(GB级别),其他少于 1G 的一般情况下是 Lora ,毕竟训练量不一样 😂
一些模型下载网站可能会标识其类型。
至于其他 VAE、Embedding、Hyperentwork 暂时还不了解。
为了让 AI 绘图更加丰富多样,我们可以下载不同模型多多尝试,包括不限于 checkpoint 和 lora,下面是可以下载到 SD 相关模型文件的地方
飞桨[8]
百度的飞桨,有些网友会把一些模型分享在上面,下载会快一些,但只有少量 SD 模型被网友传了上去。
huggingface[9]
很大的模型下载网站,里面包含了方方面面的各类模型。一般推荐在这个网站下载,速度时快时慢(可能是我的网络原因)。
civitai (需科学上网)[10]
网友简称为C站,上面有很多风格的模型下载,对于每个模型都有图片预览,需要魔法
发现即使是下载了风格很惊艳的模型,依然无法生成牛逼的图片,那可能需要在提示词上下功夫了,为了让 Stable Diffusion 制作各种惊艳的图,可以直接参考别人的提示词🫡
以下是一些比较厉害的提示词参考网站,找到喜欢的按照其提示词和参数、Lora 生成即可
**civitai[10]
**:
上面提到的 C 站,每个模型下面都有对应生成的图片分享,可以摘抄下
川普 6
lexica[11]
可以搜索 SD 生成的图片,也可以在线生成图片,看到合适的图片直接复制哈😄,会有对应的模型给出,在👆上面的模型下载网站下载即可
在使用 Stable Diffusion 过程中可能会遇到各种常见问题,我们将在这里提供一些常见解决方案。
解决方案:按照提示操作即可
临时解决方案:改为 512x1023
解决方案:
1 | # 换成对应的Python版本 |
解决方案
1 | # 启动时增加 --no-half 选项即 |
本文主要记录初步使用 SD 进行文生图的过程,至于图生图,ControlNet 等玩法后续分享
可以把你遇到的问题在评论区一起讨论
关注一下吧!
参考:
[1]. https://github.com/AbdBarho/stable-diffusion-webui-docker
[2].https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Installation-on-Apple-Silicon
[3].https://github.com/VinsonLaro/stable-diffusion-webui-chinese
[4]. https://huggingface.co/AnonPerson/ChilloutMix/tree/main (内含一些亚洲 Lora)
[5]. https://aistudio.baidu.com/aistudio/datasetdetail/193534/0
[6]. https://aistudio.baidu.com/aistudio/datasetdetail/202078
[7]. https://huggingface.co/xiaolxl/GuoFeng3/tree/main (直接看文档)
[8]. https://aistudio.baidu.com/
[10]. https://civitai.com/
[11]. https://lexica.art/
文章参考:
AIGC 绘画理论与保姆级实战:
https://zhuanlan.zhihu.com/p/617042733
SD 采样器:
https://zhuanlan.zhihu.com/p/621083328
SD 如何安装使用不同模型:
https://zhuanlan.zhihu.com/p/619553604
mac本地 SD 环境踩坑:
https://zhuanlan.zhihu.com/p/608178376
SD使用入门与提示词技巧:
]]>如今企业应用分布式、微服务盛行,针对分布于多节点的日志,会使用分布式日志系统架构,来满足业务开发查询多节点的日志并进行问题排查和定位。迄今为止,最为通用和成熟的就是elastic的ELK架构,我司现在也是按照如下通用架构(本文使用7.2版本的elastic套件):
- filebeat(本文重点):日志采集器,启动于业务服务器进行日志采集,并发送到kafka指定topic
- kafka:大规模的企业应用通常会产生大量的日志,kafka可以为增长的日志削峰填谷
- logstash: 将kafka的日志数据作为input,通过grok、oniguruma、mutate等过滤器将异构数据解析为结构化数据,最终存储到Elasticsearch
- Elasticsearch:热门开源的搜索引擎,建立在 Apache Lucene 之上,在当前场景用于存储结构化的日志数据
- kibana:用于检索和管理ES数据的UI界面
我们将在本文一步步介绍我们在使用过程中遇到的问题,配置的优化,如何确保filebeat部署在业务主机上对业务的影响降到最低,如何使用cgroup来限制filebeat的系统资源使用配额!
有些文章说filebeat的内存消耗很少,不会超过100M,这是没有针对场景和没有经过测试不严谨的说法(刚开始我们也没有完全覆盖所有情况进行测试,当然部分偶然情况有时无法预知),当真正按照默认的简单配置将filebeat部署到生产环境,或者某个参数配置错误,都可能会出现意想不到的问题,轻则影响服务的整体性能,重则可能造成应用被OOM-killer导致业务中断。我们在刚开始使用filebeat时,觉得这个组件已经如此成熟,应该问题不大。所以使用了最简单最基本的配置将其部署,为后来的问题埋下了祸根!
我们在实际使用中的确遇到了如下问题:
来看几个问题样本:
这里是filebeat导致Linux OOM 的一个场景,可使用
dmesg -T
查看,这里可以看到,在OOM时,filebeat大概占用523561*4k ~= 2G(rss是内存页数,乘上内存页大小4k就是实际物理内存)(多的时候有过5G,比如有的日志文件中打印了很多二进制内容)
使用业务问题样本日志进行的测试的结果
这是初版的配置文件,相对简单,基本没有做什么特殊的配置:
这是一个错误的样本配置,请不要使用
1 | #=========================== Filebeat inputs ============================= |
我们接收业务反馈CPU占据到了300%上下(四核),并且偶现开头出现的OOM现象。
经过文档的查阅,发现几个明显的配置问题,并针对其做过一次初步的优化
max_bytes
:单行日志的大小,默认为10Mqueue.mem.events
:内存队列的大小默认为4096,有这个一个公式 max_bytes * queue.mem.events
等于约占的内存量,这里默认10M * 4096=40G
,再考虑到队列存储已经编码为json的数据,则原始数据应该也会存储在内存中,那满打满算就得有80G内存占用,即使不存储原始日志,日常的服务器也难以接受这40G的内max_procs
:没有限制CPU内核数使用,在日志较频繁时可能导致CPU满载ignore_older
:由于服务器上有历史日志,可以使用此选项忽略较旧的文件初步调整:
1 | max_procs: 1 # *限制一个CPU核心,避免过多抢占业务资源 |
上面的改动,以为已经控制住问题,但是在不久之后还是反复出现了多次同样的OOM问题
filebeat限制单条消息最大不能超过20k,默认内存队列存储4096条记录,再加上明文日志,最高内存理论最高值在 20k * 4096 * 2 = 160M 左右浮动,即使做了以上限制,还是不时出现内存爆增的情况
一时没有找到问题解决方案,我们做了如下的几个阶段策略:
阶段一:降低非预期情况下对应用的影响
阶段二:重新梳理和优化配置,达到优化内存的目的
降低非预期情况下对应用的影响,是将filebeat进程的oom_score_adj值设置为999,在出现意外情况时OOM也优先 kill 掉filebeat,从而达到即使出现意外情况,也不会影响到业务进程
具体的操作是:
启动filebeat -> 获取进程PID -> 写入/proc/$pid/oom_score_adj 为999
OOM killer 机制一般情况下都会kill掉占用内存最大的进程,在kill进程时,有个算分的过程,这个算分过程是一个综合的过程,包括当前进程的占用内存情况,系统打分,还有可由用户控制的oom_score_adj分值,将影响整体算分。
oom_score_adj的取值范围是 -1000 至 1000,值越大,OOM在kill时会优先kill掉此进程,为了最大限度让系统kill掉filebeat,我们必须将此值调整到最大
针对多次问题的场景,进行样本的提取,发现多次问题出现的都是在大量的堆栈异常日志中出现,怀疑是多行合逻辑不对导致的问题:
下面我们来着重看一下多行最初配置:
1 | multiline: # 多行匹配日志 |
发现官网对于此参数的默认值是5s,但是现在却被误配置成了30s,肯定是有问题的啦
问题的原因应该就在 multiline.timeout
这个参数之上,我们尝试调整多次参数的大小进行测试:
1 | # 由于样本不同,可能内存量也会有所不同,这里选取的是在业务服务中有大量错误堆栈的日志进行测试 |
我的对官方的这句话的理解是:
超时时间后,即使还未匹配到下一个多行事件,也将此次匹配的事件刷出
如果日志中如果包含很多错误堆栈,或者不规范的日志大量匹配多行逻辑,会产生过多的多行合并任务,但是超时时间过长,过多的任务就会最大限度的匹配和在内存中等待,占用更多的内存!
除此以外我们也做了其他调整包括但不限于如下:
queue.mem.events
:从默认的4096 设置到了2048
queue.mem.flush.min_events
: 从默认2048设置到了1536
multiline.max_lines
:从默认500行设置到了200行
最后我们的最优配置如下,在调整之后将问题样本进行测试,内存只占用350M~500M之间:
1 | #=========================== Filebeat inputs ============================= |
对于我们的业务机器来说,让filebeat独占一个CPU去进行日志收集,显然不被业务人员所接受,因为在业务高峰期日志量会很大,filebaat进行大吞吐量的日志收集、多行合并、消息发送;很有可能会限制业务的性能,可能没有filebeat我原本需要10台主机,但是有了filebeat我就需要15台主机来承载高峰业务。
上面的配置虽然已经基本控制住内存用量,但也有可能出现不同的不可预期的情况导致内存增长
我们该如何限制CPU使用量和应对意想不到的内存增长情况?
答案是:绝对性的控制CPU/内存在一个范围内,我们可以使用cgroup来实现
什么是cgroup?
cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制,容器 Docker 技术就使用了 cgroups 提供的资源限制能力来完成cpu,内存等部分的资源控制。
另外,开发者也可以使用cgroup提供的精细化的控制能力,来限制某一组/一个进程的资源使用,比如我们的日志agent需要部署到应用服务器,为了保证系统稳定性,可以限制agent的资源用量在合理范围。
由于篇幅限制,这里对cgroup就不多做介绍了,只说如何使用起来,如果有不明白的,可以查看下方参考链接
cgroup相关的所有操作都是基于内核中的cgroup virtual filesystem,使用cgroup很简单,挂载这个文件系统即可。一般情况默认已经挂载到/sys/fs/cgroup
目录下了
mount | grep cgroup
查看系统默认是否挂载cgroup,cgroup包含很多子系统,用来控制进程不同的资源使用,我们只用其中cpu和memory这两个
/sys/fs/cgroup/cpu
子系统下建立任意目录,如filebeat_cpu
/sys/fs/cgroup/memory
子系统下建立任意目录,如filebeat_memory
filebeat_cpu和filebeat_memory下都会自动生成与上级目录相同的文件,我们重点关注一下几个文件
1 | filebeat_cpu |
改造我们的filebeat启动脚本,支持在启动后限制内存和cpu:
restartFilebeat.sh
1 |
|
限制:
CPU -> 单核25%
内存 -> 500M,大于此值则触发cgroup的OOM-killer机制
优化前:
优化后:
此篇文档着重说明其中第三个模块发布部署的大体流程:
使用菜单:
发布部署包含六个子菜单,每个菜单的功能如下:
文件管理:管理所有服务容器的配置文件,如:服务网关需要挂载于宿主机的服务白名单文件,可以通过此功能进行配置文件内容,关联某台机器的服务容器进行挂载。
服务管理:管理服务基础信息
环境管理:管理环境集信息,以及环境集下某个服务的环境变量信息
节点管理:管理节点信息(一个节点总是从属于某一个环境集)
部署单元:管理部署的服务信息,确定服务最终部署的节点和使用的镜像版本(简而言之就是具体到某个服务容器)
上线部署:上线部署数据来自于部署单元进行筛选展示,执行具体的上线升级,重启,停止操作,可以预览服务运行状态和运行的基本信息(如:当前运行的镜像tag号,服务的最后更新时间,是否需要更新等信息)
部署记录:记录每一次部署升级操作(包括重启和停止),可预览本次升级的yml配置文件并做出有效diff对比
上线场景:上线一个新服务至生产某节点,完成发布,验证存在发布记录。
已知服务基础信息:存在数据库连接,存在生产环境必须的环境变量配置,存在文件需要挂载至宿主机,需要将服务端口映射至宿主机
服务管理=>新增(可根据现有服务进行复制)
以上添加了一个基础服务,配置了服务信息,服务镜像字段不需要填写tag号,只需填写基础镜像即可。
服务中添加环境变量(ENV)的原则是:服务中不易变动的环境变量
环境集中添加环境变量(ENV)原则为:公共的环境变量,数据库资源配置信息
如果新服务有额外的环境变量需要添加,且环境变量只用于新加服务,对于其他服务完全不会需要这些环境变量,则需要添加SetSubEnv,如下:
节点管理=>新增
节点从属某个环境集,所以在添加节点时需要选定所属环境集:
是否是外部机器用于区分是否需要部署服务,一般为否
节点上的环境变量(ENV)添加原则为:尽量不添加,如果添加,必将与节点关联密切,或因节点而异的环境变量。
部署单元=>新增
一个部署单元确认了一个节点上的一个服务容器。
部署单元环境变量添加原则:只要没有特殊情况不需要添加,一旦添加,只会在当前部署单元所在节点生效。
文件描述了一个或多个容器的VOLUMES信息,当添加一个文件后,都需要与指定的部署单元(容器)进行关联,关联的文件或文件夹最终将作为容器的VOLUMES,点击关联部署单元按钮查看或关联/取消关联部署单元。
至此,所有新加的服务配置都已经完成,以上配置在升级时最终都会综合为一份配置文件进行下发如下:
从上面操作可以看到,之前添加的环境变量,文件,都生效于配置文件,确认无误后升级即可启动对应节点上的服务。
系统分为两个主要部分:
配置中心
配置将服务运行所需要的所有配置项入库, 负责生成运行所需的配置文件(一般为yml), 并指示agent进行系统的发布/回滚等.
agent-client(以下简称agent).
agent部署在服务节点上, 并接收配置中心的指令并根据指令做具体的操作.
配置管理员在web配置中心进行增删改操作,更新配置
配置管理员确认配置参数无误,进行配置的同步下发(web端表现为升级操作)
升级完成
服务:微服务架构,将业务细化,每个模块作为一个服务向外提供服务,往往每个模块具体化为一个代码库,而这里的服务就是描述这个镜像最基本的配置
环境集:一个环境集合,例如测试环境中的某个sandbox环境,生产的统一集群环境。环境集中包含一个环境集中服务高度共享的environment
信息
SetSubEnv:环境集内描述某个服务在某个节点的environment
信息
节点:节点从属于环境,一个环境集下可存在多个节点。如生产环境的多个节点app1,app2
部署单元:部署单元由环境集,节点,服务,三部分组合而成的服务容器(通俗的描述:就是在某个环境集的某台节点部署某个服务,在docker服务下表现为服务容器,运行状态下可使用docker ps查询)
文件:文件将会绑定部署单元,而部署单元在升级时会携带绑定的文件和内容
网络:解决特定的网络环境问题,如mtu,容器子网网段
yaml配置文件:每一个容器,在docker-compose模型中,都可以以一份yaml文件来描述其运行信息,应用以各项配置的优先级(服务<环境集<SetSubEnv<节点<部署单元)
进行整合,最终生成为一份yaml配置文件。
构建任务:构建任务描述信心实际上是部署单元的描述信息(在某个环境构建某个服务的某个分支,部署在这个环境的某个节点上)
]]>节点:节点从属于环境,一个环境集下可存在多个节点。如生产环境的多个节点app1,app2
部署单元:部署单元由环境集,节点,服务,三部分组合而成的服务容器(通俗的描述:就是在某个环境集的某台节点部署某个服务,在docker服务下表现为服务容器,运行状态下可使用docker ps查询)
生产–在没有构建中心之前,服务都是在其他环境通过脚本或者jenkins构建成为镜像,再行手动填写更新服务。
测试–通过tscompose构建并启动服务容器,在对应的测试主机上进行反复操作。
构建中心应当是完全替代jenkins进行持续集成的功能模块,在开发此模块的过程中,走了很多弯路。甚至走偏的中心思想。脱离了最初的对于环境集,部署单元的理解。
现在部署中心将与构建环境融为一体,构建从部署配置中来,部署从构建结果中去
。而这也是在初期开发构建中心时最为为头痛的问题,如何将构建个发布结合到一起。(历史原因是部署中心走在前,对于构建的问题没有加强考虑,过于片面的理解所谓的构建)
1.代码源信息描述在何处?
源代码信息维护在服务的基础信息中,因为不论环境如何变化,单个项目的代码源信息是不会改变的
2.在何处构建,在何处发布?
因为项目内容,环境,配置有所不同,服务在何处构建,存在区别。好比普通的sandbox上构建服务都是构建并发布。不存在运维参与升级,测试环境一个特点就是“快”(快速构建,快速发布,快速测试),针对预发布环境是“准”,预发布环境作为上线前最后一道验证环境。需要确认代码准确,并且不被其他因素所影响,比方说服务器性能等等,所以一般不会在预发布环境进行发布并部署,专门使用一台构建主机,预发布环境作为运行环境。生产环境就和预发布环境没什么区别了
3.代码分支如何切换?
在一个环境进行构建,可能需要频繁的切换分支进行构建(比方在预发布环境构建order项目分支为R_001分支),可以将分支描述在部署单元之上,一个部署单元就可以描述一个构建任务,在部署单元上配置的分支就是构建的分支
4.不同服务的构建方法有所不同,怎么描述构建的过程?
尽管各个项目的构建方式不同,如maven,sbt,npm,shell。最终都是一组指令,将这组指令描述在服务信息中
1.在环境集中添加主机时,需要指定构建主机(一个环境集下面可不可以有多个构建主机?)
2.服务管理内描述了服务的源代码信息,构建指令,依赖服务信息
3.部署单元既描述部署信息(某个环境集的某台节点部署某个服务),也描述构建信息(构建某个环境的某个服务的某个分支),通过部署单元对应的环境集查找这个环境集下已经指定的构建主机,而部署节点就是部署单元中所指定的部署节点
4.一个部署单元就相当于构建任务,配置完成后可在持续集成的界面查看其配置改动,开始构建即可在对应构建主机上进行构建,最后在部署节点上进行部署
5.针对服务依赖的管理,首先是从部署单元对应的服务信息中获得服务的依赖树,在构建执行前,查找依赖服务在部署单元中是否存在,如果存在即构建(且这个依赖服务的构建分支由所在的部署单元指定)
6.在部署单元进行部署配置时,填写的镜像tag统一使用latest
,将构建所得镜像唯一的tag打包为latest
镜像进行持续的构建
1 | [A:7349d95 => A:latest] |
定制化打包
1 | <plugin> |
执行本地脚本:
1 | <plugin> |
构建docker镜像
1 | <plugin> |
在maven中运行Ant任务,比如在打包阶段,对文件进行复制
1 | <plugin> |
jar指定目录,设定manifest的参数,或指定运行的Main class,还有依赖的jar包,加入classpath中
1 | <plugin> |
复制依赖的jar包到指定的文件夹里
1 | <plugin> |
用于一键部署,把本地打包的jar文件,上传到远程服务器上,并执行服务器上的shell命令
1 | <plugin> |
用于远程部署Java Web项目
1 | <plugin> |
用于把多个jar包,打成1个jar包一般Java项目都会依赖其他第三方jar包,最终打包时,希望把其他jar包包含在一个jar包里
1 | <plugin> |
获取git的commit-id插件,比如在打包jar包和构建docker镜像时用于区分版本(配合properties-maven-plugin 可使用${git.commit.id.abbrev}使用此变量在其他插件中获取commit-id)
1 | <plugin> |
读取指定properties(这里是配合git-commit-id-plugin 以读取commit-id信息)
1 | <plugin> |
他们的爱与风华,只问自由,只问盛放,只问深情,只问初心,只问勇敢,无问西东。
需要说明几点:
1.tscompose基于docker-compose进行进一步定制,使其能完成dapeng的服务开发=>构建=>发布=>启动整套流程
2.scompose的每个命令可以看作是一组命令的集合,只是简化了操作,做了部分逻辑优化
3.tscompose在使用前需要设置两个环境变量
1 | nodeName=sandbox nodeName,从字面来理解是节点名称,这个名称是至关重要的,下面的多项配置都会使用到此环境变量 |
ts目录结构树:
1 | ➜ tscompose git:(master) ✗ tree . |
常见使用场景
~
一般来说,你的查询可以指引你哪些数据放在tag中,哪些放在field中。
1 | 查看所有数据库 |
终端插入数据
1 | 格式: |
1 | curl -i -xpost http://localhost:8086/query --data-urlencode "q=create database dapengstate" |
通过http接口post数据到/write路径是我们往influxdb写数据的主要方式。下面的例子写了一条数据到mydb数据库。这条数据的组成部分是measurement为cpu_load_short,tag的key为host和region,对应tag的value是server01和us-west,field的key是value,对应的数值为0.64,而时间戳是1434055562000000000
1 | curl -i -xpost 'http://localhost:8086/write?db=dapengstate' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000' |
1 | curl -i -xpost 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server02 value=0.67 |
可以通过curl的@filename来写入文件中的数据,且这个文件里的数据的格式需要满足influxdb那种行的语法。
cup_data.txt
1 | cpu_load_short,host=server02 value=0.67 |
写入
1 | curl -i -xpost 'http://localhost:8086/write?db=mydb' --data-binary @cpu_data.txt |
1 | curl -g 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "q=select \"value\" from \"cpu_load_short\" where \"region\"='us-west'" |
返回值(json)
1 | { |
pretty=ture参数在url里面,是为了让返回的json格式化。这在调试或者是直接用curl的时候很有用,但在生产上不建议使用,因为这样会消耗不必要的网络带宽。
多个查询
1 | curl -g 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "q=select \"value\" from \"cpu_load_short\" where \"region\"='us-west';select count(\"value\") from \"cpu_load_short\" where \"region\"='us-west'" |
需求:
自动将十秒间隔数据聚合到30分钟的间隔数据
自动删除两个小时以上的原始10秒间隔数据
自动删除超过52周的30分钟间隔数据
如果我们写数据的时候没有指定rp的话,influxdb会使用默认的rp
创建一个保留两小时的数据的rp
1 | create retention policy "two_hours" on "food_data" duration 2h replication 1 default |
创建数据库时,influxdb会自动生成一个叫做autogen的rp,并作为数据库的默认rp,autogen这个rp会永远保留数据。在输入上面的命令之后,two_hours会取代autogen作为food_data的默认rp。
创建一个保留52周数据的RP
1 | create retention policy "a_year" on "food_data" duration 52w replication 1 |
1 | create continuous query "cq_30m" on "food_data" begin |
注意到我们在into语句中使用了”
“.” “这样的语句,当要写入到非默认的rp时,就需要这样的写法。
上面创建了一个叫做cq_30m的cq作用于food_data数据库上。cq_30m告诉influxdb每30分钟计算一次measurement为orders并使用默认rptow_hours的字段website和phone的平均值,然后把结果写入到rp为a_year,两个字段分别是mean_website和mean_phone的measurement名为downsampled_orders的数据中。influxdb会每隔30分钟跑对之前30分钟的数据跑一次这个查询。
1 | create database "noaa_water_database" with duration 3d replication 1 shard duration 1h name "liquid" |
该语句创建了一个叫做noaa_water_database的数据库,并且创建了liquid作为数据库的默认保留策略,其持续时间为3天,副本数是1,shard group的持续时间为一个小时。
1 | alter retention policy <retention_policy_name> on <database_name> duration <duration> replication <n> shard duration <duration> default |
创建保留策略what_is_time其持续时间为两天
1 | create retention policy "what_is_time" on "noaa_water_database" duration 2d replication 1 |
修改what_is_time的持续时间为3个星期,shard group的持续时间为30分钟,并将其作为数据库noaa_water_database的默认保留策略:+
1 | alter retention policy "what_is_time" on "noaa_water_database" duration 3w shard duration 30m default |
1 | drop retention policy <retention_policy_name> on <database_name> |
终端:
1 | influxd version |
curl:
1 | curl -i 'http://localhost:8086/ping' |
事件总线(EventBus)设计初衷是解耦系统模块,将系统中的各类业务操作抽象为事件模型。我们把产生事件的部分称之为事件的发送者(Publisher),消费事件的部分称之为订阅者(Subcriber)。
@大鹏开源:别看我有点萌,我可以秒变大鹏。
领域事件是领域驱动设计(Domain Driven Design,简称DDD)中的一个概念,领域模型的变化会产生领域事件,事件的产生往往伴随着相应的动作。例如,用户在完成注册后,系统会发出一封带有确认信息的邮件到用户的邮箱。有了领域事件,每个领域本身就只需要关系其自己的业务逻辑,并在处理完自身逻辑的同时抛出相应的领域事件。对这些领域事件感兴趣的业务方可以订阅该事件,然后进行后续的处理。
结合领域事件和EventBus,我们来看一下基于Today中台架构的EventBus架构模型:
领域事件产生后会有监听者进行事件监听。在如此众多的事件中,需要一个消息总线对消息进行统一的管理。消息总线的作用有:
1.一个大的领域内的各小模块之间的事件的触发和订阅;
2.跨领域(跨JVM进程)之间的事件订阅。
首先领域内某个方法触发事件,例如registerUser()
方法执行成功后,会发布一个用户创建的事件。这时候,我们只需要调用EventBus.fireEvent()
方法,就会将事件发布出去,在EventBus内部,如果本领域内有订阅者订阅此事件,Eventbus就会匹配消息的类型,然后进行相应事件的逻辑处理,这样就做到了领域内的事件监听和处理。
在这种情况下,事件的发布和订阅是强一致性的,两者在同一个处理过程中,当出现错误,触发事件方和订阅方的数据会一起回滚。
1 | def fireEvent(event: Any): Unit = { |
跨领域消息需要通过消息中间件(MQ)来进行传递,目的就是解除系统间的强依赖性,解耦业务模块。
我们的事件总线发布的跨领域(系统)消息,是通过kafka这款消息中间件来进行存储转发的。因为每一条事件消息对业务系统都十分重要,我们要确保发送消息不能丢失,并最终能够被订阅者订阅到。
Kafka的语义很直接,当发布一条消息时,kafka broker
收到后并 committed
到了日志,那么在broker
看来, 这个消息已经发布成功了,同时会有一个ack消息返回给生产者。
当网络不可靠时, 我们会碰到这样一种情形:生产者发送消息时发生网络错误,这时将无法确定错误发生在broker收到消息前还是在收到消息后(返回ack丢失)。
这里我们结合上述三种语义并以发送端(生产者)和接收端(消费者)对消息消费语义的保障分别进行探讨。可分解成两个问题:发送消息时的持久性保障和消费消息的保障。
1 | properties.put(retries, 0); |
当消息发送失败时,不会再尝试进行消息发送,这样虽然保证了消息不会重复发送,但是有可能会丢失消息,这是系统不能容忍的。
1 | properties.put(retries, 2); |
1 | properties.put(enable.idempotence, "true"); |
它的原理就是kafka-broker
为每一个生产者分配了一个PID
,以便区分不同的生产者实例,当然这个PID
对用户不透明,用户无需进行配置。开启了消息幂等后,producer在发送每条消息时,都会带上一个序列号(sequnceId),这样可以在重复发送时根据序列号进行去重。
我们也会考虑这样一种情况,当业务系统需要进行批量消息发送时,如果中途某条消息发送失败后,需要之前发送成功的消息一起回滚,类似于数据库上的事务回滚。
1 | properties.put("transactional.id","GOODS_1213"); |
通过这样的配置之后,消息在批量进行发送出现异常时,放弃当前事务即可。
我们实现的eventbus
事务发送端代码如下:
1 | private def initTransProducer(transId: String): Unit = { |
1 | def batchSend(topic: String, eventMessage: util.List[EventStore]): Unit = { |
上面代码能够保障在批量发送消息时的事务一致性:要么消息全部发送成功,提交事务;如果出现一条失败,则事务回滚。
当然,为了配合事务消息,消费端需要在创建kafka消费者实例时,配置消息获取的隔离级别为read_committed
(读取已经提交的消息)。
1 | properties.put("isolation.level", "read_committed"); |
这样既可以保障事务消息的发送,又能保障幂等性,在消息发送端不考虑非常极端的情况下,是已经做到了正好一次的语义,考虑极端情况下,也可以做到至少一次。
业务系统触发事件之后,会将事件存储在数据库中,然后会有一个定时任务线程定时去轮询数据库获取消息,并使用kafka将消息发送到broker。
使用数据库的事务来保障业务服务接口产生的事件跟业务行为保持强一致性,而在定时发送消息时,也会使用数据库事务+kafka的事务,将消息发送出去。以下为发送消息的逻辑:
1 | def doPublishMessages(): Unit = { |
在上面AAA块的代码中,我们将消息获取和kafka生产者发送消息放到了一个事务里,首先获取到消息,然后删除当前消息,再将消息发送到kafka上,保障消息刚好一次的发送。
如果这时候出现异常(kafka发送数据异常或者删除数据库记录异常),事务就会回滚,消息没有被真正删除,下一次轮询会再次执行这个过程。不考虑极端的情况下,这样的做法可以保证正好一次的消息发送。
考虑极端情况,即消息的删除和kafka发送都成功了,而在事务提交那行代码时,出现异常。这时候,数据库会回滚,但是消息已经被发送到了kafka上,因此这里还是会出现消息的重复发送,但是做到了至少一次, 而且这种情况是极其极端的。
我们已经在不考虑极端的情况下(服务器宕机)做到了正好一次,考虑极端的情况下,做到了至少一次。
然而,极端情况还是有可能会出现,因此最好的解决方案是,我们还会在事件消息上面标记一个事件唯一ID,以支持用户在业务系统上消费消息的时候做幂等处理。
如下是一个标准的业务事件的定义。(详情参考杨权文章)
1 | case class PublishedSkuEvent( |
当然并不是所有的情况都需要这么强力的保障,比如对重复消息不是很敏感的情况,我们不需要发送事务消息或保证消息幂等性,只需要做到消息不会丢失即可。对于延迟敏感的,我们允许生产者指定它想要的耐用性水平。如生产者可以指定它获取需等待10毫秒量级上的响应。生产者也可以指定异步发送,或只等待leader(不需要副本的响应)有响应。
消费端分为领域内事件消费和跨领域事件消费,领域内由于在同一个事务内,强一致性,实现简单,我们这里不再赘述。现在,我们来分析下如何做到跨领域消息订阅和接收。
前文没有提到的一点,我们将事件定义为thrift结构体,并将其序列化为字节流之后持久化到数据库中,kafka发送的时候, 消息内容是序列化之后的二进制byte数组,消费端在接收到消息时,需要进行反序列化和解码后,才能得到消息对象。因此我们设计的api如下:
1 | @KafkaConsumer(groupId = "TEST01", topic ="GOODS") |
1 | @KafkaConsumer(groupId = "TEST01", topic ="SUPPLIER") |
@KafkaConsumer
标于监听类上,定义消费者组和关心的topic。@KafkaListener
标于监听方法上,定义该方法监听的消息类型所需要的序列化器的class。
MsgAnnotationBeanPostProcessor
会对spring管理的bean进行扫描,如果发现有bean类上面有@KafkaConsumer
注解时,就会将进一步判断该类下面是否有标有@KafkaListener
的方法,代码如下(只显示主要逻辑)1 | /** |
@KafkaConsumer
注解和@KafkaListener
注解,就会创建当前consumer
上下文,保存该类的groupId,topic,serializer
等信息,并将这些信息注册到KafkaListenerRegistrar
上面,KafkaListenerRegistrar会以groupId和topic联合作为key,并创建一个kafkaConsumer
实例,放入一个实例列表中,相同的groupId和topic会使用同一个kafkaConsumer实例。代码如下:1 | public class KafkaListenerRegistrar implements InitializingBean { |
1 | public void run() { |
如果消息消费了,但是在未提交偏移量之前,消息是不会丢失的(未处理)。当消息消费后,准备提交偏移量是系统出错了,这时候会导致重复消费,因此也是至少一次的语义。所以这里交给业务系统时,还是需要业务去实现业务去重。
我们在topic的基础上进行了更细粒化的区分,消息能够根据订阅者所感兴趣的事件类型进行选择性发送。
即使两个订阅者方法都订阅了同一个topic,kafka消费者仍然会根据接收到的消息的类型和订阅者方法的所感兴趣的事件类型进行对比,如果当前接收到的事件与订阅事件一致,便会通过反射调用订阅者方法,并将收到的具体事件也传递过去,事件接收成功。
举个例子:
如果kafkaConsumer
从broker接收到消息,解码之后发现事件类型为UserCreated
,那他只会notify接收参数为UserCreated
事件的方法,而不会去调用接收UserRegisted
的订阅者方法。
DDD领域事件的消息总线分析就到这里,本文重点讲了跨领域时,通过kafka消息中间件如何做到消息的稳定发送和接收,不出现消息丢失,触发事件而未发送等情况。
]]>在过去的 30 多年,就已经有领域建模和设计的思潮;Eric Evans 将其定义为领域驱动设计(Domain-Driven Design,简称DDD)。领域模型是领域驱动的核心,而领域事件又作为领域模型中的重要模块,解决了开发者日常开发中的很多痛点,比如,代码耦合降低,拓展性增强。
@大鹏开源:别看我有点萌,我可以秒变大鹏😄
领域模型不是高大上的东西,所有的领域模型抽象都来自于具体的业务及业务的需求,而脱离业务需求的应用设计是没有任何价值的!
比如在Today的新零售电商架构中:门店、采购、订单、供应商、物流、商品、台账等等都是应用设计中的不同领域模型,必然还存在或多或少的子域模型。而对于技术人员来说,这些抽象出来的领域,就代表应用架构存在若干子系统。
系统与系统间,势必会存在某些关联。比如说A领域“发生某件事情”、“当什么产生变化的时候”、“如果什么状态变更”…,都将可能成为B领域所要关心的事件。
我们将发出事件通知的一方称为发送者 (Publisher) ,关心事件的一方称为订阅者 (Subscriber)。
关心一件事,便会收集这件事情相关的信息。而这些都将会转换为消息流,在订阅这件事情的领域间传播,一旦命中所要关心的事情,就由订阅者自行去处理接下来的事情。
以上eventbus示意图大致流程是这样的:
很多业务场景下,我们可能需要在某件事情完成后,根据业务完成状态来做业务路由。
比如说商品领域的的变价审核业务,在商品变价审核通过之后,对应的商品价格也随之生效;价格的变动可能会引起采购,供应商,抑或者门店等领域作出响应的调整。
而我们在代码中通常这样去描述与以上类似的业务:
1 | val code = updateSkuPriceApproveStatus(skuId,status) |
从上面可以看出,当主线业务遭遇某个状态时,需要第三方系统作出应对,我们在主线任务中加入了冗长的代码甚至引入别人的 api ,这使得我的单个业务变的臃肿、过度耦合、不易阅读。恰好领域事件帮助我们更加优雅的解决了这个问题!
当引入事件后,do A 将变成了 send eventA
在 today 中台服务团队的各领域实践中,已经开始投产 eventbus ,并且效果可观,三方系统的订阅对接相当便捷.那这样的事件机制该如何去使用?
为了给第三方系统和本部门的业务开发人员提供一致性的开发体验,我们将事件总线从dapeng的框架中剥离出来, 单独提供了一套类库用于实现事件的发布以及订阅。
1 | "com.today" % "event-bus_2.12" % "0.1-SNAPSHOT" |
1 | CREATE TABLE `common_event` ( |
这里以商品变价审核的状态变更为例,了解在开发中如何做事件发送与订阅.
具体来说,就是四步:
下面具体说明一下每个步骤:
1.事件收发双方共同协定定义事件消息的内容, 一个领域的所有消息定义都在同一个独立的idl文件中. 这个idl文件应该放在发布者的API包中.
2.我们的事件对象需要定义一个事件 id (建议通过分布式取号服务来获取), 订阅者可以自己决定是否需要用这个事件 id 来做消息的幂等处理
==> goods_events.thrift
1 | namespace java com.today.api.goods.events |
== >goods_service.thrift
1 | namespace java com.today.api.goods.service |
注:如果想要了解更多有关文档站点的内容,请留意后期的 dapeng 文档站点专题
==> goods_event_task.thrift
1 | namespace java com.today.api.goods.service |
==> task/GoodsScheduledServiceImpl.scala
1 |
|
关键性的bean配置
所有的事件消息,最终都会发送到 kafka 的队列中,等待订阅者消费;所以每一个配置都将必不可少。==> spring/services.xml
1 | <!--messageTask 事件发布任务bean--> |
topic
kafka 消息 topic,领域区分(建议:domain_version_event
)
kafkaHost
kafka 集群地址(如:127.0.0.1:9091,127.0.0.1:9092)
tidPrefix
kafka 事务 id 前缀,领域区分
dataSource
使用业务的 dataSource
服务配置==> config_user_service.properties
1 | # event config |
AbstractEventBus
,来做好自定义的本地监听分发==> commons/EventBus.scala
1 | object EventBus extends AbstractEventBus { |
==> spring/services.xml
1 | <bean id="eventBus" class="com.today.service.commons.EventBus" factory-method="getInstance"> |
1 | EventBus.fireEvent(RegisteredEvent(event_id,user.id)) |
EventBus
的 dispatchEvent
方法提供领域内订阅者的事件分发,以便本地订阅者可以订阅到关注的事件消息。这些领域内的订阅者,只需要在 dispatchEvent
中模式匹配进行分发。是不是已经是相当的简洁呢?
1 | ... |
对于跨领域事件订阅者
依赖
1 | <!--if => maven project--> |
1 | <bean id="postProcessor" class="com.today.eventbus.MsgAnnotationBeanPostProcessor"/> |
1 | // java |
GoodsEventsConsumer
也需要在 spring 上下文中托管。@KafkaConsumer
groupId
:kafka Consumer groupId,领域区分topic
:kafka 消息 topic kafkaHostKey
: dapeng.kafka.consumer.host
,可以自定义覆盖默认值System.setProperty("kafka.consumer.host","127.0.0.1:9092");
@KafkaListener
通过以上已经知道在事件中,存在领域内的订阅者消费事件消息,也可能存在跨领域的事件订阅者消费事件消息。下面将分析这两者的不同:
需要注意的是:在 eventbus 中,领域内消费事件之后还是会将事件消息广播出去。因为不能保证不会有其他领域对发生的事件感兴趣!
如商品领域的商品变价审核通过后,触发了审核通过事件:
@BinlogListener
1 |
|
总体来说,EventBus 的引入对于开发者而言,不论是事件的发送还是订阅,都是易用的,没有多余的配置。对于第三方系统的支持也做的非常优秀,希望在日常开发中能够更加灵活的运用。尽量减少不必要的耦合!并能经受实践考验!
有关eventBus的具体实现细节,将由小伙伴 hz.lei 来进行剖析!
scala中,带有函数式编程思想的代码很多,如何去理解才更加容易?
1 | def plusOne(num:Int):Int = { |
1 | (Int)=>Int // 函数的"类型"提取 |
1 | val plusOne:Int=>Int={ |
1 | val plusOne=(num:Int) => num+1 |
1 | (num:Int) => num+1 |
1 | val nums=List[Int](1,2,3) |
函数副作用指当调用函数时,除了返回函数值之外,还对主调用函数产生附加的影响。例如修改全局变量(函数外的变量)或修改参数。
1 | f(x) { |
1 | a = 0 |
参考
http://blog.csdn.net/bluishglc/article/details/45291533
https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0%E5%89%AF%E4%BD%9C%E7%94%A8
]]>近期我司项目的需要,采用Angular(4)+SpringBoot前后端分离的架构。并且在需要在项目中实现Arcgis地图。
像我这种菜鸡遇到这种没有干过的事情肯定是先问百度和谷歌,两个关键词敲下。几乎搜索的内容里很少有两个关键字共存的。但是我这慧眼识得好代码,于是发现了这: https://github.com/Esri/angular-esri-map
Esri是美国环境系统研究所公司,多年来,ESRI公司始终将GIS视为一门科学.也就是说这是官方实例呀。
这样就完了吗?不,事情总是没那么简单的。我以负八级的英文水平开始看这个项目的README,第一行。心都碎了[手动心碎]他是这样说的。
A collection of directives to help you use Esri maps and services in your AngularJS v1.x applications.
wtf?==>AngularJS v1.x applications,我的项目用的可是4.x,这不扯淡?
继续遨游在GayHub[手动滑稽]的代码海洋里。皇天不负有心人让我找到了他:
https://github.com/tomwayson/angular2-esri-example
在这里我尝试将他的项目clone到本地,的确可以跑起来,并且可以看到地图,但尝试获取核心代码但是在包下载的时候就出现了很多问题于是放弃了[真的是无限差包]。
因为之前看到是2.x版本就机遇尝试便没有仔细阅读本项目的说明文档。回去看他的说明文档并把Resources
节点下的东西都挨个看了一遍,发现了其中一项貌似很有用:
于是开始阅读这个示例的说明文档,他在文中提到:
This repository is an example of one way to use the ArcGIS API for JavaScript in an application generated with angular-cli.
此存储库是在使用angular-cli生成的应用程序中使用ArcGIS API for JavaScript的一种方法的示例
还有一句:
Adding the ArcGIS API to your own angular-cli application
将ArcGIS API添加到您自己的Angular-cli应用程序
Rather than clone this repository, you should create your own application with the angular-cli and then follow the instructions below to add the above libraries:
而不是克隆此存储库,您应该使用angular-cli创建自己的应用程序,然后按照以下说明添加以上库:
下面的是说明:
上面的意思已经很清楚。这个项目不建议clone,而是使用angular2-esri-loader 来加载ArcGIS模块,angular-esri-components组件是只能在Arcgis4.x版本中使用的。
当点开angular2-esri-loader这个模块的时候,会很清楚的看到如何安装这个Angular的gis加载库,并且写了示例程序。对于angular有一定的了解的话,这些代码或许就能很清晰的表达出它在做什么。
示例的代码就不列出,可以到github上阅读。大体流程是:
项目示例:
https://git.oschina.net/StruggleYang/ngGisDemo
项目效果:
你如果看过Arcgis for JavaScript的代码。那么JavaScript代码,如何转换为Angular(TypeScript)的代码,这里我也没有做过多的了解,只是照葫芦画瓢写的一些:
这里推荐去看一下阮一峰的:ES6标准入门可以提供一些参考
下面将做出原生的Arcgis for JavaScript代码和Angular中的书写对比。
变量声明:
1 | // 有可能你需要在地图初始化前首先声明变量,以便你在任何地方都是可用的 |
地图的模块加载,Arcgis的api是基于dojo框架的,如下:
1 | var map; |
1 | // 这里代码并不全,具体请查看上面的示例项目 |
1 | ... |
这里实际上就是一个箭头函数的区别还有变量的声明区别。
这就结束了?
不不不,远远还不只这些。不论是Angular还是Arcgis,很多东西都没有做过多的了解和深入。不知道那行代码存在隐患。所以革命尚未成功,还得加倍学习和实践巩固。
]]>因为本博客是基于Hexo+GitHub-Pages,所以在hexo -d
后生成的静态文件都存放于github,所以这是不用担心的。本地的hexo博客的源文件内存放着大量的文章markdown文件,所以问题来了。如果换电脑或者硬件损坏,或者有在其他机器更新文章的需求。就需要做一件事情就是将源文件,也就是本地hexo博客源文件的根目录整个备份。
在那么现在就必须做一些前置操作,就是把你的hexo博客源文件备份到GitHub或者其他代码托管平台,这里的操作就不写出来了,可以参考罪恶的起源,git初识里的如何将代码提交到远程仓库。
也可以使用开源中国的码云,我就是用的码云[手动滑稽],操作都是一样的。
清除hexo的
public
目录=>重新生成静态文件=>更新github pages的文章内容=>拉取其他机器的提交=>将所有的文章Markdown源文件改动add到本地暂存=>提交=>push源文件到另一个备份仓库
那么这个命令如何实现,在上一篇文章的额基础上,我对三个命令做出了拓展,使它有一些基本的功能,比如help
,防止自己也忘了这个命令干嘛的。加入了只是本地预览博客的指令-s
。已经一些友好的提示,让你知道它都做了什么。那么来看看这个命令的脚本长什么样吧!
1 | # by StruggleYang |
假设已经将此脚本命名为up.sh
当我输入 sh up.sh
时:
1 | $ sh up.sh |
当我输入sh up.sh help
提示和以上一样,所以我是希望能够在每次更新和提交时,能够足够便捷,并且能够提示我填写commit的desc
还有一个指令是-s
,这个指令的作用显而易见只是将hexo的page重新生成并且能够本地预览。获取并不想提交更新,或者只是调试!
当我真正的需要更新文章或者博客的布局,并且备份元数据!
只需要这样写:
1 | $ sh up.sh "this is commit message test" |
运行如下:
1 | F:\hexo (master) |
等你换了电脑或者公司的电脑来更新的的时候。前提是这台电脑是需要有node.js和npm以及hexo环境的。那只需要将备份的元数据clone到你想要的位置。
执行:
1 | $ npm install |
然后更新文章,继续使用这个脚本来使得hexo变得更为轻松!
]]>事实证明,这样的方式暂时是没有什么问题的。并且非常的方便!
Linux 尝试输入git可查看是否安装,如果未安装按照提示安装
windows直接官网下桌面版
安装完成后,还需要最后一步设置,在命令行输入:
1 | $ git config --global user.name "Your Name" |
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址
注意git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:
1 | $ mkdir learngit |
pwd命令用于显示当前目录
Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。
第二步,通过git init命令把这个目录变成Git可以管理的仓库:
1 | $ git init |
当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏
如果没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。
在当前目录中添加任意文件:readme.txt(示例而已)
将文件添加到仓库
1 | $ git add readme.txt |
将文件提交仓库中
1 | $ git commit -m "wrote a readme file" |
修改了文件git status
查看状态
1 | $ git status |
git status
命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。
git diff
查看具体修改的内容差异
1 | $ git diff readme.txt |
git log
命令显示从最近到最远的提交日志
1 | $ git log |
git log --pretty=oneline
显示简略信息
1 | $ git log --pretty=oneline |
类似3628164…882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
回退上一个版本:
1 | git reset --hard HEAD^ |
回退上一个的上一个版本
1 | git reset --hard HEAD^^ |
版本多了就
1 | git reset --hard HEAD~100 |
通过commit id回退版本或回到最新版
1 | $ git reset --hard 3628164 |
版本号没必要写全,前几位就可以了,Git会自动去找。
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向你回退的版本
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?
Git提供了一个命令
1 | git reflog |
用来记录你的每一次命令:
1 | $ git reflog |
这样可以找到某个版本的commit id了
操作git的目录就是工作区
版本库:
在git init时,会在当前工作区目录下生成.git目录。这不属于工作区的,而属于Git版本库
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
git checkout -- file
可以丢弃工作区的修改:
一种是文件自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
从版本库中删除
1 | git rm file |
提交
第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa
和id_rsa.pub
这两个文件,如果已经有了,可直接跳到下一步。
如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
1 | $ ssh-keygen -t rsa -C "youremail@example.com" |
id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容
为什么GitHub需要SSH Key呢?
因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送
1.在github上创建空仓库
2.关联本地仓库与远程仓库
1 | $ git remote add origin git@github.com:youname/learngit.git |
3.初次推送本地仓库的内容到远程仓库中
1 | git push -u origin master |
1 | $ git push -u origin master |
4.往后的每次推送$ git push origin master
第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:
1 | The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established. |
输入yes回车即可。
git clone
克隆一个本地库:
1 | $ git clone https://github.com/username/gitTest.git |
分支作用:
假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:
每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:
当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:
Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:
合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
创建dev分支,然后切换到dev分支:
1 | $ git checkout -b dev |
git checkout
命令加上-b参数表示创建并切换,相当于以下两条命令:
1 | $ git branch dev |
用git branch
命令查看当前分支:
*号为当前分支
1 | $ git branch |
git merge命令用于合并指定分支到当前分支。所以合并前先切换需要合并的分支之外的分支
1 | $ git merge dev |
Fast-forward 表示是快速合并
1 | $ git branch -d dev |
小结
1 | Git鼓励大量使用分支: |
合并分支时如果有冲突,在当前分支修改后提交,删除要合并的分支
]]>使用github pages服务搭建博客的好处有:
node作用:用来生成静态页面的 到Node.js官网下载相应平台的最新版本,一路安装即可。
git作用:把本地的hexo内容提交到github上去
你的用户名.github.io
的仓库域名配置最常见有2种方式,CNAME和A记录,CNAME填写域名,A记录填写IP,由于不带www方式只能采用A记录,所以必须先ping一下你的用户名.github.io
的IP,然后到你的域名DNS设置页,将A记录指向你ping出来的IP,将CNAME指向你的用户名.github.io
,这样可以保证无论是否添加www都可以访问,如下:
Hexo是一个简单、快速、强大的基于 Github Pages 的博客发布工具,支持Markdown格式,有众多优秀插件和主题。
官网: http://hexo.io
github: https://github.com/hexojs/hexo
1 | $ npm install -g hexo |
在电脑的某个地方新建一个名为hexo的文件夹(名字可以随便取),比如我的是F:\hexo
,由于这个文件夹将来就作为你存放代码的地方,所以最好不要随便放。
1 | $ cd /f/Workspaces/hexo/ |
hexo会自动下载一些文件到这个目录,包括node_modules,目录结构如下图:
1 | $ hexo g || hexo generate # 生成静态页面 |
执行以上命令之后,hexo就会在public文件夹生成相关html文件,这些文件将来都是要提交到github去的:
hexo s
是开启本地预览服务,打开浏览器访问 http://localhost:4000
打开博客根目录下的_config.yml
文件,在最下方找到并照如下修改:
1 | deploy: |
执行命令,自动使用git部署:
1 | npm install hexo-deployer-git --save |
部署:
1 | hexo deploy |
在浏览器输入user_name.github.io
,比如:
user_name是对应的github用户名
1 | hexo clean #清理public下的文件,建议使用,有时候不清理页面不生效 |
1 | hexo new "postName" #新建文章 |
文章在 source/_posts,编辑器可以用 Sublime,vscode,atom,有道云笔记,支持 markdown 语法。如果想修改头像可以直接在主题的 _config.yml 文件里面修改,友情链接,之类的都在这里,修改名字在 public/index.html 里修改
]]>在使用了一段时间的Linux后,前前后后安装也有几十次,也犯过一些致命的错误,为了下次不再到处翻文档,现总结一些安装后必备的东西以及常用软件及操作,以便日后查阅!
备注一下:
注意:请先阅读一遍全文后再操作,适用发行版为Ubuntu16.04及基于Ubuntu16.04构建的发行版,其他发行版部分相同或类似,不保证所有发行版的适用,其余发行版请自行Google对应教程,望悉知
发行版:elementary OS 0.4.1 Loki(基于 “Ubuntu 16.04.2 LTS” 构建)
警告:慎用rm命令,特别是root下的rm,或者带有-rf指令的rm
1 | # sudo apt-get update |
上面的东西执行起来速度可能会很慢,但是这样的过程不会经常出现
在商店对一些软件进行更新,并且安装显卡驱动等等,这些都是可视化的简单操作,这里不再累述
安装系统更新后你可能想安装一些软件了,但是我觉得你有必要进行如下的一些操作:
1 | # timedatectl set-local-rtc 1 --adjust-system-clock |
有可能在第一次安装后执行此操作无效,你可以多试几次并重启
为什么要安装vim,虽然系统已经有vi,但是易用性不是很强,vim是个不错的选择,而且对vi完全兼容,后面的操作里需要有它,所以先将他安装了,方便后面操作
1 | # sudo apt-get vim |
vim的三种模式:
为什么要开机挂载磁盘?
假设一个场景,在某应用不得不需要引用windows的磁盘文件时,每次都会提示找不到路径,那你不得不在文件管理器中将其挂载。为了一劳永逸,并减少不必要的操作。所以建议此步执行,而这个挂载路径的方法使用于部分发行版但又有所不同,如Centos7系列的挂载可能需要安装NTFS3等等操作,具体内容还请Google。
挂载磁盘的基本思路事找到win下对应磁盘的设备号,将其
查看磁盘号,找到type为ntfs磁盘对应的设备号,再根据设备的具体类型大小和LABEL来找到平常对应的挂载路径,再修改设置使其长期挂载。
1 | # sudo fdisk -l |
下面是我的磁盘:
1 | Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors |
如现sda1,5,6,7根据大小可以判断其分别对应的win下C,D,E,F盘,并且最后可看出类型事ntfs格式磁盘
现查看磁盘的id及挂载名
1 | # sudo blkid |
结果
1 | /dev/sda1: UUID="8E5691D85691C17F" TYPE="ntfs" PARTUUID="98eae607-01" |
修改配置
1 | # sudo vim /etc/fstab |
i进入插入模式在后面添加:
注:sy是我的用户名,在media文件夹下你也可以看到你对应的文件夹
1 | # disk for Windows10 |
上面有三个磁盘挂载,C盘我不希望(怕误删了windows下的重要文件)自动挂载所以给注释了。而每个磁盘对应着六个参数其意思分别是:(从左到右)
<file system>
:分区定位,可以给磁盘号,UUID或LABEL,例如:/dev/sda2,UUID=6E9ADAC29ADA85CD或LABEL=Docs<mount point>
: 具体挂载点的位置,例如:/media/userName/C<type>
: 挂载磁盘类型,linux分区一般为ext4,windows分区一般为ntfs<options>
: 挂载参数,一般为defaults<dump>
: 磁盘备份,默认为0,不备份<pass>
: 磁盘检查,默认为0,不检查在这里我发现一个问题就是,NTFS对应的LABEL在windows下对应磁盘的名称,所以建议在windows下使用英文命名磁盘名称
以上操作完成后保存并退出vim,在终端输入以下检查并挂载新添项:
1 | # sudo mount -a |
mount -a会/etc/fstab中的项全部挂载,如果有错,则会提示错误,然后根据错误找出原因修改。
如果说某个磁盘没有找到,先查看是否在文件管理器已经将其挂载,因为在检查时会因为没有挂载而找不到,将所有磁盘挂载后再次执行即可。
注意:千万不要挂载到当前用户的根目录,因为挂载的分区会覆盖当前分区内容,那有可能将是一个致命的操作
两中方式安装:
sudo apt-get install gdebi
安装现在的你可能需一个中文输入法对一些问题进行描述和记录,那么它来了
安装搜狗输入法是一个简单的过程,但是会需要安装一些依赖步骤如下:
先添加以下源
1 | # sudo add-apt-repository ppa:fcitx-team/nightly |
如果提示源找不到依此执行安装:
1 | # sudo apt-get install python-software-properties |
添加源之后需要更新一下系统
1 | # sudo apt-get update |
开始安装fcitx
1 | # sudo apt-get install fcitx |
下载搜狗输入法安装包(官网地址):
http://pinyin.sogou.com/linux/?r=pinyin
下载完毕在文件管理器中用Gdebi打开并安装。
或者在软件包对应的目录(文件名要对应修改)
1 | # sudo gdebi sogoupinyin.deb |
在这里这些常用软件都是deb包的,所以安装过程不再累述,安装只需要gdebi打开就行,或者在命令行进行安装
还有一点注意的事,就是deb包用gdebi安装时会自动将其依赖的包下载安装,所以一些软件你不必去担心他的依赖
下面列出常用的一些可以通过deb软件包程序安装的日常软件:
以上软件deb包都可以在对应的官网进行下载
还有一些可以在应用商店下载安装的程序:
上面做的只是对于日常使用而做的一些安装和配置,对于程序员来讲,要发挥桌面版的Linux的最大作用还差这些东西,现简要列出来:
在ubuntu(elementary OS)下安装MySQL是一件简单的事情,只需要执行以下命令
1 | # sudo apt-get install mysql-server |
安装过程中会让你设定两次mysql的root密码,输完请按tab键到(ok)确定,并继续
1 | # sudo apt-get install mysql-client |
安装完成后用以下命令来检验是否安装成功
1 | # sudo netstat -tap|grep mysql |
通过上述命令检查后如果看到mysql的socket处于listen状态则表示安装成功
登陆mysql检验:
1 | # mysql -u root -p |
键入刚才设置的密码以检验。
卸载openjdk:
1 | # sudo apt-get purge openjdk* |
官网:http://www.oracle.com/technetwork/java/javase/downloads/index.html
下载官方jdk(如:jdk-8u102-linux-x64.tar.gz)
创建JDK存放路径。我的JDK存放在“/usr/jdk”,所以使用命令
1 | # sudo mkdir /usr/jdk |
复制jdk-8u102-linux-x64.tar.gz文件到/usr/jdk,且使用解压缩命令“tar zxvf”解压缩
1 | # cd /usr/jdk |
环境变量配置:
1 | sudo vim /etc/profile |
这时会打开文件,在最后添加:(如果安装路径改变请对应修改)
1 | export JAVA_HOME=/usr/jdk/jdk1.8.0_102 |
添加完成保存关闭,回到终端输入:
1 | # source /etc/profile |
输入java或javac检验
这个东西直接参考Maven官网就可以操作完成了
一般情况下提供tar.gz包和zip包
安装maven的先决条件是JDK哟
假设下载下来的是tar.gz包:apache-maven-3.5.0-bin.tar.gz
将其存放到你想安装的目录,在存放目录下执行:
1 | # sudo tar -zxvf apache-maven-3.5.0-bin.tar.gz |
现假设Maven被安装在/usr/maven目录下:(此操作将其加入环境变量但只是暂时的)
1 | # export PATH=/usr/maven/apache-maven-3.5.0/bin:$PATH |
环境变量永久生效:
1 | # sudo vim /etc/profile |
加入以下变量:
1 | #maven |
wq退出后刷新使环境变量生效
1 | # source /etc/profile |
检验安装:
1 | mvn -v |
正确输出:(类似就行,不必一样)
1 | Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T03:39:06+08:00) |
Tomcat安装与上面几个安装是类似的:
下载tar.gz包,不再累述复制和解压过程,请参照以上两个解压过程
现假设下载tomcat7被解压安装到了/usr/tomcat7/
下:
先将tomcat文件夹及子文件权限改到任意人读写执行
1 | # sudo chmod -R a+rwx /usr/tomcat7/* |
找到bin目录:
1 | # cd /usr/tomcat7/apache-tomcat-7.0.73/bin |
启动:
1 | # ./startup.sh |
提示jdk环境问题:
1 | # sudo vim catalina.sh |
加入JDK的环境变量:(请相应改变)
1 | export JAVA_HOME=/usr/jdk8/jdk1.8.0_131 |
正确输出:
1 | Using CATALINA_BASE: /usr/tomcat7/apache-tomcat-7.0.79 |
停止:
1 | sudo ./shutdown.sh |
IDEA的安装过程没有多大变化,下载解压即可使用。
官网:http://www.jetbrains.com/idea/
除了IDEA很多jetbrains家族的东西都是很好用的,在Linux平台也有很好的更新支持
如果是Android开发者,android studio也会很容易兼容此系统
关于科学上网,我是用的奇影shadowsocks。一般我也用的不多,同步Chrome书签和插件时,找找Google时会用用!
]]>还有很多有趣的东西自己去探索吧。此文为迁移博文。之前发表于=>我的CSDN