首页 文章 精选 留言 我的

精选列表

搜索[快速],共10000篇文章
优秀的个人博客,低调大师

通过简单例子 | 快速理清 UML 中类与类的六大关系

类与类之间的六大关系 泛化 ( Generalization ) ---> 表继承关系 实现 ( Realization ) 关联 ( Association ) 聚合 ( Aggregation ) 组合 ( Compostion ) 依赖 ( Dependency ) 前言: 最近学校在上统一建模语言 UML ,也是毕业设计中需要用到,做个小记录。 希望这篇文章能够给大家带来些许收获,让大家趁兴而归。 一、单个类的类图 一步一步来,我们先学学如何使用 UML 图来表示单个类。 我先把类贴下面: package uml; /** * @Author: crush * @Date: 2021-09-30 15:00 * version 1.0 */ public class Person { private String name; private Integer age; private static String school="某小学"; public static String nationality="中国"; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public static String getSchool() { return school; } public static void setSchool(String school) { Person.school = school; } public static String getNationality() { return nationality; } public static void setNationality(String nationality) { Person.nationality = nationality; } public void selfIntroduction(String name, Integer age, String school){ System.out.println("做一个自我介绍,我的名字是:"+name+",今年"+age+"岁了,来自于"+school); } } 这个类还是非常简单的哈,接下来就是要如何用一个类图来进行描述呢? 如下图: 解释: 上半部分是 Person 类的属性,下半部分是 Person 类的方法 - name:String 描述的是:private String name; -号:表示为私有属性( private ),反过来 + :就表示 public name:为属性名称 :xxx :是表示属性的类型的。此处为 String 类型 <u>-School:String="某幼儿园"</u> :描述的是 private static String school="某小学"; <u>下划线</u>是表示此属性为 static(静态属性) "某幼儿园" 表示有默认值。 其他同上。 <u>+ getNationality():String</u> 描述的是 public static void setNationality(String nationality) { Person.nationality = nationality; } 和上面基本一样,+ 表示 public ,下划线表示 static 修饰,getNationality() 表示方法名,String 表示返回值为String类型。 但是平时中,我们通常都是多个类之间有关系,不是个孤零零的孤寡老人。 二、多个类之间的关系 表达多个类之间的关系有以下六种: 泛化 ( Generalization ) ---> 表述继承关系 ( 三角箭头的实线,箭头指向父类 ) 实现 ( Realization ) ( 三角箭头的虚线,箭头指向接口 ) 关联 ( Association ) ( 普通箭头的实心线,指向被拥有者 ) 聚合 ( Aggregation ) ( 空心菱形的实心线,菱形指向整体 ) 组合 ( Compostion ) ( 实心菱形的实线,菱形指向整体) 依赖 ( Dependency ) ( 箭头的虚线,指向被使用者 ) 三、继承和实现的类图 3.1、继承 【泛化关系】:是一种继承关系,表示一般与特殊的关系,它指定了子类如何特化父类的所有特征和行为。例如:老虎是动物的一种,即有老虎的特性也有动物的共性 1)代码 动物类: public class Animal { private String name; private Integer age; public Animal() { } public Animal(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } 猫类继承动物类: public class Cat extends Animal { private String breeds; public Cat(String name, Integer age, String breeds) { super(name, age); this.breeds = breeds; } public String getBreeds() { return breeds; } public void setBreeds(String breeds) { this.breeds = breeds; } public void selfIntroduction(String name,Integer age,String breeds){ System.out.println("我叫"+name+",是一只"+breeds+"品种的猫,今年"+age+"岁了,"); } } 我们用类图来表示这个关系。 4)图示 箭头要用对,不然关系就完全不一样拉。 3.2、实现 【实现关系】:是一种类与接口的关系,表示类是接口所有特征和行为的实现. 1) 代码 吃睡接口,我们再让动物类来实现他两。 public interface Eat { void eat(); } public interface Sleep { void sleep(); } public class Animal implements Eat,Sleep{ private String name; private Integer age; public Animal() { } public Animal(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public void eat() { System.out.println("吃东西"); } @Override public void sleep() { System.out.println("睡觉"); } } 2) 图示 四、关联关系的类图 【关联关系】:是一种拥有的关系,它使一个类知道另一个类的属性和方法;如:老师与学生,丈夫与妻子关联可以是双向的,也可以是单向的。双向的关联可以有两个箭头或者没有箭头,单向的关联有一个箭头。 我们增添一个出身地的类,每个动物都会有一个出生地的地方。 我们将这个出生地和动物关联起来。 4.1、代码 /** * @Author: crush * @Date: 2021-09-30 19:11 * version 1.0 * 出生地 */ public class Birthplace { private String birthplace; public Birthplace(String birthplace) { this.birthplace = birthplace; } public String getBirthplace() { return birthplace; } public void setBirthplace(String birthplace) { this.birthplace = birthplace; } } 与动物类关联起来: public class Animal implements Eat,Sleep{ private String name; private Integer age; private Birthplace birthplace; public Animal() { } public Animal(String name, Integer age, Birthplace birthplace) { this.name = name; this.age = age; this.birthplace = birthplace; } public Birthplace getBirthplace() { return birthplace; } public void setBirthplace(Birthplace birthplace) { this.birthplace = birthplace; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public void eat() { System.out.println("吃东西"); } @Override public void sleep() { System.out.println("睡觉"); } } 在自我介绍方法中增添输出。 public class Cat extends Animal { private String breeds; public Cat(String name, Integer age,Birthplace birthplace, String breeds) { super(name, age,birthplace); this.breeds = breeds; } public String getBreeds() { return breeds; } public void setBreeds(String breeds) { this.breeds = breeds; } public void selfIntroduction(String name,Integer age,String breeds,Birthplace birthplace){ System.out.println("我叫"+name+",是一只"+breeds+"品种的猫,今年"+age+"岁了,出生于"+birthplace.getBirthplace()); } } 4.2、图示 五、聚合和组合关系的类图 5.1、聚合 聚合 ( Aggregation ) : 是整体与部分的关系,且部分可以离开整体而单独存在。如车和轮胎是整体和部分的关系,轮胎离开车仍然可以存在。 聚合关系是关联关系的一种,是强的关联关系;关联和聚合在语法上无法区分,必须考察具体的逻辑关系。 先说说我这个例子,我们再写代码。 【例子】每台车都会有四个轮胎和一个引擎,轮胎离开车可以单独存在的,引擎同样也是。 1)代码 public class Wheel { private String type; public Wheel(String type) { this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } public void move(){ System.out.println("滚动!!!"); } } public class Engine { private String type; public Engine(String type) { this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } public void start(){ System.out.println("启动引擎!!!"); } } public class Car { private Wheel wheel; private Engine engine; public Car(Wheel wheel, Engine engine) { this.wheel = wheel; this.engine = engine; } public Wheel getWheel() { return wheel; } public void setWheel(Wheel wheel) { this.wheel = wheel; } public Engine getEngine() { return engine; } public void setEngine(Engine engine) { this.engine = engine; } public void go(){ System.out.println("开车出去浪;啊"); } } 用类图如何表示勒,接着往下看👇 2)图示 5.2、组合 组合 ( Composition ) : 是整体与部分的关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系,没有公司就不存在部门。还有如人由头和身体组成,没有了人,头和身体还咋存在勒。 组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。 1)代码 public class Body { private double size; public Body(double size) { this.size = size; } public double getSize() { return size; } public void setSize(double size) { this.size = size; } } public class Head { private double size; public Head(double size) { this.size = size; } public double getType() { return size; } public void setType(double size) { this.size = size; } } public class Person2 { private String name; private Head head; private Body body; public Person2(String name, Head head, Body body) { this.name = name; this.head = head; this.body = body; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Head getHead() { return head; } public void setHead(Head head) { this.head = head; } public Body getBody() { return body; } public void setBody(Body body) { this.body = body; } public void say(){ System.out.println("我会说话"); } } 2)图示 六、依赖关系的类图 依赖(Dependency): 关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。 在 UML 类图中,依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类。如人与手机的关系图,人通过手机的语音传送方法打电话。 1、代码 public class Phone { public void callUp(){ System.out.println("与人通话"); } } public class Person3 { private String name; public Person3(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void callUp(Phone phone){ System.out.println("使用手机打电话"); phone.callUp(); } // 下面这种方式也是依赖关系 // public void callUp(){ // Phone phone=new Phone(); // System.out.println("使用手机打电话"); // phone.callUp(); // } } 2、图示 七、类关系的强弱 强弱关系:泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖 另外我们常常说的降低耦合性,也是降低类与类之间的关系。 八、自言自语 今天的文章就到这里了。 如若在文章中遇到疑惑,请留言或私信,或者加主页联系方式,都会尽快回复。 如若发现文章中存在问题,望你能够指正,不胜感谢。 如果觉得对你有所帮助的话,请点个赞再走吧!. 知乎 | 宁在春 简书 | 宁在春 CSDN | 宁在春 掘金 | 宁在春 博客园 | 宁在春

优秀的个人博客,低调大师

开源的傻瓜搜索引擎,帮你快速实现搜索功能

傻瓜一词借鉴自傻瓜相机,又称轻便相机、全自动相机,通常指容易操作针对一般人而设计的小型全自动相机。 在 HelloGitHub 找到有趣、入门级的开源项目,大家好我是卤蛋。说到开源搜索引擎第一个想到的应该是鼎鼎大名的 ElasticSearch,但 ES 对于个人项目有些重。 今天给大家带来一款轻盈、人人都会用的开源傻瓜搜索引擎——MeiliSearch https://github.com/meilisearch/MeiliSearch 在介绍 MeiliSearch 的功能之前,我想先聊下我是怎么找到它并喜欢上它的。 我的要求并不高 我开发的 HelloGitHub 小程序:支持关键字搜索往期月刊中的开源项目。 小程序的搜索功能是用 Rust 写的开源搜索引擎 Sonic,它虽然搜索速度快但使用过程中发现: 不支持中文分词,导致搜索结果较差 没有官方的 Python 客户端,三方开源客户端问题较多 搜索返回的结果仅有 ID,需要再去数据库关联其他数据 这些问题直接影响了搜索的体验,让我十分苦恼一边看搜索相关的知识,另外也在寻找新的开源解决方案。想找一个: 部署+配置简单、支持中文分词、搜索速度快、轻量级开源搜索引擎项目。 俗称:傻瓜中文搜索引擎。 它有个美丽的名字 它有个“美丽”(meili)的名字「MeiliSearch」,同样是用 Rust 写的开源搜索引擎,支持: 概述功能:搜索速度快、全文搜索、支持汉字、容易安装和维护,这不就是我在找的:傻瓜中文搜索引擎吗? 我已经摩拳擦掌的跃跃欲试了,话不多说搞起! 简单的开始 纸上得来终觉浅,得上手试试效果。 1、安装和启动 Linux & Mac OS 的一键安装和启动的命令: curl -L https://install.meilisearch.com | sh ./meilisearch 这个安装够不够傻瓜🤪 启动成功如下图: 用浏览器访问:http://127.0.0.1:7700/ 就可以看到 MeiliSearch 提供的 Web 搜索页面。我提前写入了一些数据,用来演示搜索: 2、基本操作 MeiliSearch 就是一个搜索的服务,提供 RESTful API 通讯协议更加通用,官方提供了多种编程语言的客户端: JavaScript Python PHP Go ... 后面的演示将采用 Python 代码作为示例,安装 Python SDK: # 要求 Python3.6+ pip3/pip install meilisearch 用 Python 实现连接、写入、查询、删除等基本操作: import meilisearch client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey') # masterKey 是密码 # index 相当于数据库的表 index = client.index('books') # 准备写入搜索的数据 documents = [ { 'book_id': 123, 'title': 'Pride and Prejudice' }, { 'book_id': 456, 'title': 'Le Petit Prince' }, { 'book_id': 1, 'title': 'Alice In Wonderland' }, { 'book_id': 1344, 'title': 'The Hobbit' }, { 'book_id': 4, 'title': 'Harry Potter and the Half-Blood Prince' }, { 'book_id': 42, 'title': 'The Hitchhiker\'s Guide to the Galaxy' } ] # 删:清空指定 index index.delete_all_documents() # 写: result = index.add_documents(documents) # 该引擎会根据写入数据 ID 做替换或者新增的操作 # 写入后并不代表搜索引擎处理完成,可以查看返回 updateId 的状态 index.get_update_status(result.get('updateId')) # enqueued, processed or failed 三种状态(processed 代表完成) # 查: index.search('harry pottre') # 结果: # 包含丰富的字段 """ { // 命中的结果 "hits" => [{ "book_id" => 4, "title" => "Harry Potter and the Half-Blood Prince" }], // 页 "offset" => 0, // 每页条数 "limit" => 20, // 处理耗时 "processingTimeMs" => 1, // 查询的内容 "query" => "harry pottre" } """ 至此已经实现了搜索的最基本的功能,但探索不止于此。 3、优化搜索效果 MeiliSearch 可通过配置规则来提高搜索结果: synonyms:同义词 stopWords:停用词(为节省存储空间和提高搜索效率,自动过滤掉某些字或词) rankingRules:排序规则 ... 可以用 Python 客户端更新 MeiliSearch 配置,示例代码: # 停用词 client.index('movies').update_settings({ 'stopWords': [ 'the', 'a', 'an' ], }) # 排序规则 client.index('movies').update_ranking_rules([ "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", "asc(publish_time)", "desc(watch)" ]) # 查看 stop words client.index('movies').get_stop_words() # 重置设置 # index.reset_settings() # 除了搜索其它操作都是异步,会直接返回一个 updateId 需要通过 ID 查询处理状态 # wait_for_pending_update 可阻塞等待处理结果 这些设置可以有效的提高搜索效果,比如使用停用词之前,搜索“开源的书籍”命中不了“开源书籍”,加了停用词即可命中,因为匹配时忽略了输入内容包含的停用词(无用词)。 说一个我遇到的坑,我测试搜索效果时发现:go 搜不到,但是 golang 就可以搜索到,排查了半天最后发现是因为 go 在上面的停用词字典中😅 另外,功能上对比 sonic 没有词联想(suggest),可以通过新建 index+searchableAttributes 实现。 同义词集合我没有找到,如果大家有现成的 中/英文 同义词词典,欢迎留言告诉我~感谢 4、部署 MeiliSearch 部署很简单,增加到系统的 systemd 服务就行了。 cat << EOF > /etc/systemd/system/meilisearch.service [Unit] Description=MeiliSearch After=systemd-user-sessions.service [Service] Type=simple ExecStart=/usr/bin/meilisearch --http-addr 127.0.0.1:7700 --env production --master-key xxxxxx [Install] WantedBy=default.target EOF # Set the service meilisearch systemctl enable meilisearch # Start the meilisearch service systemctl start meilisearch # Verify that the service is actually running systemctl status meilisearch 但部署正式环境,需要注意以下几点: 生产环境必须设置密码,开发环境无强制 生产环境 Web 页面会关闭 没有远程访问和权限控制,可以通过 Nginx 实现 IP 白名单+ Cerbot 实现 HTTPS,提高安全性 可通过 curl 地址 查看服务状态 以上就是我使用 MeiliSearch 的一些心得,总体给我的感觉: 安装简单,没有复杂的配置:省心 数据写入方便,功能丰富:傻瓜 查询快 一条命令即可启动搜索服务,一行代码实现搜索功能,有了它我这个搜索小白都能分分钟实现一个搜索服务,舒服~ 爱的结晶(实战) 我用 MeiliSearch 重写了 HelloGitHub 小程序的搜索功能,后端用的 FastAPI 框架。除此之外还增加了一些新功能: 热门搜索词 项目详情页 项目镜像地址提高访问速度 新的界面 HelloGitHub 小程序第二版效果图如下: 已上线,微信搜:HelloGitHub 小程序,即可使用 后面计划增加:信息流、评论、打分、用户系统、积分系统,因为只有我一个人开发,所以进度会很慢...但我不会半途而废哒 💪 最后 如果说 MeiliSearch 缺点的话,我觉得搜索准确度还有待提高,一方面我需要学习下分词和 NLP 的一些知识,另一方面需要再熟悉下它的 API 和原理,然后再找一些词典辅助,应该能提高准确度,但心急吃不了热豆腐慢慢来吧。 最后,希望本文的分享有帮助到你,今天的文章就到这里了。 优秀的开源项目像散落在海边的贝壳,需要发现它的人。 HelloGitHub 就是拾贝者,找开源项目来 HelloGitHub 就对了! 关注 HelloGitHub 公众号 第一时间收到更新。 还有更多开源项目的介绍和宝藏项目等待你的发现。

优秀的个人博客,低调大师

直播回放:快速上手,使用 Kotlin 把支付宝小程序装进自己的 App

写一个 Android App 或许不难,但企业对于移动应用的要求愈来愈高,不只要求开发速度、稳定度、质量等,甚至希望能具备动态扩展的架构设计、在 App 中自启动小程序。面向这些需求,若是有好的开发工具及平台的支持,将可以大大降低开发及运维的成本。本次网络研讨会特别邀请到支付宝高级无线开发工程师温盛章为大家演示用 Kotlin 开发移动应用,并集成 mPaaS 让 App 具备小程序能力。 ▶点击观看全程回放 主题分享 本次分享共有三个关键字:Kotlin 、 小程序 、 mPaaS 。温盛章首先从用户、开发、技术、平台等四大视角,向大家说明小程序是什么?简单来说,小程序就是一种拥有完整生命周期、应用间相互隔离、独立运行于宿主应用内的应用。而小程序从工作型 App、平台型 App、超级 App 到新阶段一路的演化历程,目前已经可以有接近 Native 的体验和顺畅、也可以有 H5 的快捷发布的优势。 对小程序有概念后,温盛章就以 Android Studio 演示如何在一个 Mobile App 里,以 Kotlin 撰写 Mobile App 的代码,并接上 mPaaS 平台,让 App 有自启动小程序的能力。要接入 mPaaS,首先需在 Android Studio 里安装 mPaaS 插件,并到阿里云的 mPaaS 后台创建一个新建用。接着,在 Android Studio 里通过插件介入 mPaaS 后下载设置文件及基线。再来,依照项目的需求,下载所需的 mPaaS 组件。完成这些设置后,在 Native 部份,仅需 App、Activity、Plugin 三个文件,就可以做出一个接上小程序的简单应用。 小程序的部份,可以通过 mPaaS 的 IDE 撰写 HTML、CSS、JS 完成小程序端的开发,上传至 mPaaS 后台后,就可在 App 里启动。不仅如此,mPaaS 的 SDK 还可以将 Native 端与小程序间打通,两者可以交互传递信息,只要照着文档示例操作,一个具备小程序能力的移动应用,就在不到 1 小时内完成! 听完这场分享后,相信大家都能体验小程序在开发及部署的好处、Kotlin 语法的简洁及 mPaaS 服务的完整性。通过这样的工作流,可帮助您实现“代码仅需撰写一次,便可多端投放”,从而深度提升研发效率。 Q&A Q. 学习 Kotlin 可以完全不用懂 Java 吗?或者了解下 Java 的一些基本知识就够了? 温盛章:Kotlin 在设计上有许多语法糖,像是 Extension 可以轻松的依据需要做扩展、Lambda 表达式可以构成 DSL 的能力、Coroutine 把线程封装后更好使用,加上现在 Google 的 Android 团队采用 Kotlin 做为官方语言,所以我觉得可以先以 Kotlin 为主去学习 Android 开发。不过,别忘了 Kotlin 最终还是编译成 JVM 的字节码,所以要搞清楚底层的话,一些基本功还是不能落下。 范圣佑补充:学习 Android 时,可以到 Google 的 Code Lab 上学习,非常适合初学者。 Q. 我的理解是 Kotlin 是负责数据的处理,而像获取安卓手机信息这个功能只需要调用安卓的一些组件就能实现了是吗? 温盛章:这个东西需要隔离开来看,我们可以先把 Kotlin 理解成一个槌子,调用安卓组件我们可以简单的理解成钉子。怎么把钉子打到墙里面,你可以用槌子、也可以用剪刀,只要能完成任务就行。但很明显的,用剪刀把钉子打到墙里估计要比槌子难,所以 Kotlin 在这里就是扮演着槌子的角色。就我自己使用的经验来说,Kotlin 在提升效率这方面带来非常大的帮助。原本用 Java 得写又臭又长的代码,改用 Kotlin 后就变得非常的简洁。 我这边要特别强调一下 Kotlin 里 Null Safety 的特性,以前在 Java 里一个变量是否为 Null 需要在逻辑层里自行解决,但在 Kotlin 里可以用问号,通过编译器就可以预先做好对空值的处理。这部份的强化和提升是我非常喜欢的。 Q. 用 Kotlin 开发安卓,用 Andriod Studio 比较好还是用 IntelliJ IDEA 更方便些,有哪些好用的插件了可以推荐下? 范圣佑:Android Studio 和 IntelliJ IDEA 是使用相同的 IntelliJ Platform 打造出来的,所以在 UI、快捷键操作上其实都很雷同,许多插件也是可以互通的。若你只需要开发 Android 的话,用 Android Studio 其实就可以满足你的需求;但若你不仅需要开发 Android,还需要开发像 Web、数据库的工作,那会推荐使用 IntelliJ IDEA Ultimate 版才能满足各方面的需求。 温盛章:单纯开发 Android 或 Android 与其他工程混在一起的项目,我会推荐用 Android Studio;但假如是纯 Java 或 Kotlin 的项目,我就会推荐用 IntelliJ IDEA,而且非常推荐使用 Ultimate 版,因为 Ultimate 版相比 Community 版提供了更多的功能,非常的好用。 两位推荐的插件包括: 1)在演示过程中可以显示快捷键提示的 Presentation Assistant 插件 2)让 IntelliJ IDEA 可以有像 Vim 一样操作模式的 IdeaVim 插件 3)本次演示的主角 mPaaS 插件(目前仅支持 Android Studio) 4)用 Annotation 让 Java 有一些类似 Kotlin 特性的 Lombok 插件 Q. 有办法可以 Android 模拟器调试吗? 温盛章:以开发 mPaaS 应用来说,因为没有提供 x86 及 x64 的 Native 支援,所以很遗憾的目前没有办法以 Android 模拟器调试,只真机调试。对于 Android 开发者来说,因为 Google 及许多平台的 SDK 对 x86 的支持也不是那么的好,加上考虑自己的电脑是不是够快,所以 Android 开发我还是强调建议真机调试。 Q. 请问手机投屏的软件是? 温盛章:付费版的 Vysor。 Q. 请问小程序怎么不选择 Flutter 作为引擎? 温盛章:小程序的好处是上层使用的语言(也就是使用 HTML、CSS、JS)及下层搭配用 Web View 显示已经固定且稳定,所以 mPaaS 优先支持这样的架构。而 Flutter 在下层使用的引擎不同,我们其实已经有在做尝试,但现阶段还不适合商业公开。等到技术上够成熟后,会再公开 mPaaS 与 Flutter 的版本。 END

优秀的个人博客,低调大师

阿里云自助建站,阿里云模板建站快速建设一个企业网站

使用阿里云建网站的三种方式购买云服务器手动建站、云速成美站模板建站或者选择阿里云定制建站三种方式,站长分享利用阿里云创建网站的三种方式及优势对比: 阿里云建站方法汇总 使用阿里云建站可以有三种方式,一种是购买ECS云服务器,然后自行手动搭建网站,需要技术门槛;第二种方式是购买阿里云官网云速成美站,使用模板建站,阿里云提供上千套模板,模板建站价格便宜,会打字就会建站;第三种是使用阿里云官方定制建站,需要什么样的网站什么功能,阿里云建站专家提供一对一网站定制。参考下表: 阿里云建站方式 所需产品 优势 适用人群 自助建站 ECS云服务器 自行购买云服务器,手动搭建网站 需要些技术门槛,适用于刚接触云计算或对云服务器和建站不太了解、希望自行设计网站的个人或小企业用户。 模板建站 云·速成美站 使用阿里云提供上千套模板,可视化后台管理,会打字就会建站 适合有一定软件应用能力的个人或小企业用户,模板建站支持Web站点、移动端站点、互动表单以及会员支付多场景。 定制建站 云·企业网站定制和功能定制 由阿里云专业网站设计师完成网站设计及搭建 适合对网站有品质要求或个性化需求、希望节省人力和时间成本的企业用户。 阿里云建站产品如何选择?如果您是站长类的技术人员,当然选择自助建站方式,如果非技术人员,个人或者工作室建议选择云·速成美站,如果是企业用户建站选择阿里云网站定制服务。 阿里云建站不需要用户另外购买云服务器或虚拟主机等产品,阿里云提供香港节点并且提供全球CDN加速,不用备案,拿来即用。阿里云大品牌无隐形消费,我见过太多打着免费建站的幌子,实际价格贵的离谱。举例来说,免费建站,使用的域名是对方的三级域名,域名人家说收回就收回,免费建站,云主机却要收费,而且价格很贵没有质量保障,网站说打不开就打不开。 我从新手过来的,之前使用过免费域名,用了有一段时间了,结果被收回了,使用免费虚拟主机,速度卡不说,结果网站数据丢失了,这不是免费惹的祸,是小编贪图便宜惹的祸,建议选择大品牌,值得信赖。

优秀的个人博客,低调大师

快速上手百度大脑EasyDL专业版·物体检测模型(附代码)

作者:才能我浪费99 1. 简介: 1.1. 什么是EasyDL专业版 EasyDL专业版是EasyDL在2019年10月下旬全新推出的针对AI初学者或者AI专业工程师的企业用户及开发者推出的AI模型训练与服务平台,目前支持视觉及自然语言处理两大技术方向,内置百度海量数据训练的预训练模型,可灵活脚本调参,只需少量数据可达到优模型效果。 适用人群: 专业AI工程师且追求灵活、深度调参的企业或个人开发者 支持定制模型类型。 1.2. 支持视觉及自然语言处理两大技术方向: 视觉:支持图像分类及物体检测两类模型训练。 任务类型: 预置算法 图像分类: Resnet(50,101)、Se_Resnext(50,101)、Mobilenet Nasnet 物体检测: FasterRCNN、YoloV3、mobilenetSSD 自然语言处理:支持文本分类及短文本匹配两类模型训练,内置百度百亿级数据所训练出的预训练模型ENNIE. ERNIE(艾尼)是百度自研持续学习语义理解框架,该框架可持续学习海量数据中的知识。基于该框架的ERNIE2.0预训练模型,已累计学习10亿多知识,中英文效果全面领先,适用于各类NLP应用场景。 任务类型 :预置网络 文本分类: BOW、CNN、GRU、TextCNN、LSTM、BiLSTM 短文本匹配:SimNet(BOW、CNN、GRU、LSTM)、FC 1.3. EasyDL专业版特点 预置百度百亿级数据规模的预训练模型,包括丰富的视觉模型及自然语言处理模型ERNIE,训练效果更突出。 对比经典版,支持代码级调整模型参数和模型结构,封装底层算法逻辑细节,代码行数更少,更易有算法基础的开发者上手。 支持从数据管理,模型训练到模型部署一站式AI服务。 如果说EasyDL经典版是倚天剑,PaddlePaddle是屠龙刀,那么EasyDL专业版就是刀剑合璧。 2. 评测案例 该应用为一个特种车辆识别的应用,主要识别邮车和消防车,未来可以扩展加入更多的车辆种类,对于特种车辆管理有很好的应用价值。 2.1. 整体说明 EasyDL专业版的工作流程如下图所示: EasyDL专业版的主界面如下图所示: 2.2. 业务需求: 需要对各种特种车辆进行识别,在本评测中为邮车、消防车两种。 2.3. 上传并标注数据: 首先需要建立特种车辆数据集,在主界面上点击“数据管理/标注”就可以进入数据管理界面,具体步骤如下: 1.设计标签 在上传之前确定想要识别哪几种物体,并上传含有这些物体的图片。每个标签对应想要在图片中识别出的一种物体。在本例中只有2个标签,就是邮车(标签:youche)和消防车(标签:xiaofang)。 例如: 2.准备图片 基于设计好的标签准备图片: 每种要识别的物体在所有图片中出现的数量最好大于50 如果某些标签的图片具有相似性,需要增加更多图片 一个模型的图片总量限制4张~10万张 图片格式要求: • 目前支持图片类型为png、jpg、bmp、jpeg,图片大小限制在4M以内 • 图片长宽比在3:1以内,其中最长边小于4096px,最短边大于30px 图片内容要求: • 训练图片和实际场景要识别的图片拍摄环境一致,举例:如果实际要识别的图片是摄像头俯拍的,那训练图片就不能用网上下载的目标正面图片。 • 每个标签的图片需要覆盖实际场景里面的可能性,如拍照角度、光线明暗的变化,训练集覆盖的场景越多,模型的泛化能力越强。 本例中从网上找了30多张不同角度的特种车辆图片。(因为是测试版,所以图片较少,实际应用的时候每种标签的图片不应少于50) 3. 上传和标注图片 先在【创建数据集】页面创建数据集: 如果训练数据需要多人分工标注,可以创建多个数据集。将训练数据分批上传到这些数据集后,再将数据集"共享"给自己的小伙伴,同步进行标注。 再进入【数据标注/上传】: 1、选择数据集 2、上传已准备好的图片 3、在标注区域内进行标注 首先在标注框上方找到工具栏,点击标注按钮在图片中拖动画框,圈出要识别的目标。 如下图所示: 然后在右侧的标签栏中,增加新标签,或选择已有标签 2.4. 创建项目和任务 在主界面点击“全部训练任务”即可进入项目界面: 点击新建项目,填写相关信息信息,即可创建项目。 在本次评测中我们使用物体检测。 创建项目后在新建的项目内选择创建任务,以建立一个新的任务: 按要求输入信息,数据集及验证集选择我们上一步建立的数据集youche和youchevalid。 网络方面,因为我们这次主要是对位置进行确认,对BoundingBox要求不高,所以先选用YOLO。 大家看脚本编辑框里面的内容可以发现就是采用PaddlePaddle实现模型功能的Python代码。点击脚本编辑框里面的立即编辑按钮可以对生成的脚本进行编辑,方便进行客户化的定制。 选择保存就可以将任务保存。 2.5. 训练模型 在任务界面中点击提交训练任务,就可以开始训练模型,因为我们这次准备的数据不多,所以有一个提示,点击继续训练就好: 运行开始后可以看到本任务的状态为运行中: 可以点击日志,查看运行情况: 训练时间与数据量大小有关,1000张图片可能需要几个小时训练,不过本评测案例因为只有不到40张图,所以速度很快。运行成功有界面如图: 2.6. 校验模型效果 可通过模型评估报告或模型校验了解模型效果: 选择一张测试图: 感觉效果还可以,虽然BoundingBox有点偏差,不过主要是因为训练集太小以及采用了追求速度的YOLO算法。如果增加训练集以及采用FastRCNN会有不小的提升。 还可以选择“模型效果”查看模型信息: 2.7. 模型部署 为了应用模型,需要对模型进行部署,点击“部署”按钮进入部署界面: 本次选择公有云部署,录入相关的信息,发布模型生成在线API: 发布后的服务,可以在“我的服务”中进行查看,修改: 2.8. 接口赋权 在正式使用之前,还需要做的一项工作为接口赋权,需要登录EasyDL控制台中创建一个应用,获得由一串数字组成的appid,然后就可以参考接口文档正式使用了 也可以直接点击服务界面的"立即使用"进入赋权界面: 3. 测试不同算法: 现在物体检测支持 FasterRCNN、YoloV3、mobilenetSSD,三种算法。我们在第2章使用的是YoloV3,在本章我们将对其他两种算法建立不同版本的服务,并互相进行对比。 3.1. 算法简介: 目标检测可以理解为是物体识别和物体定位的综合,不仅仅要识别出物体属于哪个分类,更重要的是得到物体在图片中的具体位置。因为具体算法内容很长,在这里只能进行一个简单的说明。 为了完成这两个任务,目标检测模型分为两类。一类是two-stage,将物体识别和物体定位分为两个步骤,分别完成,这一类的典型代表是R-CNN, fast R-CNN, faster-RCNN家族。他们识别错误率低,漏识别率也较低,但速度较慢,不能满足实时检测场景。为了解决这一问题,另一类方式出现了,称为one-stage, 典型代表是Yolo, YoloV2, YoloV3等。他们识别速度很快,可以达到实时性要求,而且准确率也基本能达到faster R-CNN的水平。 Faster R-CNN准确率mAP较高,漏检率recall较低,但速度较慢。而yolo则相反,速度快,但准确率和漏检率不尽人意。SSD综合了他们的优缺点。它的贡献在于它利用了多层网络特征,而不仅仅是FC7。 3.2. V2版(Fast RCNN): 在任务界面选择新建任务: 具体操作参考第2章的内容即可,区别在于网络选择Faster_R-CNN-ResNet50-FPN。训练后的模型效果如下所示: 可以发现在评测集上,FasterRCNN算法的效果很好,让我们验证一下具体的效果。选择与V1版一样的图片进行验证,效果如下: 可以看到,效果的确比YOLOV3的效果要好一些,圈取的内容更加准确。 3.3. V3版(SSD): 具体操作参考第2章的内容即可,区别在于网络选择SSD。训练后的模型效果如下所示: 选择与V1版一样的图片进行验证,效果如下: 4. 应用评测及结论 4.1. 评测代码 按照服务API的说明,针对V1版(YOLOV3)的服务,编写调用代码(Python3)。需要注意的是与其他图像识别服务不同的是定制化图像识别服务以json方式请求。 Body请求示例: { “image”: “” } 具体代码如下: import urllib import base64 import json import time import urllib3 #获取token def get_token(): host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + client_id + '&client_secret=' + client_secret request = urllib.request.Request(host) request.add_header('Content-Type', 'application/json; charset=UTF-8') response = urllib.request.urlopen(request) token_content = response.read() #print (token_content) if token_content: token_info = json.loads(token_content) token_key = token_info['access_token'] return token_key #保存图片 def save_base_image(img_str,filename): img_data = base64.b64decode(img_str) with open(filename, 'wb') as f: f.write(img_data) #画识别结果 def draw_result(originfilename,results,resultfilename,fontsize): from PIL import Image, ImageDraw,ImageFont image_origin = Image.open(originfilename) draw =ImageDraw.Draw(image_origin) setFont = ImageFont.truetype('C:/windows/fonts/simhei.ttf', fontsize) for result in results: location=result['location'] draw.rectangle((location['left'],location['top'],location['left']+location['width'],location['top']+location['height']),outline = "red") draw.text((location['left'],location['top']), result['name']+', Score:'+str(round(result['score'],3)),"blue",font=setFont) image_origin.save(resultfilename, "JPEG") def specialcar(filename,resultfilename,fontsize): url = "https://aip.baidubce.com/rpc/2.0/ai_custom_pro/v1/detection/specialcar" # 二进制方式打开图片文件 f = open(filename, 'rb') img = base64.b64encode(f.read()) access_token = get_token() url=url+'?access_token='+access_token begin = time.perf_counter() #img参数进行一下str转换 params={'image':''+str(img,'utf-8')+''} #对参数params数据进行json处理 encoded_data = json.dumps(params).encode('utf-8') request=urllib3.PoolManager().request('POST', url, body=encoded_data, headers={'Content-Type':'application/json'}) #对返回的byte字节进行处理。Python3输出位串,而不是可读的字符串,需要进行转换 content = str(request.data,'utf-8') end = time.perf_counter() print('处理时长:'+'%.2f'%(end-begin)+'秒') if content: #print(content) data = json.loads(content) #print(data) results=data['results'] print(results) draw_result(filename,results,resultfilename,fontsize) 4.2 测试结果: 首先是消防车及识别结果:: 邮车及识别结果: 速度非常快,效果也很不错,虽然BoundingBox有点偏差,不过主要是因为训练集太小以及采用了追求速度的YOLO算法。如果增加训练集以及采用FasterRCNN会有不小的提升。 4.3. 评测结论 EasyDL专业版定会是深度学习开发者非常喜欢的一个功能,它将EasyDL图形开发的易用性及编程的灵活性结合在一起。在提供了很多便利的同时,又将控制权交给了客户,让客户可以更加灵活的使用深度学习技术,激发无限可能,感觉非常棒。后续我准备增加训练集再试一下,看看能提高多少,然后再尝试一下离线部署成Docker的效果,建议大家都试一下。 4.4. 评测后的优化建议: 希望百度后续能增加更多的模型,比如Mask RCNN等; 希望能支持不规则形状的BoundingBox。 希望后续增加数据导入导出功能。 — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 近期《百度大脑EasyDL深度实战营》专业版课程从3月4日至25日,每周三/四 晚8点在线直播,感兴趣的同学可以加入专业版QQ群:868826008进行学习讨论。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册