关于ruby:前端学-Ruby唐诗项目部署优化

前言本篇文章和 Ruby 关系不大,只是波及到部署问题 前文花了不少工夫从零到部署唐诗我的项目,过后因为篇幅问题留下了不少的坑 例如能够采纳 docker-compose 来代替两个容器相互拜访、应用 shell 命令在本地部署,本文并未对其进行革新,因为传统部署 Ruby on Rails 的弊病很显著,须要运维教训。为疾速部署 Rails 援用,笔者寻找到了 fly.io。本文将在唐诗我的项目根底上将其部署到 fly.io 上 回顾唐诗 API随机呈现一首诗:/poetry/random用诗的题目查问:/poetry/title/静夜思列出这个诗人的所有诗:/poetry/author/李白列出这个诗人的这首诗:/poetry/author/张若虚/title/春江花月夜如何启动先将我的项目中的 tangpoetry.sql 导入到 postgresql 数据库。能够应用 pgAdmin 也能够应用命令行 psql 导入数据 再 rails s 启动我的项目 查看本地启动没问题后,开始部署我的项目 部署我的项目官网 Rails 部署教程 曾经写的很分明了,能够依照下面的做一遍练练手 这里咱们依照亲自体验 Fly.io 来手把手体验 Fly.io 装置 flyctl装置形式能够参考官网文档:https://fly.io/docs/hands-on/install-flyctl/ 因为笔者是 window,可运行以下命令装置 pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"# 或者powershell -Command "iwr https://fly.io/install.ps1 -useb | iex"如果执行 flyctl version 不报错,就阐明装置胜利了 flyctl version# flyctl.exe v0.1.32 windows/amd64 注册 fly.io如果这是您第一次应用 Fly.io,则须要注册一个帐户 ...

June 16, 2023 · 2 min · jiezi

关于ruby:Java对象的序列化和反序列化

Java 对象的序列化和反序列化是一种将对象转换成字节流并存储在硬盘或网络中,以及从字节流中从新加载对象的操作。Java 的序列化和反序列化提供了一种不便的形式,使得能够将对象在不同的应用程序之间进行交互。 一、什么是 Java 序列化和反序列化?Java 对象的序列化是将 Java 对象转换成字节流的过程,可用于长久化数据,传输数据等。序列化是将 Java 对象的状态示意为字节序列的过程,能够通过网络传送,存储到文件中或者应用其余的长久化技术,如数据库等。序列化后的字节流能够被传输给近程零碎,并在那里从新结构成原始对象。Java 序列化是一个将对象转化为字节流的过程。Java 对象的反序列化是将字节流从新复原为原始对象的过程。反序列化是将字节流转化为对象的过程。反序列化是对象序列化的逆过程,通过反序列化操作可能在接收端复原出与发送端雷同的对象。当咱们须要对存储的对象进行读取操作时,就须要对序列化的字节流进行反序列化操作,将字节流转化为原始的对象信息。二、序列化和反序列化的实现形式Java 中的序列化和反序列化能够通过实现 Serializable 接口来实现。Serializable 是一种标记接口,它没有办法定义,但它具备一个特地的作用,就是用于在形容 java 类可序列化时做类型判断的信息。当一个类实现 Serializable 接口时,表明这个类是可序列化的。Serializable 接口只是一个标识接口,咱们并不需要重载任何办法。在实现 Serializable 接口后,就能够通过 ObjectOutputStream 来将对象序列化,并将序列化后的字节流输入到文件或网络中;同时,也能够通过 ObjectInputStream 来将序列化后的字节流反序列化成对象。java.io.ObjectOutputStream 继承自 OutputStream 类,因而能够将序列化后的字节序列写入到文件、网络等输入流中。来看 ObjectOutputStream 的构造方法: ObjectOutputStream(OutputStream out)一个对象要想序列化,必须满足两个条件: 该类必须实现java.io.Serializable 接口open in new window,否则会抛出NotSerializableException 。该类的所有字段都必须是可序列化的。如果一个字段不须要序列化,则须要应用transient 关键字open in new window进行润饰。该构造方法接管一个 OutputStream 对象作为参数,用于将序列化后的字节序列输入到指定的输入流中。 示例代码如下:import java.io.*; public class SerializationDemo { public static void main(String[] args) { // 序列化对象 Person person = new Person("Tom", 20); try { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("person.txt")); objectOutputStream.writeObject(person); objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } // 反序列化对象 try { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("person.txt")); Person restoredPerson = (Person) objectInputStream.readObject(); System.out.println(restoredPerson); objectInputStream.close(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }}} ...

April 18, 2023 · 2 min · jiezi

关于ruby:国产化我们在信创下的改变

信创是什么信创是一个统称概念,理论是把现有与信息技术相干的行业联合在一起,命名为“信息技术利用翻新产业”,简称“信创”。信创包含:根底硬件、根底软件、应用软件、信息安全四大板块。其中,根底硬件次要包含:芯片、服务器/PC、存储等;根底软件包含:数据库、操作系统、中间件等。应用软件包含:办公软件、ERP 和其它软件等;信息安全包含硬件安全、软件平安、平安服务等各类产品。 为什么这两年这么火在近几年,因为种种原因。”信创“、”国产化“、”数字化“、”自主可控“ 等名词曾经高频呈现在各种国央企的我的项目中,根本是跑不掉的一个货色。大抵的推动节奏如下图: 在 2022 年又进一步减速了,代表作是传闻中的 ”79 号文件“,要求: 明确国央企在 2027 年前必须实现国产化替换,而且提出了替换品种和推动时间表。明确替换工作分为三类推动: 全面替换:央企信创 OA、门户、邮箱、纪检、党建、档案管理等。应替就替:战略决策、ERP、风控治理、CRM 经营管理系统等。能替就替:生产制作、研发零碎等。 有风闻这个信创工作将是考核指标之一。不过比拟难讲究,但大趋势的确是往这块在走,根本都在执行和询问。常见细项零碎架构常见以下几种混合选项: 前后端拆散。BFF 架构。微服务架构(SpringCloud)。云原生部署。 编程语言广泛要求应用 Java 语言,应用 SpringCloud 框架集(生态)。有局部会要求应用 JDK8,或是没有明说。JDK 的版本上,有时候也是比拟魔幻的。像客户可能明面上没有间接要求版本,但可能提供的 JDK 版本就是 1.7 或者 1.8 的。这种时候,如果你能够适配,倒还好,不能的话,比较简单的就是要求降版本。数据库广泛要求适配国产化数据库,次要抉择适配达梦数据库、人大金仓等。常见的 MySQL 当初也还能用,很像有则加冕,无则还是连忙适配一下,能加分的感觉。 云厂商和操作系统冀望部署或适配 “华为云”,信创云的底下有的是华为云作为基建搭建的。操作系统经常会和云厂商的部署绑定在一起,总体来解决是华为云部署的统信生态居多,其余某某云并不占大劣势。在 OS 上,很多也会冀望适配欧拉(openEuler)操作系统。CPU 上,也经常与之相绑定,鲲鹏,ARM64 居多。鸿蒙也略有耳闻。通过 36kr 的分享的数据,能够看到华为云这块的劣势: 2C 和 2B 的市场状况截然相同。一些企业的懊恼如果你是非定制化起家时,就会遇到比拟大的懊恼。因为你本来就有一套成熟的技术体系、架构以及生态圈。对应着也有着与之匹配的员工的能力模型建设。但此往往和对方要的信创类诉求,多少有些不匹配。如果你强硬匹配,会呈现不少的综合老本流水。可能会呈现隐性老本大于账目支出的状况。按当初业内常见的模式,根本是非定制化(SaaS)和定制化(大客户)的会离开两个团队,两套模型。若有能用的话,再看适当抽离一些逻辑过去复用。两者如果长期迭代和保护,最终还是会是越来越远。毕竟人家原本就是大客户的定制版。总结明天给大家分享了热火朝天的信创市场、企业的个别思考状况,心愿可能给大家在做技术和方向选型时提供一些帮忙。这篇文章次要做了整体的穿针引线,没有特地的深刻关上。如果对信创有更多实际和教训分享的小伙伴。也欢送一起交换和学习!

April 4, 2023 · 1 min · jiezi

关于ruby:微服务中的鉴权该怎么做

认证与受权首先小伙伴们晓得,无论咱们学习 Shiro 还是 Spring Security,里边的性能无论有哪些,外围都是两个:认证受权 所以,咱们在微服务中解决鉴权问题,也能够从这两个方面来思考。1.1 认证认证,说白了就是登录。传统的 Web 登录是 Cookie+Session 的计划,这种计划依赖于服务器本地内存,在微服务中,因为服务泛滥,这种计划显然不再适合。 可能会有小伙伴说用 Redis+SpringSession 做 Session 共享,这是个方法,然而不是最佳计划,因为这种计划的性能以及可扩展性都比拟差。 所以,微服务中的认证,还是倡议应用令牌的形式,能够抉择 JWT 令牌,这也是目前应用较多的一种计划。然而相熟 JWT 的小伙伴都晓得,纯正的无状态登录无奈实现登记,这就很头大,所以在理论利用中,单纯的应用 JWT 是不行的,个别还是要联合 Redis 一起,将生成的 JWT 字符串在 Redis 上也保留一份,并设置过期工夫,判断用户是否登录时,须要先去 Redis 上查看 JWT 字符串是否存在,存在的话再对 JWT 字符串做解析操作,如果能胜利解析,就没问题,如果不能胜利解析,就阐明令牌不非法。这样有状态登录+无状态登录混在一起的形式,尽管看起来有点不三不四,然而就当下来说,这个折衷的方法算是一个可行的计划了。 其实,下面的计划,说白了,跟传统的 Cookie+Session 没什么两样,思路简直都是齐全 copy 的:传统的 Session 用 Redis 代替了;传统穿梭于服务端和浏览器之间的 jsessionId 被 JWT 字符串代替了;传统的 jsessionId 通过 Cookie 来传输,当初的 JWT 则通过开发者手动设置后通过申请头来传输;传统的 Session 能够主动续签,当初用 JWT 就是手动续签,每次申请达到服务端的时候,就去看下 Redis 上令牌的过期工夫,快过期了,就从新设置一下,其余都截然不同。 这是认证计划的抉择。1.2 受权微服务中受权,也能够应用 Shiro 或者 Spring Security 框架来做,省事一些。思考到微服务技术栈都是 Spring 家族的产品,所以在权限框架这块也是倡议大家首选 Spring Security(如果有小伙伴对 Spring Security 还不相熟的话,能够在微信公众号后盾回复 ss,有教程)。当然,如果感觉 Spring Security 比较复杂想本人搞的话,也是能够的。本人搞的话,也是能够借助于 Spring Security 的思路的,松哥最近的一个我的项目就是这样: ...

April 4, 2023 · 1 min · jiezi

关于ruby:浅尝高并发编程接私活差点翻车

前言作为一名本本分分的练习时长两年半的Java练习生,始终深耕在业务逻辑里,对并发编程的理解仅仅停留在八股文里。一次偶尔的机会,接到一个私活,外围逻辑是写一个 定时拜访api把数据长久化到数据库的小服务。 期间遇到了很多坑还挺有意思,做进去很简略,做得好还是挺难的,这里跟大家分享一下。maven引入内部jar包部署我的项目背景是某家厂商要对接第三方领取公司的open api拿到每日商品销售量与销售额,第三方领取公司就是哗啦啦,这里吐槽下哗啦啦做的凋谢文档写的是真捞。。。首先要把哗啦啦这边提供的jar包引入到咱们的服务里,本地开发间接引入即可能够用maven的一条命令间接把本地的jar包打到本地仓库里。mvn install:install-file -DgroupId=com.uptown -DartifactId=xxx_sdk -Dversion=1.0-SNAPSHOT -Dpackaging=jar -Dfile=E:\uptown\uptown.jar复制代码然而这样部署服务的时候就会发现打不出jar包来,我的项目能跑,然而到要害的调用sdk的时候就报ClassNofFoundException谬误。须要在pom里配置好引入内部jar包的插件才行,这里算是一个小坑。<plugin> <groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>UTF-8</encoding> <compilerArguments> <bootclasspath>${java.home}/lib/rt.jar</bootclasspath> </compilerArguments></configuration></plugin>复制代码上线程池客户大概有150个门店,这样阻塞申请下来仅仅是申请api的耗时就将近半小时,还不算入库的工夫。 这时候依据熟读并背诵的八股文只是,要充分利用cpu的能力无脑抉择线程池,于是起了一个外围线程20个的线程池去并发申请api数据入库。部署之后发现总有这么几条谬误日志。com.*.OrderDetailMapper.updateById(batch index #2) failed. 1 prior sub executor(s) completed successfully, but will be rolled back. Cause: java.sql.BatchUpdateException: Deadlock found when trying to get lock复制代码果然背八股文救不了中国,依据报错判断出入库时死锁了。。。。追究死锁因为我在服务里用了mybatis-plus的orm框架,而且数据是一些订单数据存在一些状态变更,而后服务要同步的数据可能会有更改之前旧数据的场景,所以就用了Mybatis里的SaveOrUpdate办法,好事就好事在这下面。 这个货色还要从mysql数据库的隔离级别开始说起,家喻户晓,依照八股文里mysql隔离级别默认状况下为可反复读,那可反复读隔离机制下防止了脏读,不可反复读,日常开发里也并没有呈现过幻读,看似MVCC多版本并发管制帮咱们避开了幻读。其实不然,幻读的概念与不可反复读类似,不可反复读读到了他人update的数据,幻读读到了他人insert/delete的数据。一个事务在读取了其余事务新增的数据,好像呈现了空想。这里先简略说一下,mysql在可反复读隔离级别下会为每个事务以后读的时候加间隙锁,后续会写一篇mysql在可反复读的隔离级别下如何解决幻读文章。那怎么解决的呢,工夫紧工作重,认真一想这个数据库基本上全是往里增删改的动作,查问的动作简直没有,那为什么不把它隔离级别降级,降成读已提交,这样间隙锁就不失效了。很完满,后续也验证了这个问题,再也没呈现过数据库的死锁状况。数据库链接失落这个问题是真滴恶心,客户买的服务器拉的一批,还买windows服务器,这年头正经人谁用windows,用客户端连都常常失落链接。遇到这个问题非常辣手,那不解决数据就永远不精确。然而想根治这个问题又得失相当,甲方选windows还不就是看重了可视化界面了。这时候再让他们迁徙服务器必定不可能。于是为了解决这个就疯狂在网上搜计划,什么改my.ini的wait_out_time,什么改jdbc的url都白搭,起初我一想,算球了,不靠数据库了,原本想让这么多数据每条都一次胜利也不事实。于是搞了个error_msg表,入库的时候有问题就记在error_msg里,而后启一个定时工作,每1分钟扫描表里所有插入失败记录,一次不行两次,两次不行三次,三次不行始终试。这个重试补上之后的确数据库这方面的坑根本踩的差不多了。服务假死CPU打满这个状况是出在解决mysql链接失落前,过后我想,为什么要用多线程,是因为效率低,效率低其实是低在申请api上,也就是我能够先多线程申请到数据放到一个list里,而后用单个数据库链接去写,这样升高mysql的连接数应该就不会丢了吧。这么容易就丢那还写啥啊。后果我就一个月一个月的拉数据,写完数据清空list,于是搞了个CopyAndWriteList,白背了那么多八股文了,一次也没用过,后果就cpu给人打的满满的。。。起因其实也很简略,就是这个容器外部都用锁保障了线程平安。我就把这个容器当作参数传给每个Thread,弄完间接启动。后果吧是服务忽然就没有新增数据了,而后看日志也没不打日志,jps看服务还在。遇到这种问题先上三板斧,回到家连上服务器上来先看快照,Jstack -l pid。 Locked ownable synchronizers: - None复制代码又是死锁了,这里就不深究了。后续间接换了用LinedblockingQueue的提早队列,另起生产线程一直生产提早队列入库的计划了。线程池莫名失落链接原本认为解决了写库的问题就差不多了,没想到啊没想到,这个不丢那个丢,数据还是有很多差别,找error_msg又没体现进去,一顿排查起初发现是线程池这边的问题。这里的线程池用的Guava的线程池,重写异样捕捉 @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); //线程池中的工作挂掉,主动从新提交该工作 if (!ObjectUtils.isEmpty(t)) { System.out.println("restart fetch data..."); execute(r); }}复制代码期待队列用无界队列,客户的服务器尽管拉,然而内存挺大,订单数撑不爆内存,外围线程10个,感觉一切都是那么正当。然而就是有问题,我发现在afterExecute办法拦挡挂掉的工作异样时发现有很多工作的异样是java.util.concurrent.RejectedExecutionException也就是被执行了回绝策略。这就非常不合理了,只有当队列满了且正在运行的线程数量大于或等于maximumPoolSize,那么线程池才会启动饱和回绝策略。那我定义线程池的时候明明是无界队列,来者不拒。为啥会被执行回绝策略。这个问题困扰了老久老久,以致于我都不想管了,奈何客户始终催始终催,逼得我不得不解决这问题。起初在Stack Overflow上有个老哥在源码中找到起因 public void execute(Runnable command) { ...

April 4, 2023 · 1 min · jiezi

关于ruby:传参base64时的号变空格问题

问题产生上上周,看到一位老哥找咱们组共事联调接口,不晓得是什么问题,两人坐一起搞了快1个小时,看起来如同有点简单。忽然,老哥收回一声卧槽,"我传参里的+号,到你这怎么变成了空格!",这个声音很大,我显著的听到了,很快,我就大略Get到了他们的问题点。我猜想他们遇到的问题大略如下: 咱们的接口协议上,都会将申请数据做一次base64编码,而后放到data参数上。而后某些数据做base64编码后有+,如{"notes":"代码"}base64编码为eyJub3RlcyI6IuS7o+eggSJ9Cg==。而后间接拼到data参数上,即data=eyJub3RlcyI6IuS7o+eggSJ9Cg==,组织成http申请收回。 如果写成等价的curl,就是这样:$ curl http://localhost:8080/send -d 'data=eyJub3RlcyI6IuS7o+eggSJ9Cg=='复制代码写个测试接口调试下看看,如下: 这就是他们遇到的问题,+会变成空格,这个坑其实蛮容易踩到,我本人刚工作时就踩到过这个坑,也屡次看到或听到他人同踩此坑问题起因这个问题和urlencode编码无关,urlencode编码,一般来说,除字母、数字和*,.,-和_这些字节原样输入外,其它字节都会编码为%XX(16进制)的模式。 但有一个特例,如下:String enc = URLEncoder.encode(" ", "UTF-8");System.out.println(enc); // 输入+号 String dec = URLDecoder.decode("+", "UTF-8");System.out.println(dec); // 输入空格复制代码特例就是空格会被编码为+号,反之,+号会被解码为空格! 注:在新的RFC 2396标准中,空格其实也能够编码成%20,而解码时,+号与%20都会被解码为空格。 回忆下面的场景,如果将带有+号的base64字符串,一成不变的封装到data=中,再发送给Tomcat等Web服务器,若Tomcat侧做一次urldecode解码,+是不是就变成空格了而Tomcat的确会做urldecode解码这样的操作,当调用方的Content-Type为application/x-www-form-urlencoded时,这里晓得有这种操作即可,想理解细节可看看我写的这篇文章 由x-www-form-urlencoded引发的接口对接失败解决问题解决这种问题,次要有两种办法,如下: 调用方对参数做urlencode编码。 按标准来看,当Content-Type为application/x-www-form-urlencoded时,调用方是必须对参数名与参数值做urlencode的,java实现如下:String base64Str = Base64.getEncoder().encodeToString(data);String requestStr = "data=" + URLEncoder.encode(base64Str, "UTF-8");复制代码这里做了urlencode后,+会被编码为%2B,再由服务端解码,就会变成原样的+号。 注:如果是应用apache的HttpClient,可思考应用UrlEncodedFormEntity,它会主动做这个事件。 应用urlsafe版本的base64。 一般的base64不能间接作为参数值,因为它可能蕴含+、/这两个url不平安的字符,所以base64有个变种叫urlBase64,它将+、/替换成了url平安的-、_,java实现如下:String urlBase64Str = Base64.getUrlEncoder().encodeToString(data);String requestStr = "data=" + urlBase64Str;

March 28, 2023 · 1 min · jiezi

关于ruby:Vue3-巧用自定义全局属性封装只为高效率

简介要想缩小重复性代码,少不了全局属性配置的问题,做这方面的模块封装。当然就是为了少敲点代码,以及为了后续需要变更的时候,咱们只须要批改一处中央,而不须要在用到这个模块的页面都要改变一遍,这难道不是内耗,和浪费时间吗。出于这个目标,再次深研了扩大全局属性扩大全局属性某些插件会通过 app.config.globalProperties 为所有组件都装置全局可用的属性。举例来说,import axios from 'axios' declare module 'vue' { interface ComponentCustomProperties { $http: typeof axios $translate: (key: string) => string} }复制代码咱们可能为了申请数据而装置了 this.$http,或者为了国际化而装置了 this.$translate。为了使 TypeScript 更好地反对这个行为,Vue 裸露了一个被设计为能够通过 TypeScript 模块扩大来扩大的 ComponentCustomProperties 接口:类型扩大的地位咱们能够将这些类型扩大放在一个 .ts 文件,或是一个影响整个我的项目的 *.d.ts 文件中。无论哪一种,都应确保在 tsconfig.json 中包含了此文件。对于库或插件作者,这个文件应该在 package.json 的 types 属性中被列出。留神:这里的官网介绍,是为后续工具类或者组件封装做后期思路的筹备为了利用模块扩大的劣势,咱们须要确保将扩大的模块放在 TypeScript 模块 中。 也就是说,该文件须要蕴含至多一个顶级的 import 或 export,即便它只是 export {}。如果扩大被放在模块之外,它将笼罩原始类型,而不是扩大!自定义组件封装Vue3过滤器制作对于 Vue2 中的过滤器,过滤器能够艰深了解成是一个非凡的办法,用来加工数据的。而在 vue3 中,曾经去掉了 filters 这个属性,然而咱们的需要还是在的。而官网给的倡议是能够通过写composition办法,来代替;然而这样子的话,每次须要应用到相似过滤器的这个办法,都要进行导入,还是比拟麻烦;索性在全局配置中,附加进去,如下:在 main.js 中加上 //vue3配置全局过滤器app.config.globalProperties.$filters = { //formatTime过滤器的名称 isPeriodEmpty(value: string) { // 实现一个字段为空返回--的过滤器 return value || '--'},};复制代码在组件中应用如下<template #operation="scope"> {{ $filters.isPeriodEmpty(scope.row.abc) }} </template>复制代码然而这样做的话,ts语法会提醒谬误 为了解决这个问题,咱们这里利用到了上文简介中我所提到的扩大全局属性 ComponentCustomProperties 从上文简介类型扩大的地位,tsconfig.json中 "include": ["/.ts", "src//.d.ts", "src/types/**/*.d.ts", "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],复制代码蕴含的任意地位,增加vue.d.ts文件,并写入// 扩大全局属性类型declare module 'vue' { ...

March 22, 2023 · 1 min · jiezi

关于ruby:在Vue3这样子写页面更快更高效

前言在开发治理后盾过程中,肯定会遇到不少了增删改查页面,而这些页面的逻辑大多都是雷同的,如获取列表数据,分页,筛选性能这些基本功能。而不同的是出现进去的数据项。还有一些操作按钮。 对于刚开始只有 1,2 个页面的时候大多数开发者可能会间接将之前的页面代码再拷贝多一份进去,而随着我的项目的推动相似页面数量可能会越来越多,这间接导致我的项目代码耦合度越来越高。这也是为什么在我的项目中一些可复用的函数或组件要抽离进去的次要起因之一上面,咱们封装一个通用的useList,适配大多数增删改查的列表页面,让你更快更高效的实现工作,准点上班 ~ 前置常识 VueVue Composition Api 封装咱们须要将一些通用的参数和函数抽离进去,封装成一个通用hook,后续在其余页面复用雷同性能更加简略不便。定义列表页面必不可少的分页数据export default function useList() { // 加载态 const loading = ref(false); // 当前页 const curPage = ref(1); // 总数量 const total = ref(0); // 分页大小 const pageSize = ref(10);}复制代码如何获取列表数据思考一番,让useList函数接管一个listRequestFn参数,用于申请列表中的数据。定义一个list变量,用于寄存网络申请回来的数据内容,因为在外部无奈间接确定列表数据类型,通过泛型的形式让内部提供列表数据类型。export default function useList<ItemType extends Object>( listRequestFn: Function) { // 疏忽其余代码 const list = ref<ItemType[]>([]);}复制代码在useList中创立一个loadData函数,用于调用获取数据函数,该函数接管一个参数用于获取指定页数的数据(可选,默认为curPage的值)。 执行流程 设置加载状态调用内部传入的函数,将获取到的数据赋值到list和total中敞开加载态 这里应用了 async/await 语法,假如申请出错、解构出错状况会走 catch 代码块,再敞开加载态 这里须要留神,传入的 listRequestFn 函数接管的参数数量和类型是否失常对应上请依据理论状况进行调整 export default function useList<ItemType extends Object>( listRequestFn: Function) { // 疏忽其余代码 // 数据 const list = ref<ItemType[]>([]); // 过滤数据 // 获取列表数据 const loadData = async (page = curPage.value) => { ...

March 22, 2023 · 4 min · jiezi

关于ruby:MongoDB为什么比Mysql高效

在当今互联网时代,数据是价值连城。为了更高效地存储和治理数据,数据库成为了重要的组成部分。MySQL和MongoDB都是罕用的数据库,但MongoDB比MySQL更为高效,这是为什么呢?数据存储形式不同MysqlMySQL是一种关系型数据库管理系统(RDBMS),它应用传统的表格形式来存储数据。具体来说,MySQL中的数据是以表格(也称为关系)的模式组织的,每个表格蕴含若干列和行。列示意数据的属性,行示意具体的数据记录。在MySQL中,表格中的每一列都必须有一个数据类型来定义其数据格式。MySQL反对的数据类型包含整型、浮点型、字符型、日期型等等。此外,MySQL还反对定义主键、外键、索引等数据束缚,以保证数据的完整性和一致性。MySQL中的数据以文件的模式存储在磁盘上,每个数据库对应一个或多个物理文件。其中,一个非凡的文件称为“数据字典”,它存储了数据库中所有表格、列、索引、束缚等信息。在查问和批改数据时,MySQL会首先从数据字典中读取表格构造信息,而后再依据表格构造和索引信息定位具体的数据记录。总的来说,MySQL的数据存储形式是传统的关系型数据库形式,实用于结构化数据的存储和查问。MySQL也反对一些非关系型数据的存储形式,比方BLOB和TEXT类型的数据,但相比于MongoDB等面向文档的数据库,MySQL的非结构化数据处理能力绝对较弱。MongoDBMongoDB是一种面向文档的数据库管理系统,它应用文档的形式来存储数据。具体来说,MongoDB中的数据是以BSON(Binary JSON)文档的模式组织的,每个文档都是一个键值对的汇合,能够蕴含任何类型的数据。在MongoDB中,数据存储在汇合(Collection)中,每个汇合蕴含若干文档。汇合的构造非常灵活,同一个汇合中的文档能够有不同的构造,每个文档能够有本人的字段和值。这种构造非常适合存储非结构化数据,比方日志、社交媒体数据等等。MongoDB中的数据以文件的模式存储在磁盘上,每个数据库对应一个或多个物理文件。在MongoDB中,数据的读写操作都是基于内存的,MongoDB会将频繁拜访的数据缓存在内存中,以进步查问和更新的速度。MongoDB还反对正本集和分片机制,能够轻松地实现数据的程度扩大和负载平衡。在正本集中,每个节点都是一个残缺的MongoDB实例,其中一个节点被指定为主节点,其余节点作为从节点。主节点负责接管所有的写操作和查问操作,从节点负责复制主节点的数据,并提供读操作。在分片机制中,MongoDB会将数据依照特定的规定分成多个分片,每个分片存储一部分数据,以实现程度扩大。总的来说,MongoDB的数据存储形式是面向文档的,非常适合存储非结构化数据。MongoDB还反对分布式部署和扩大,能够解决大规模的数据和高并发拜访。索引机制不同MysqlMySQL索引是一种数据结构,它可能放慢数据检索的速度。MySQL反对多种类型的索引,包含B-tree索引、哈希索引、全文索引等等。其中,B-tree索引是最罕用的索引类型。B-tree索引是一种均衡树结构,它将索引值依照肯定的程序组织成一个树形构造,每个节点蕴含若干索引值和指向子节点的指针。在B-tree索引中,查问操作会从根节点开始,依据索引值的大小关系顺次遍历子节点,直到找到指标节点或者达到叶子节点。这种构造能够十分疾速地定位到指标数据记录,因为树的高度通常很小,而且每个节点都能够包容很多索引值。MySQL中的B-tree索引反对单列索引和组合索引。单列索引只蕴含一个列的值,而组合索引则蕴含多个列的值,多个列的值组合在一起作为索引值。组合索引能够更加准确地定位数据记录,但它的创立和保护老本也更高。MySQL还反对笼罩索引,即查问所需的数据都能够从索引中获取,不须要再拜访数据表。笼罩索引能够大大减少查问的磁盘访问量,进步查问的性能。总的来说,MySQL的索引机制能够放慢数据检索的速度,缩小磁盘访问量,进步数据库的性能。不过,索引也有一些毛病,比方减少了数据的存储空间、升高了写入性能等等。因而,在应用索引时须要依据具体的状况进行衡量和抉择。MongoDBMongoDB的索引机制是一种基于B-tree的索引实现,相似于MySQL的B-tree索引。MongoDB反对单字段、多字段、复合、文本、地理位置等多种类型的索引。在MongoDB中,创立索引能够应用createIndex()办法,能够指定索引类型、索引字段、索引方向等参数。例如,上面的代码创立一个名为“username”的单字段索引:db.collection.createIndex({username: 1})复制代码MongoDB的索引机制能够大大提高数据的查问性能,因为它可能在索引中疾速定位数据记录,而不须要扫描整个数据汇合。如果一个查问蕴含多个条件,能够应用复合索引来进步查问性能。例如,上面的代码创立一个蕴含“username”和“email”的复合索引:db.collection.createIndex({username: 1, email: 1})复制代码在应用MongoDB的索引时须要留神以下几点: 创立过多的索引会占用大量的存储空间,影响性能,因而须要依据理论需要进行抉择。索引会减少写入操作的开销,因为每次写入操作都须要更新索引。如果写入操作频繁,能够思考应用稠密索引或者禁用索引。索引的抉择和设计要依据具体的查问需要进行优化,避免出现有效的或者低效的索引。 总的来说,MongoDB的索引机制能够进步数据的查问性能,但须要依据具体情况进行抉择和优化。分布式架构不同MysqlMySQL是一个传统的关系型数据库,最后设计并没有思考分布式架构。然而,随着数据量和访问量的一直增长,单机MySQL曾经无奈满足高可用、高性能的要求,因而呈现了分布式MySQL架构。分布式MySQL架构通常采纳主从复制和分片技术。主从复制是指将数据从主数据库复制到多个从数据库,从数据库能够解决读申请和备份数据。主数据库负责解决写申请,从数据库负责读申请。分片技术是指将数据依照肯定的规定划分为多个片(或者分区),每个片存储在不同的数据库节点上,通过路由技术来决定哪个节点解决特定的申请。分布式MySQL架构的长处是能够进步数据处理能力、升高单点故障危险、加强零碎的可扩展性和可靠性。不过,分布式MySQL架构也有一些毛病,例如: 零碎的复杂度减少,须要额定的保护和管理工作。数据的一致性和可靠性可能会受到影响,须要采纳适合的复制和同步机制来保证数据的一致性。分片机制可能会导致一些跨片的操作成为瓶颈,须要采纳适合的路由算法和负载平衡策略。分布式MySQL架构须要更高的硬件老本和网络带宽。 总的来说,分布式MySQL架构须要依据具体的业务需要和数据规模来进行设计和优化,须要综合思考性能、可靠性、一致性、复杂度等多个方面。MongoDBMongoDB是一种分布式文档型数据库,具备天生的分布式架构设计。MongoDB的分布式架构蕴含多个组件,包含分片、正本集和分布式查问路由。 分片 MongoDB的分片技术将数据宰割成多个分片(shard),每个分片存储局部数据,多个分片组成一个分片集群。分片能够依照数据的范畴、哈希值、分片键等形式进行调配。在分片集群中,有一个特定的MongoDB节点充当分片协调器(mongos),负责接管客户端的申请,将申请路由到对应的分片节点上,并将后果返回给客户端。 正本集 为了进步数据的可靠性和可用性,MongoDB采纳正本集(replica set)技术。正本集包含一个主节点和多个从节点,主节点负责解决写申请和同步数据到从节点,从节点负责解决读申请和备份数据。如果主节点生效,从节点能够选举一个新的主节点,保证系统的高可用性。 分布式查问路由 MongoDB的分布式查问路由机制将查问申请路由到适合的分片节点上。当客户端向mongos发送查问申请时,mongos会将申请转发给对应的分片节点,如果申请波及多个分片,mongos会主动将后果聚合返回给客户端。为了进步查问性能,MongoDB反对在每个分片上执行局部查问,而后将后果返回给mongos,在mongos上再进行聚合。总的来说,MongoDB的分布式架构设计能够进步数据的解决能力、可靠性和可用性,同时也减少了零碎的复杂度和治理难度。须要依据具体的业务需要和数据规模来进行分片、正本集和查问路由的配置和优化。总结 MysqlMongodb数据存储形式MySQL采纳的是传统的关系型数据库,数据以表格的模式存储,每个表都有固定的列和行。这种构造使得MySQL在解决结构化数据时表现出色,然而在解决非结构化数据时体现不佳。MongoDB则是面向文档的数据库,它应用文档的形式存储数据,文档中能够蕴含任何类型的数据,而且不须要当时定义其构造。这种形式使得MongoDB在存储和查问非结构化数据时更加高效。索引机制索引是进步数据库查问效率的重要伎俩,MySQL和MongoDB的索引机制也不同。MySQL采纳B+树索引,这种索引实用于结构化数据,但对非结构化数据的查问效率较低。MongoDB采纳的是BSON索引,BSON是一品种JSON的二进制编码格局,它反对对文档中的任何字段进行索引,查问速度十分快。此外,MongoDB还反对天文空间索引和全文索引等高级索引形式,使得非结构化数据的查问更加高效。分布式架构MySQL在分布式环境下须要进行数据分片,这会带来许多治理和保护的问题。MongoDB天生就是分布式的,它采纳的是正本集和分片机制,能够轻松地实现数据的程度扩大和负载平衡。MongoDB还具备主动故障转移和主动复原等性能,当节点产生故障时会主动将其替换为备用节点,保证系统的高可用性和数据的安全性。综上所述,MongoDB比MySQL更适宜存储和查问非结构化数据,具备更高的查问效率和更好的分布式扩展性。当然,在理论应用中,抉择哪种数据库要依据具体的业务需要和数据特点来确定。

March 7, 2023 · 1 min · jiezi

关于ruby:JDK17会代替JDK8吗

俗话说:“它发认它发,我用Java8”。然而随着Spring 6.0以及SpringBoot 3.0的公布,JDK17仿佛大有取代JDK8的趋势了。 Spring Boot 3.0 requires Java 17 as a minimum version. If you are currently using Java 8 or Java 11, you'll need to upgrade your JDK before you can develop Spring Boot 3.0 applications. Spring 6.0&SpringBoot 3.0对AOT的反对,能极大进步利用的启动速度,从而能够补救Java在云原生、Serverless等畛域的缺点,据我所知,某驰名大厂外部曾经在进行降级了。另外,JDK17是一个LTS(长期反对版),能够收费商用到2029年,JDK17自身在性能上也有优化,比方对于NIO的性能优化,至多晋升了10%。随着各大框架对JDK17的反对,JDK17取代JDK8只是工夫问题。这里我大抵列以下JDK9-JDK17中几个要害的新个性: sealed 密封类文本块record 纪录类G1成为默认垃圾收集器ZGC的欠缺与降级JDK模块化JFR飞行器新swich表达式虚构线程... 比方SpringBoot3.0的源码中就用到了新个性: 尽管JDK17跟JDK8相比拟的确减少了很多新个性,不论是语法上、性能上,都在踊跃的汲取其余语言的特点,并且整个Java生态也在一直的降级为JDK17,然而对于公司而言,除非是新我的项目、新利用,不然是不太可能把现有我的项目降级到JDK17的。你们我的项目中,当初用的是JDK哪个版本呢?

February 27, 2023 · 1 min · jiezi

关于ruby:MyBatis获取参数值的两种方式-与

{}与${}的区别{}的实质是占位符赋值,${}的实质是字符串拼接${}应用字符串拼接的形式拼接sql,若为字符串类型或日期类型的字段进行赋值时,须要手动加单引号 {}应用占位符赋值的形式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,能够主动增加单引号如何应用${}与#{}获取参数值获取单个字面量类型的参数 此时能够应用#{}和${}以任意的名称(最好见名识意)获取参数的值,留神${}须要手动加单引号 编写mapper接口: public class UserMapper { //通过id查问用户信息User getUserById(Integer id);}复制代码 编写映射文件: <select id="getUserById" resultType="com.mybatis.pojo.User"> SELECT * FROM user WHERE `id` = #{id}</select>复制代码或<select id="getUserById" resultType="com.mybatis.pojo.User"> SELECT * FROM user WHERE id = '${id}'</select>复制代码多个字面量类型的参数 若mapper接口中的办法参数为多个时,此时MyBatis会主动将这些参数放在一个map汇合中 以arg0,arg1...为键,以参数为值;以param1,param2...为键,以参数为值; 因而只须要通过${}和#{}拜访map汇合的键就能够获取绝对应的值,留神${}须要手动加单引号。 应用arg或者param都行,要留神的是,arg是从arg0开始的,param是从param1开始的 编写mapper接口: public class UserMapper { //通过姓名和年龄查问用户信息User getUserByNameAndAge(String name, Integer age);}复制代码 编写映射文件: <select id="getUserByNameAndAge" resultType="com.mybatis.pojo.User"> SELECT * FROM user WHERE name = #{arg0} AND age = #{arg1} </select>复制代码或<!--User checkLogin(String username,String password);--><select id="getUserByNameAndAge" resultType="com.mybatis.pojo.User"> SELECT * FROM user WHERE name = '${param1}' AND age = '${param2}'</select>复制代码map汇合类型的参数 ...

February 22, 2023 · 2 min · jiezi

关于ruby:详解Redisson分布式限流的实现原理

咱们目前在工作中遇到一个性能问题,咱们有个定时工作须要解决大量的数据,为了晋升吞吐量,所以部署了很多台机器,但这个工作在运行前须要从别的服务那拉取大量的数据,随着数据量的增大,如果同时多台机器并发拉取数据,会对上游服务产生十分大的压力。之前曾经减少了单机限流,但无奈解决问题,因为这个数据工作运行中只有不到10%的工夫拉取数据,如果单机限流限度太狠,尽管集群总的申请量管制住了,但工作吞吐量又降下来。如果限流阈值太高,多机并发的时候,还是有可能压垮上游。 所以目前惟一可行的解决方案就是分布式限流。 我目前是抉择间接应用Redisson库中的RRateLimiter实现了分布式限流,对于Redission可能很多人都有所耳闻,它其实是在Redis能力上构建的开发库,除了反对Redis的根底操作外,还封装了布隆过滤器、分布式锁、限流器……等工具。明天要说的RRateLimiter及时其实现的限流器。接下来本文将具体介绍下RRateLimiter的具体应用形式、实现原理还有一些注意事项,最初简略谈谈我对分布式限流底层原理的了解。RRateLimiter应用 RRateLimiter的应用形式异样的简略,参数也不多。只有创立出RedissonClient,就能够从client中获取到RRateLimiter对象,间接看代码示例。RedissonClient redissonClient = Redisson.create();RRateLimiter rateLimiter = redissonClient.getRateLimiter("xindoo.limiter");rateLimiter.trySetRate(RateType.OVERALL, 100, 1, RateIntervalUnit.HOURS); 复制代码 rateLimiter.trySetRate就是设置限流参数,RateType有两种,OVERALL是全局限流 ,PER_CLIENT是单Client限流(能够认为就是单机限流),这里咱们只探讨全局模式。而前面三个参数的作用就是设置在多长时间窗口内(rateInterval+IntervalUnit),许可总量不超过多少(rate),下面代码中我设置的值就是1小时内总许可数不超过100个。而后调用rateLimiter的tryAcquire()或者acquire()办法即可获取许可。rateLimiter.acquire(1); // 申请1份许可,直到胜利boolean res = rateLimiter.tryAcquire(1, 5, TimeUnit.SECONDS); // 申请1份许可,如果5s内未申请到就放弃复制代码 应用起来还是很简略的嘛,以上代码中的两种形式都是同步调用,但Redisson还同样提供了异步办法acquireAsync()和tryAcquireAsync(),应用其返回的RFuture就能够异步获取许可。RRateLimiter的实现 接下来咱们顺着tryAcquire()办法来看下它的实现形式,在RedissonRateLimiter类中,咱们能够看到最底层的tryAcquireAsync()办法。 private <T> RFuture<T> tryAcquireAsync(RedisCommand<T> command, Long value) { byte[] random = new byte[8]; ThreadLocalRandom.current().nextBytes(random); return commandExecutor.evalWriteAsync(getRawName(), LongCodec.INSTANCE, command, "——————————————————————————————————————" + "这里是一大段lua代码" + "____________________________________", Arrays.asList(getRawName(), getValueName(), getClientValueName(), getPermitsName(), getClientPermitsName()), value, System.currentTimeMillis(), random);}复制代码 映入眼帘的就是一大段lua代码,其实这段Lua代码就是限流实现的外围,我把这段lua代码摘出来,并加了一些正文,咱们来具体看下。local rate = redis.call("hget", KEYS[1], "rate") # 100 local interval = redis.call("hget", KEYS[1], "interval") # 3600000local type = redis.call("hget", KEYS[1], "type") # 0assert(rate ~= false and interval ~= false and type ~= false, "RateLimiter is not initialized")local valueName = KEYS[2] # {xindoo.limiter}:value 用来存储残余许可数量local permitsName = KEYS[4] # {xindoo.limiter}:permits 记录了所有许可收回的工夫戳 ...

February 14, 2023 · 2 min · jiezi

关于ruby:我终于搞懂了asyncawaitpromise和setTimeout的执行顺序

从一道题目登程明天看到一道面试题,是对于async/await、promise和setTimeout的执行程序,题目如下:async function async1() { console.log('async1 start');await async2();console.log('asnyc1 end');}async function async2() { console.log('async2');}console.log('script start');setTimeout(() => { console.log('setTimeOut');}, 0);async1();new Promise(function (reslove) { console.log('promise1');reslove();}).then(function () { console.log('promise2');})console.log('script end');复制代码我给出的答案:script startasync1 startasync2asnyc1 end // xpromise1script endpromise2setTimeOut复制代码正确的答案:script startasync1 startasync2promise1script endasnyc1 endpromise2setTimeOut复制代码为什么promise1比asnyc1 end先进去呢?带着这个疑难,我去理解了一下事件循环机制。js EventLoop 事件循环机制JavaScript的事件分两种: 宏工作(macro-task)微工作(micro-task)scriptpromise. then/catch/finally )setTimeoutprocess.nextTick(Node.js 环境)setIntervalMutaionOberver(浏览器环境)setImmediate(Node.js 环境)Object.observeIO操作xUI交互事件xpostMessagexMessageChannelx事件的执行程序,是先执行宏工作,而后执行微工作,这个是根底,工作能够有同步工作和异步工作,同步的进入主线程,异步的进入Event Table并注册函数,异步事件实现后,会将回调函数放入Event Queue中(宏工作和微工作是不同的Event Queue),同步工作执行实现后,会从Event Queue中读取事件放入主线程执行,回调函数中可能还会蕴含不同的工作,因而会循环执行上述操作。 留神: setTimeOut并不是间接的把你的回掉函数放进上述的异步队列中去,而是在定时器的工夫到了之后,把回掉函数放到执行异步队列中去。如果此时这个队列曾经有很多工作了,那就排在他们的前面。这也就解释了为什么setTimeOut为什么不能精准的执行的问题了。setTimeOut执行须要满足两个条件: 主过程必须是闲暇的状态,如果到工夫了,主过程不闲暇也不会执行你的回调函数这个回调函数须要等到插入异步队列时后面的异步函数都执行完了,才会执行 promise、async/await首先,new Promise是同步的工作,会被放到主过程中去立刻执行。而.then()函数是异步工作会放到异步队列中去,那什么时候放到异步队列中去呢?当你的promise状态完结的时候,就会立刻放进异步队列中去了。带async关键字的函数会返回一个promise对象,如果外面没有await,执行起来等同于一般函数;如果没有await,async函数并没有很厉害是不是。await 关键字要在 async 关键字函数的外部,await 写在里面会报错;await如同他的语意,就是在期待,期待右侧的表达式实现。此时的await会让出线程,阻塞async内后续的代码,先去执行async外的代码。等里面的同步代码执行结束,才会执行外面的后续代码。就算await的不是promise对象,是一个同步函数,也会等这样操作。流程梳理咱们整体再梳理一下下面代码执行的流程: 整个代码片段(script)作为一个宏工作执行console.log('script start'),输入script start;执行setTimeout,是一个异步动作,放入宏工作异步队列中;执行async1(),输入async1 start,持续向下执行;执行async2(),输入async2,并返回了一个promise对象,await让出了线程,把返回的promise退出了微工作异步队列,所以async1()上面的代码也要期待下面实现后继续执行;执行 new Promise,输入promise1,而后将resolve()放入微工作异步队列;执行console.log('script end'),输入script end;到此同步的代码就都执行实现了,而后去微工作异步队列里去获取工作接下来执行resolve(async2返回的promise返回的),输入了async1 end;而后执行resolve(new Promise的),输入了promise2;最初执行setTimeout,输入了settimeout。 在第4步中, await 这里有一个机制, 就是 await 的期待, 不会阻塞内部函数的执行, 而 await 期待的 如果是一个 Promise 则 Promise 外面的代码还是同步执行, 如果不是 Promise ,就会应用 Promise.resolve 来进行封装, 这里的 async2 是一个 async 办法, 外面的 打印会同步执行, 而 await async2() 前面的代码 会放到微工作队列中的第一个地位,期待内部同步代码执行结束当前再执行。所以我晓得了script end为什么会优先于async1 end输入。 ...

February 8, 2023 · 1 min · jiezi

关于ruby:Spring中singleton-bean如何同时服务多个请求

当我开始学习 Spring 时,两个“难”的问题次要在我脑海中回旋: 如何创立单例 bean,而后如何在不同的类中主动拆卸单个 bean?设想一下这种状况: 有 2 个用户,其中一个想要登录,另一个想要同时在咱们的应用程序中创立报告。login 和 createReport 办法都应用范畴为单例的 userService bean。在这种状况下,这些办法是否按程序应用该单例 bean?否则 singleton bean 如何同时解决多个申请?答复他们并不像我想的那么艰难。只是须要廓清简略但重要的要点。这就是为什么我会尝试用根本的代码示例来形容它们。让咱们开始:1.先讲一下Spring容器会比拟好。因为我认为这会帮忙你在脑海中更好地形容过程。Spring 容器在其中创立 bean。创立所需的 bean 后,它会注入它们的依赖项。容器通过读取配置元数据(XML 或 Java 正文)来获取指令。因而,在初始化 Spring 容器后,您的应用程序就能够应用了,如下图所示: 当你像上面这样定义一个 bean 定义时,你通知容器它必须只为容器中的那个 bean 定义创立一个实例:<bean id=”accountDao” class=”…” scope=”singleton”/>此单个实例存储在此类单例 bean 的缓存中。而后 Spring 容器将这个缓存的对象返回给具备该 bean 定义的 bean 的所有申请和援用: 如果咱们想用 new() 运算符显示下面的示例,以形容 Spring 容器在应用程序启动时所做的简化视图,咱们能够编写如下代码:UserService userService = new UserService(); UserController userController = new UserController();userController.userService = userService; ReportController reportController = new ReportController();reportController.userService = userService复制代码@RestControllerpublic class UserController { ...

February 8, 2023 · 1 min · jiezi

关于ruby:订单30分钟未支付自动取消怎么实现

目录 理解需要计划 1:数据库轮询计划 2:JDK 的提早队列计划 3:工夫轮算法计划 4:redis 缓存计划 5:应用音讯队列 理解需要在开发中,往往会遇到一些对于延时工作的需要。例如 生成订单 30 分钟未领取,则主动勾销生成订单 60 秒后,给用户发短信 对上述的工作,咱们给一个业余的名字来形容,那就是延时工作。那么这里就会产生一个问题,这个延时工作和定时工作的区别到底在哪里呢?一共有如下几点区别定时工作有明确的触发工夫,延时工作没有定时工作有执行周期,而延时工作在某事件触发后一段时间内执行,没有执行周期定时工作个别执行的是批处理操作是多个工作,而延时工作个别是单个工作上面,咱们以判断订单是否超时为例,进行计划剖析计划 1:数据库轮询思路该计划通常是在小型我的项目中应用,即通过一个线程定时的去扫描数据库,通过订单工夫来判断是否有超时的订单,而后进行 update 或 delete 等操作实现能够用 quartz 来实现的,简略介绍一下maven 我的项目引入一个依赖如下所示<dependency>   <groupId>org.quartz-scheduler</groupId>   <artifactId>quartz</artifactId>   <version>2.2.2</version></dependency>复制代码调用 Demo 类 MyJob 如下所示package com.rjzheng.delay1;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class MyJob implements Job {   public void execute(JobExecutionContext context) throws JobExecutionException {       System.out.println("要去数据库扫描啦。。。");   }   public static void main(String[] args) throws Exception {       // 创立工作       JobDetail jobDetail = JobBuilder.newJob(MyJob.class)               .withIdentity("job1", "group1").build();       // 创立触发器 每3秒钟执行一次       Trigger trigger = TriggerBuilder               .newTrigger()               .withIdentity("trigger1", "group3")               .withSchedule(                       SimpleScheduleBuilder                               .simpleSchedule()                               .withIntervalInSeconds(3).                               repeatForever())               .build();       Scheduler scheduler = new StdSchedulerFactory().getScheduler();       // 将工作及其触发器放入调度器       scheduler.scheduleJob(jobDetail, trigger);       // 调度器开始调度工作       scheduler.start();   }}复制代码运行代码,可发现每隔 3 秒,输入如下要去数据库扫描啦。。。复制代码长处简单易行,反对集群操作毛病 ...

February 8, 2023 · 7 min · jiezi

关于ruby:为什么大家都说-SELECT-效率低

无论在工作还是面试中,对于SQL中不要用“SELECT *”,都是大家听烂了的问题,虽说听烂了,但广泛了解还是在很浅的层面,并没有多少人去追本溯源,探索其原理。效率低的起因先看一下最新《阿里java开发手册(泰山版)》中 MySQL 局部形容:【强制】在表查问中,一律不要应用 * 作为查问的字段列表,须要哪些字段必须明确写明。阐明: 减少查问分析器解析老本。增减字段容易与 resultMap 配置不统一。无用字段减少网络 耗费,尤其是 text 类型的字段。 开发手册中比拟概括的提到了几点起因,让咱们深刻一些看看: 不须要的列会减少数据传输工夫和网络开销用“SELECT * ”数据库须要解析更多的对象、字段、权限、属性等相干内容,在 SQL 语句简单,硬解析较多的状况下,会对数据库造成惨重的累赘。增大网络开销;* 有时会误带上如log、IconMD5之类的无用且大文本字段,数据传输size会几何增涨。如果DB和应用程序不在同一台机器,这种开销非常明显即便 mysql 服务器和客户端是在同一台机器上,应用的协定还是 tcp,通信也是须要额定的工夫。 对于无用的大字段,如 varchar、blob、text,会减少 io 操作精确来说,长度超过 728 字节的时候,会先把超出的数据序列化到另外一个中央,因而读取这条记录会减少一次 io 操作。(MySQL InnoDB)失去MySQL优化器“笼罩索引”策略优化的可能性SELECT * 杜绝了笼罩索引的可能性,而基于MySQL优化器的“笼罩索引”策略又是速度极快,效率极高,业界极为举荐的查问优化形式。例如,有一个表为t(a,b,c,d,e,f),其中,a为主键,b列有索引。那么,在磁盘上有两棵 B+ 树,即汇集索引和辅助索引(包含单列索引、联结索引),别离保留(a,b,c,d,e,f)和(a,b),如果查问条件中where条件能够通过b列的索引过滤掉一部分记录,查问就会先走辅助索引,如果用户只须要a列和b列的数据,间接通过辅助索引就能够晓得用户查问的数据。如果用户应用select *,获取了不须要的数据,则首先通过辅助索引过滤数据,而后再通过汇集索引获取所有的列,这就多了一次b+树查问,速度必然会慢很多。因为辅助索引的数据比汇集索引少很多,很多状况下,通过辅助索引进行笼罩索引(通过索引就能获取用户须要的所有列),都不须要读磁盘,间接从内存取,而汇集索引很可能数据在磁盘(外存)中(取决于buffer pool的大小和命中率),这种状况下,一个是内存读,一个是磁盘读,速度差别就很显著了,简直是数量级的差别。索引常识延申下面提到了辅助索引,在MySQL中辅助索引包含单列索引、联结索引(多列联结),单列索引就不再赘述了,这里提一下联结索引的作用。联结索引 (a,b,c)联结索引 (a,b,c) 理论建设了 (a)、(a,b)、(a,b,c) 三个索引咱们能够将组合索引想成书的一级目录、二级目录、三级目录,如index(a,b,c),相当于a是一级目录,b是一级目录下的二级目录,c是二级目录下的三级目录。要应用某一目录,必须先应用其下级目录,一级目录除外。 联结索引的劣势1) 缩小开销建一个联结索引 (a,b,c) ,理论相当于建了 (a)、(a,b)、(a,b,c) 三个索引。每多一个索引,都会减少写操作的开销和磁盘空间的开销。对于大量数据的表,应用联结索引会大大的缩小开销!2)笼罩索引对联结索引 (a,b,c),如果有如下 sql 的,SELECT a,b,c from table where a='xx' and b = 'xx'; 复制代码那么 MySQL 能够间接通过遍历索引获得数据,而无需回表,这缩小了很多的随机 io 操作。缩小 io 操作,特地是随机 io 其实是 DBA 次要的优化策略。所以,在真正的理论利用中,笼罩索引是次要的晋升性能的优化伎俩之一。3)效率高索引列多,通过联结索引筛选出的数据越少。比方有 1000W 条数据的表,有如下SQL:select col1,col2,col3 from table where col1=1 and col2=2 and col3=3;复制代码假如:假如每个条件能够筛选出 10% 的数据。 ...

February 1, 2023 · 1 min · jiezi

关于ruby:这几个SQL语法的坑你踩过吗

1、LIMIT 语句分页查问是最罕用的场景之一,但也通常也是最容易出问题的中央。比方对于上面简略的语句,个别 DBA 想到的方法是在 type, name, create_time 字段上加组合索引。这样条件排序都能无效的利用到索引,性能迅速晋升。SELECT *FROM   operationWHERE type = 'SQLStats'       AND name = 'SlowLog'ORDER BY create_timeLIMIT 1000, 10;复制代码好吧,可能90%以上的 DBA 解决该问题就到此为止。但当 LIMIT 子句变成 “LIMIT 1000000,10” 时,程序员依然会埋怨:我只取10条记录为什么还是慢?要晓得数据库也并不知道第1000000条记录从什么中央开始,即便有索引也须要从头计算一次。呈现这种性能问题,少数情景下是程序员偷懒了。在前端数据浏览翻页,或者大数据分批导出等场景下,是能够将上一页的最大值当成参数作为查问条件的。SQL 从新设计如下:SELECT   *FROM     operationWHERE   type = 'SQLStats'AND     name = 'SlowLog'AND     create_time > '2017-03-16 14:00:00'ORDER BY create_time limit 10;复制代码在新设计下查问工夫根本固定,不会随着数据量的增长而发生变化。2、隐式转换SQL语句中查问变量和字段定义类型不匹配是另一个常见的谬误。比方上面的语句:mysql> explain extended SELECT *     > FROM   my_balance b     > WHERE b.bpn = 14000000123     >       AND b.isverified IS NULL ;mysql> show warnings;| Warning | 1739 | Cannot use ref access on index 'bpn' due to type or collation conversion on field 'bpn'复制代码其中字段 bpn 的定义为 varchar(20),MySQL 的策略是将字符串转换为数字之后再比拟。函数作用于表字段,索引生效。上述情况可能是应用程序框架主动填入的参数,而不是程序员的原意。当初利用框架很多很繁冗,使用方便的同时也小心它可能给本人挖坑。3、关联更新、删除尽管 MySQL5.6 引入了物化个性,但须要特地留神它目前仅仅针对查问语句的优化。对于更新或删除须要手工重写成 JOIN。比方上面 UPDATE 语句,MySQL 理论执行的是循环/嵌套子查问(DEPENDENT SUBQUERY),其执行工夫可想而知。UPDATE operation oSET   status = 'applying'WHERE o.id IN (SELECT id               FROM   (SELECT o.id,                               o.status                       FROM   operation o                       WHERE o.group = 123                               AND o.status NOT IN ( 'done' )                       ORDER BY o.parent,                                 o.id                       LIMIT 1) t);复制代码 ...

January 5, 2023 · 7 min · jiezi

关于ruby:软件测试报告模板的类型有哪些

软件测试报告模板的类型,通常状况,测试报告分为六类: 1、注销测试报告模板(实用于软件产品增值税即征即退以及双软评估)。 2、鉴定测试报告模板(实用于政府我的项目申报、高新认证、我的项目结题和翻新产品认定等)。 3、验收测试报告模板(实用于各类软件和硬件零碎相结合的综合性集成我的项目的第三方验收测试,如政府、事业单位、企业、学校等我的项目验收)。 4、零碎测试报告模板(实用于软件和系统集成我的项目,由开发方发动并组织的我的项目验收)。 5、性能测试报告模板(实用于我的项目的性能验证、性能调优、发现性能缺点等利用场景)。 6、平安测试报告模板(扫描,浸透测试,代码审计;企业在网站或者APP利用上线之前,对网站、服务器或APP进行全面粗疏的平安监测,及早发现网站、服务器或APP测试的潜在破绽,免得蒙受黑客攻击,导致敏感数据泄露)。 举荐浏览: app压力测试怎么做 小程序兼容性测试怎么做 手机兼容性测试怎么做 缺点管理工具有哪些 app性能测试工具有哪些 自动化测试工具有哪些

May 13, 2022 · 1 min · jiezi

关于ruby:从论文到代码完成-RoIPooling

从论文到代码实现 RoIPoolingRoI Pooling失去特色图和候选框,就会将候选框投影在特色图,而后进行一次缩放失去大小一致的特色图,在 Faster RCNN 中,区域候选框用来预测对象是前景还是背景,这是 class head 要做的工作,而 regression 是学习到基于 anchor 的差分,也就是核心的偏移量和宽高的缩放。 在投影过程中候选框的尺寸和地位是相干于输出图像,而不是相干于特色图,首先需要将其进行转换到候选框在特色图上具体地位,而后在对提取候选框进行尺寸的缩放。 给定一个特色图和一组提议,返回会合的特色示意。区域提议网络被用来预测对象性和回归盒的偏差(对锚点)。这些偏移量与 anchor 拆散起来生成候选框。这些倡导通常是输出图像的大小而不是特色层的大小。因此,这些倡导需要按比例缩小到特色图层,之所以这样做,以便上游的CNN层能够提取特色。 咱们在原图上有一个尺寸,也就是候选框中心点的坐标以及宽度,首先咱们投影在原图上坐标点除以下采样的倍数,也就是 32 倍下采样,如果坐标无奈整除则进行取整操作。 import numpy as npimport torchimport torch.nn as nnfloattype = torch.cuda.FloatTensorclass TorchROIPool(object): def __init__(self, output_size, scaling_factor): #输入特色图的尺寸 self.output_size = output_size #缩放比率 self.scaling_factor = scaling_factor def _roi_pool(self, features): """ 在给定的缩放提取特色图基础,返回固定大小的特色图 Args: features (np.Array): """ # 特色图的通道数、高 和 宽 num_channels, h, w = features.shape # 计算步长 w_stride = w/self.output_size h_stride = h/self.output_size # res = torch.zeros((num_channels, self.output_size, self.output_size)) res_idx = torch.zeros((num_channels, self.output_size, self.output_size)) for i in range(self.output_size): for j in range(self.output_size): # important to round the start and end, and then conver to int # w_start = int(np.floor(j*w_stride)) w_end = int(np.ceil((j+1)*w_stride)) h_start = int(np.floor(i*h_stride)) h_end = int(np.ceil((i+1)*h_stride)) # limiting start and end based on feature limits # w_start = min(max(w_start, 0), w) w_end = min(max(w_end, 0), w) h_start = min(max(h_start, 0), h) h_end = min(max(h_end, 0), h) patch = features[:, h_start: h_end, w_start: w_end] max_val, max_idx = torch.max(patch.reshape(num_channels, -1), dim=1) res[:, i, j] = max_val res_idx[:, i, j] = max_idx return res, res_idx def __call__(self, feature_layer, proposals): """Given feature layers and a list of proposals, it returns pooled respresentations of the proposals. Proposals are scaled by scaling factor before pooling. Args: feature_layer (np.Array): 特色层尺寸 proposals (list of np.Array): 列表中每一个元素 Each element of the list represents a bounding box as (w,y,w,h) Returns: np.Array: proposal 数量,通道数,输入特色图高度, self.output_size """ batch_size, num_channels, _, _ = feature_layer.shape # first scale proposals based on self.scaling factor scaled_proposals = torch.zeros_like(proposals) # the rounding by torch.ceil is important for ROI pool scaled_proposals[:, 0] = torch.ceil(proposals[:, 0] * self.scaling_factor) scaled_proposals[:, 1] = torch.ceil(proposals[:, 1] * self.scaling_factor) scaled_proposals[:, 2] = torch.ceil(proposals[:, 2] * self.scaling_factor) scaled_proposals[:, 3] = torch.ceil(proposals[:, 3] * self.scaling_factor) res = torch.zeros((len(proposals), num_channels, self.output_size, self.output_size)) res_idx = torch.zeros((len(proposals), num_channels, self.output_size, self.output_size)) # 遍历候选框 for idx in range(len(proposals)): # proposal = scaled_proposals[idx] # adding 1 to include the end indices from proposal extracted_feat = feature_layer[0, :, proposal[1].to(dtype=torch.int8):proposal[3].to(dtype=torch.int8)+1, proposal[0].to(dtype=torch.int8):proposal[2].to(dtype=torch.int8)+1] res[idx], res_idx[idx] = self._roi_pool(extracted_feat) return res

May 8, 2022 · 2 min · jiezi

关于ruby:RVM切换到rbenvMacOS

参考原文: https://gist.github.com/akdetrick/7604130本文在翻译原文根底上对在实际操作中产生的问题追加了零星的解决办法. 起初看着RVM性能要比rbenv多, 所以抉择了RVM来治理ruby的版本, 但通过一段时间的应用发现对于ruby版本的管制还是rbenv不便些, 而且Gemset的设置多少有点麻烦, 设置不好连rails创立我的项目都报错. 所以索性换成rbenv. 1) remove RVM from your system首先,要删除RVM. 以下的命令等让你清理掉RVM的安装文件以及通过RVM装置的所有版本的Ruby. # rvm 的"自爆"模式, 将主动删除装置的ruby和本身的文件$ rvm implode# 偶然会有因权限问题导致 ~/.rvm 删除不掉的问题$ rm -rf ~/.rvm$ gem uninstall rvm$ rm ~/.rvmrc$ rm /etc/rvmrc2) remove any remaining traces of RVM从以下文件中删除所有关联rvm援用门路的设置 .profile.bash_profile.bashrczsh还须要批改: .zshrc3) install rbenv应用Homebrew装置rbenv和ruby-build插件 rbenv的装置也能够参考rbenv自家的文档: https://github.com/rbenv/rbenv#installation $ brew update$ brew install rbenv ruby-build4) install rubies for rbenv应用rbenv装置须要的ruby版本 # 列出可装置的ruby稳固版本:$ rbenv install -l# 装置指定版本的ruby:$ rbenv install 2.0.0-p247Note: 新装置一个ruby版本或gem之后如果呈现问题, 运行 $ rbenv rehash命令 ...

April 28, 2022 · 1 min · jiezi

关于ruby:ruby更换gem阿里镜像

有时候下载gem文件会比较慢或不胜利等,能够批改通过gem镜像源来进步下载速度。 参考rubygems镜像-rubygems下载地址-rubygems装置教程-阿里巴巴开源镜像站 阿里巴巴开源镜像站 在批改gem镜像之前,须要先查看一下,你以后零碎中gem的镜像是什么,而后才好进行对应的删除。 首先执行命令查看以后镜像 gem sources l 我的显示如下  C:\Users\Administrator>gem sources l*** CURRENT SOURCES ***https://rubygems.org/接着删除这个镜像执行命令 gem sources --remove https://rubygems.org/显示这个阐明删除胜利 C:\Users\Administrator>gem sources -r https://rubygems.org/https://rubygems.org/ removed from sources再增加新阿里巴巴gem镜像 gem sources -a https://mirrors.aliyun.com/rubygems/返回以下后果 C:\Users\Administrator>gem sources -a https://mirrors.aliyun.com/rubygems/https://mirrors.aliyun.com/rubygems/ added to sources镜像切换胜利后, 下载相对来说就快很多了。

February 15, 2022 · 1 min · jiezi

关于ruby:使用-Mastodon-搭建个人信息平台调优篇

本篇文章是应用 Mastodon 搭建个人信息平台的第二篇内容,我将聊聊在容器环境中搭建 Mastodon 后的一些利用调整和问题修复。 这篇文章或者同样是你可能找到的为数不多的对于如何在容器环境中搭建和优化 Mastodon 服务的内容。 写在后面本篇内容须要有上一篇内容的根底,所以如果你还未浏览上一篇内容,能够思考移步过来,浏览理解 《应用 Mastodon 搭建个人信息平台:前篇》。 在上篇文章完结后,咱们曾经能够通过手机利用进行登录和发帖记录信息了,然而在 Web 端应用的话,还是会遇到一些影响体验的小问题,同时,利用运行时应用的资源也会绝对节约,所以本篇内容就来解决这些问题。 为了关照新人,解决问题的程序依照从简到难,先从根底的服务配置开始吧。 如何启用 ES 全文搜寻在登录账号之后,在侧边栏抉择“首选项”,关上利用后盾页面。在后盾页面的侧边栏中抉择“治理”,就能够看到展现利用以后运行状况的信息面板啦。 在图片中咱们能够看到“服务器配置”中的“全文搜寻”目前是敞开着的。 为了让服务失常应用,咱们须要在前文中提到的配置文件 .env.production 中增加一些内容: ES_ENABLED=trueES_HOST=esES_PORT=9200接着应用 docker-compose down && docker-compose up -d 重启服务,稍等服务运行就绪之后,咱们就可能看到“全文搜寻”曾经启用啦。 加载字体资源报错的问题在利用控制台中,咱们会看到一条扎眼的报错。 Refused to load the font 'data:application/font-woff2;base64,...' because it violates the following Content Security Policy directive: "font-src 'self' https://hub-assets.lab.com".这是因为 config/initializers/content\_security\_policy.rb 中的设置比拟严格导致: Rails.application.config.content_security_policy do |p| p.base_uri :none p.default_src :none p.frame_ancestors :none p.font_src :self, assets_host p.img_src :self, :https, :data, :blob, assets_host p.style_src :self, assets_host p.media_src :self, :https, :data, assets_host p.frame_src :self, :https p.manifest_src :self, assets_host if Rails.env.development?... else p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url p.script_src :self, assets_host p.child_src :self, :blob, assets_host p.worker_src :self, :blob, assets_host endend解决这个问题很简略,只须要在 font 资源的安全策略中容许 data: 类型的资源即可: ...

January 25, 2022 · 5 min · jiezi

关于ruby:使用-Mastodon-搭建个人信息平台前篇

本篇文章是应用 Mastodon 搭建个人信息平台的第一篇内容,我将聊聊在容器环境中搭建 Mastodon 的一些细节。 同时,这篇文章或者你可能找到的为数不多的对于如何在容器环境中搭建和优化 Mastodon 服务的内容。 写在后面随着折腾的零碎越来越多,我开始冀望有一个中央可能将这些零碎中的音讯进行集中的出现,让我可能疾速清晰的理解到有什么乏味的陈腐的、重要的事件产生了,以及让我可能通过更简略的形式对已有零碎中的数据进行疾速的查问,以及记录一些忽然呈现的想法。 我认为以时间轴为线索的 Feed 流模式的信息展现,配合和各种“虚构利用”和 Bot 的对话形式或者可能解决我这个阶段的诉求。交互简略间接、交互操作层级也浅,在少数查问和记录场景下,我只须要输出内容,按下回车就能拿到我想要的数据,而不用关上具体的利用的页面,而后再一步一步、一步一步的操作。 在以往工作和生存中,其实多多少少也有应用过一些蕴含了交互或者性能和我诉求有交加的工具,比方:在新浪云工作应用的 TeamToy、在淘宝时应用的 Redmine 和阿里门户、美团时应用的大象、之后应用的 Slack、企业微信、学城等等。 不过这类计划少数都是外部或者 SaaS 化的计划,在集体应用场景下,尤其是联合各种 HomeLab 零碎,我更心愿它是一个私有化的服务。 对于新增“实体”,我比拟克服,所以所以在此之前的摸索过程中,我对 Phabricator、Confluence 、WordPress、Dokuwiki、Outline 等各种我之前比拟相熟的零碎都进行过了一些考察和简略的二次开发,发现尽管可能解决一部分问题,然而交互和体验上总感觉不是那么难受。因为这些工具或多或少都是基于合作登程,或者基于内容整顿登程,而不是信息汇聚和展现。我须要一个即便一个人应用也能很爽的计划。 于是,我开始彻底尝试切换思路,寻找一个上文中提到的,以时间轴为信息展现线索,可能和工具中的 Bot 互动,来记录我的想法、将各种我关注的事件实时汇聚到工具中,可能以简略的命令和办法查问各种零碎中已有的数据。最终,我抉择了 Mastodon,一个两年前我就曾经折腾过一阵的 “Twitter / Weibo Like” 的产品。 在开始折腾之前,咱们先来聊聊它的技术架构。 技术架构Mastodon 的技术架构属于比拟经典的 Web 架构,次要的性能组件有:前端利用(React SPA)、利用接口(Ruby Rails6)、推送服务(Node Express + WS)、后台任务(Ruby Sidekiq)、缓存和队列(Redis)、数据库(Postgres),以及可选的全文索引(Elasticsearch 7)形成。 除此之外,反对应用匿名网络通讯的形式和互联网上其余不同的社区实例通信,替换社区已公布内容,来实现其分布式社区的构想。不过这个性能不在本文范畴之内,而且非常简单,就不啰嗦开展了。 根底服务筹备在折腾利用之前,咱们先实现利用对于根底服务的依赖设施的搭建。先来聊聊网络布局。 搭建利用网关,进行网络布局和以往利用一样,咱们应用 Traefik 作为服务利用网关,让利用能够应用服务注册的形式动静地接入 Traefik。并且应用 Traefik 提供 SSL 装载、根底的 SSO 鉴权等。 如果你还不理解 Traefik,能够浏览之前的内容进行学习和理解。 我心愿 Mastodon 各个组件在可能通信、必要的服务可能应用 Traefik 进行服务注册,提供 Web 拜访的前提下,还能和主机上其余的容器服务在网络层面互相隔离。 ...

January 25, 2022 · 8 min · jiezi

关于ruby:Ruby-将引入新-JIT-编译器YJIT平均速度提升-23

近日,Ruby 代码仓库新增了一个对于合并 YJIT 的PR。 据介绍,YJIT 是一种应用 Lazy Basic Block Versioning (LBBV) 编译器架构构建的即时编译器。 在进行理论基准测试时,YJIT 比以后的CRuby 解释器平均速度晋升了23%。 Ruby 开发团队打算将 YJIT 蕴含在 Ruby 3.1 预览版中,以便更多用户能够帮忙他们对其进行测试,从而取得性能晋升。 目前 YJIT 默认处于禁用状态,须要关上--yjit 选项或设置 YJIT\_RUBY\_ENABLE=1 进行启用。须要留神的是,YJIT 临时只反对 macOS 和 Linux 零碎和 x86-64 CPU 架构。 其余问题 在不受反对的平台上,Ruby 应用传统的解释器生成的代码没有垃圾收集性能。超过设定的--yjit-exec-mem-size 数值就会报错。开发团队称在将来几个月内会解决此问题。YJIT 在运行时会应用更多内存,因为它须要调配机器代码,可通过设置--yjit-exec-mem-size 的值进行调整YJIT 不能与 MJIT 同时启用,两者中只有一个能够在运行时处于活动状态。

October 27, 2021 · 1 min · jiezi

关于ruby:Ruby-实现-数组反转-Not-Reverse

Ruby实现Array#reverse 性能 def reverse(arrays) new_arrays = [] index = arrays.size - 1 while index >= 0 new_arrays << arrays[index] index -= 1 end new_arraysend

October 22, 2021 · 1 min · jiezi

关于ruby:Ruby-实现-九九乘法表

require 'byebug'as = 1..9 as.each do |a| (1..a).each do |b| a = a.to_i b = b.to_i #byebug # s 用作对齐 s = a*b >= 10 ? " " : " " print " #{b} * #{a} = #{a*b}#{s}" end puts " \n"end

October 20, 2021 · 1 min · jiezi

关于ruby:含着泪写完了这个Ruby-NetHTTP短信验证码接口太不容易了

成人的世界素来没有容易二字,生存如此,代码亦是如此,因为我的项目的需要,我写了一个Ruby - NetHTTP接入短信验证码接口的代码,没想到说我对接的接口的短信服务商价格太贵。 无可奈何,通过本人的聪明才智,终于在在各大云市场找到一个价格低且稳固的短信供应商~可把本人牛批坏了~ 上面就给大家分享我写的代码吧: `require "uri"require "net/http" url = URI("https://vip.veesing.com/smsApi/verifyCode") https = Net::HTTP.new(url.host, url.port);https.use_ssl = true request = Net::HTTP::Post.new(url)request["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8"request.body = "appId=41KYR0EB&appKey=IIWCKKSR7NOQ&phone=1561894**&templateId=1043&variables=1234" response = https.request(request)puts response.read_body`这件事件通知咱们一个情理,验证码接口不要轻易乱接,很有可能是无用功。 Ruby - NetHTTP.rb和文档阐明下载

November 11, 2020 · 1 min · jiezi

译-在-Rails-中使用-Flash-Message即时信息

(本文翻译自:https://www.rubyguides.com/2019/11/rails-flash-messages/) 什么是即时信息? 即时信息是即时信息是一种将信息显示给你的 Rails 网站用户的一种方式,用于告诉他们发生了什么事。 示例: 密码被修改(确认提示)用户没有找到(错误信息)即时信息往往在 Controller 中设置即时信息,然后再视图中渲染出来。你的用户得到所需要的信息。 让我们来学习它如何工作。 如何使用即时信息你可以通过使用 flash 助手函数,来发起提示信息。 他们用起来很像 Ruby hash。 即时信息对象具有像 keys,any?,或者 each 这种方法,要访问即时信息,则是使用 []。 那么,你可以设置哪些类型的的消息呢? 默认情况下,你可以设置: noticealert这是一个使用例子: flash.alert = "User not found."另一种风格: flash[:alert] = "User not found."(两者只是风格不同) 你可以使用这些代码,在你的 Controller Actions 中,比如 index,create,new 之类的。 另一种使用方式: redirect_to :books_path, notice: "Book not found"这允许你在一步中,重定向页面和创建即时消息。 这很棒呦! Alert 对比 Notice据我了解,alert 或者 notice 具体使用哪个,不是很重要。哪个用着合适,就用哪个。 我习惯使用 alert 显示错误信息,使用 notice 显示一些提示信息。 两者主要还是风格的区别。 举个例子你可以将 alert 显示为红色,将 notice 显示为绿色。 你也可以根据需要,在控制器中,使用 add_flash_types,来创建你自己的消息类型。 ...

July 5, 2020 · 1 min · jiezi

译-如何使用-Rails-Helper

翻译自:https://www.rubyguides.com/2020/01/rails-helpers/ 在 Rails 中,Helper 是指什么? Helper 是一个函数(多数时候),用于 Rails 视图之间,共享可复用的代码。Rails 内置一组 Helper 函数。 其中一个是 time_ago_in_words。 例子time_ago_in_words(Time.now)# "less than a minute"time_ago_in_words(Time.now + 60)# "1 minute"time_ago_in_words(Time.now + 600)# "10 minutes"这个函数,用于显示指定格式的日期。 另一个用于 Rails 视图的 Helper 函数是 number_to_human。 例子:number_to_human(10_000)# "10 Thousand"当你想要将数字显示为可读的形式时,这个函数很有用。 你可以在 Rails 文档中,找到更多的内容:https://api.rubyonrails.org/ 那么,该如何定义自己的 Helper 函数呢? 编写自己的 Helper 函数如果你要编写 Helper 函数,正确的路径是 app/helpers,然后将你的 Helper 函数,写在其中的 helper module 中。 每个 Rails 应用,默认都带了基础的 helper module,命名为 ApplicationHelper。这里就是存放你 helper 函数的地方。 只要在模块中写好 helper 函数,那些函数在视图中,将自动变的可用。稍后将为你展示如何在 Controller 中使用它们,以及为什么这是个坏点子。如果你愿意,你可以在 ApplicationHelper 中写一切 helper 函数,但还有更好的组织方法。你可以创建一个你自己的文件,用来存储相关 helper 函数。 ...

July 1, 2020 · 1 min · jiezi

将博客搬至CSDN

上传文件到linux上, 是上传到当前所在的目录下yum list|grep lrzszsudo yum -y install lrzsz.x86_64命令:(参数 -y 如果linux上有相同的文件, 会覆盖) rzrz -y上传文件到linux上, 是上传到当前所在的目录下yum list|grep lrzszsudo yum -y install lrzsz.x86_64命令:(参数 -y 如果linux上有相同的文件, 会覆盖) rzrz -y上传文件到linux上, 是上传到当前所在的目录下yum list|grep lrzszsudo yum -y install lrzsz.x86_64命令:(参数 -y 如果linux上有相同的文件, 会覆盖) rzrz -y

October 9, 2019 · 1 min · jiezi

小型的编程项目有哪些值得推荐这本神书写了-22-个个个了不得

本文原创并首发于公众号【Python猫】,未经授权,请勿转载。 原文地址:https://mp.weixin.qq.com/s/Ob... 今天,猫哥要推荐一本非常著名的开源书籍:《500 Lines or Less》。 在开始正题之前,先介绍一下它所属的系列。该系列叫 AOSA,是“The Architecture of Open Source Applications”的简称,即“开源程序的体系结构”,目前有四本书,本期主角是最近的一本(发布于 2016.7.12)。 这个系列最初的目的是:研究那些优秀的开源项目,从中吸取精华的实践经验。 在前三本书中,研究对象已多达 50 几个,其中不乏名头响亮者,例如 Eclipse、Selenium、Git、matplotlib、nginx、Puppet、Pypy、SQLAlchemy 与 Twisted 等等。 每个章节的作者都是开源软件的核心参与者,介绍了项目是如何设计的、为什么这样设计、主要的组成部分是什么、各模块间如何互动、开发中的优秀成果有哪些…… 这些书拆解了开源界的明星项目,通过阅读,你能了解到开源作者们的思考方式,了解到各类困难问题的解决方案,学习使用现成的轮子。所谓见多识广,学习吸取经验,有望“站在巨人的肩膀上”。 但是,这几本书主要偏向于架构和工程方面,项目代码量基本是几千上万行,对于初级程序员来说不够实用,想要吃透,挑战性太大。 针对这个问题,该系列新出了一本《500 Lines or Less》,专注于 500 行或更少代码的小型项目。 关注编写代码时所作出的设计决定与权衡 : 为什么要使用一些接口将应用程序分成不同的模块?为什么在这里使用继承,在别处使用封装?如何预测程序的扩展,如何让其他程序员轻松实现?简而言之,这本书聚焦于一些相对较小但又很具代表性的课题,并通过 500 行以内的代码来实现它。 书中写了 22 个项目,下面逐一简介: 1、Blockcode: A visual programming toolkit(可视化编程工具包) 使用语言:HTML、CSS、JavaScript 该项目基于开源的 Waterbear 工具,提供可视化的操作界面,通过简单而直观的交互方式,实现图形编程。 2、A Continuous Integration System(持续集成系统) 使用语言:Python 2 CI 是软件开发中重要的持续集成系统,保障新功能的稳定实现。这个项目介绍了 CI 系统的工作原理,并尝试构建自己的 CI 系统,实现监听器、测样例调度器和测试运行器。 3、Clustering by Consensus(分布式系统) ...

July 15, 2019 · 2 min · jiezi

RPA增进企业内部协作的润滑剂

到目前为止,有关RPA(机器人流程自动化)的许多好处(大幅降低成本、减少错误、优化业务流程等),已经开始被更多的人所熟知。但实际上,RPA还是增进企业内部各方协作的“润滑剂”。 1、之前从未合作过的员工之间的协作 自动化端到端流程本身的行为将迫使员工进行协作,包括彼此从未有过互动的员工。为了实现流程自动化,组织必须将不同部门的员工(例如IT、财务和客服人员)聚集在一起,组成跨职能团队。并仔细考虑整个流程,因为在创建RPA自动化流程机器人的过程中,可能会出现十几个以前不曾知道的流程变体。通过跨职能团队的协作,迅速找出问题的解决方式,让人意识到一切都是相互关联的。 2、IT与业务之间的协作 几十年来,专家一直在倡导IT和业务应该更紧密地合作。但在许多组织当中,技术专家和业务用户之间并没有形成真正的合作。极端情况下,这种脱节甚至还会成为阻碍技术功能顺利实现的“元凶”。RPA的部署,往往需要技术人员和非技术人员携手合作,以便自动化流程不是简单地做做样子,而是切实改善业务流程。 3、团队之间的协作 一些企业正在使用双团队方法开发RPA机器人,以确保机器人正常工作。一个团队开发核心自动化功能,而另一个团队验证自动化的逻辑。如果有任何错位,两个团队会齐心协力,共同解决问题。这可确保通过密切协作对逻辑进行全面测试和双重检查。 4、员工和机器人之间的协作 随着RPA部署的增加,自动化流程也将变得越来越复杂,并且需要人工和数字工作人员进行协作的混合型工作人员。因为随着流程变得更加复杂和多方面,在流程中的某些点或多点通常需要人为判断。机器人执行这些任务,将其传递给员工,然后员工再将其传递回机器人以进行另一个行动思考,做出选择,决定行为过程。随着RPA越来越深入企业各流程,机器人与人类员工的合作将会越来越多。 5、员工与客户之间的“协作” 无论是B2B还是B2C,销售人员和客户之间的互动都很复杂。一些符合客户需求的产品特性(尺寸、颜色和特征)的讨论必须得到更多例行任务的支持,例如确定产品是否有库存,处理订单以及安排交付。然而,这些方面经常会妨碍实际的销售。通过RPA自动化这些流程,让机器人处理它们,将员工从中释放,并更好的与客户沟通,以确保提供满足其精确要求的产品或服务。 自动化并不意味着人类工作者将不再相互交流。实际上RPA会鼓励不同业务部门之间,跨职能团队之间,客户之间,甚至机器人之间的协作。从某种意义上说,部署与实施RPA的过程,就是鼓励员工、团队协作互动的过程。

July 8, 2019 · 1 min · jiezi

PC软件web网站小程序手机APP产品如何增加个人收款接口

接入前准备通过 XorPay 注册个人收款接口,原理是帮助你签约支付宝和微信(不需要营业执照)支持个人支付宝和个人微信支付接口,大概几分钟可以开通,开通后即可永久使用PC 网站接入效果:用户点击支付后,前端ajax 请求你的后台,你后台再请求 xorpay 支付接口返回支付二维码到前台,页面展示微信或者支付宝二维码,用户用手机微信或支付宝扫码支付接口:可以使用 JSAPI / Native / 收银台 / 支付宝当面付 支付接口JSAPI 支付,通过构造二维码,用户微信扫码后在打开自己服务器的页面,再在这页面通过 JSAPI 拉起微信支付收银台支付,效果和 JSAPI 一样,更简单,不用自己请求获取 openid,直接在 xorpay 的页面下发起支付Native 支付,前端 ajax 请求自己后端的接口,后端接口请求 xorpay 支付接口,返回支付二维码,用户微信扫码后支付支付宝当面付,方法同 Native 接口PC 软件效果:用户点击支付后,前端网络请求你的后台,你后台再请求 xorpay 支付接口返回支付二维码到前台,页面展示微信或者支付宝二维码,用户用手机微信或支付宝扫码支付接口:可以使用 JSAPI / Native / 收银台 / 支付宝当面付 支付接口JSAPI 支付,通过构造二维码,用户微信扫码后在打开自己服务器的页面,再在这页面通过 JSAPI 拉起微信支付收银台支付,效果和 JSAPI 一样,更简单,不用自己请求获取 openid,直接在 xorpay 的页面下发起支付Native 支付,前端 ajax 请求自己后端的接口,后端接口请求 xorpay 支付接口,返回支付二维码,用户微信扫码后支付支付宝当面付,方法同 Native 接口手机网站接入效果:因为个人的微信接口没有 h5 功能(个人支付宝当面付可以 h5),所以只能扫码接口:可以使用 JSAPI / 收银台 / 支付宝当面付 支付接口JSAPI 支付 ...

June 23, 2019 · 1 min · jiezi

个人收款之微信小微商户

微信支付小微商户介绍微信支付商户申请面向线下小微商户开放,无需营业执照,个人即可开通。符合条件的微信支付服务商可为小微商户发起接入申请。点击开通小微商户 一、小微商户能力介绍1. 快速进件(审核开通只需要几分钟)2. 支持零钱、借记卡、信用卡支付方式3. 交易手续费 0.38%4. 每日结算款T+1日自动提现至商户个人银行卡 小微商户普通商户收款方式银行卡银行卡交易费率0.38% 点击开通小微商户标准费率 查看对照表支付方式零钱、借记卡、信用卡零钱、借记卡、信用卡支付权限JSAPI支付 Native支付 付款码支付JSAPI支付 Native支付 付款码支付 H5支付 APP支付管理能力可登录商家助手小程序可登录商家助手小程序 可登录微信支付商户平台二、申请规则1. 小微商户仅支持服务商通过API发起接入申请2. 申请提交后,平台一般会在5分钟内完成审核,若通过,API会返回签约二维码,小微商户需扫码确认方可完成签约3. 小微商户签约后,平台会实时开通交易能力,可由服务商为小微商户发起JSAPI支付、付款码支付、Native支付 小微商户普通商户申请方式服务商通过API申请服务商通过页面申请审核耗时5分钟内 点击开通小微商户48小时内账户验证方式平台快捷验证(无需商户操作)打款验证+回填金额签约微信签约微信签约 商户平台签约三、申请材料点击注册登陆查看资料表格 五、常见问题点击查看

June 10, 2019 · 1 min · jiezi

Ruby-比特币开发教程汇总

Mixin Network 是一个免费的 极速的端对端加密数字货币交易系统. Mixin network 官方资源汇总 课程简介创建一个机器人Ruby比特币开发教程: 机器人接受比特币并立即退还用户Ruby比特币开发教程: 创建比特币钱包Ruby 买卖Bitcoin:ExinCore API 实时兑换Ruby 买卖Bitcoin:在自由市场Ocean.One挂单买卖Ruby 买卖任意ERC20 token:在自由市场Ocean.One挂单买卖其他编程语言汇总Python 比特币开发教程 Node.js 比特币开发教程 Java 比特币开发教程 Golang 比特币开发教程 C# 比特币开发教程

May 29, 2019 · 1 min · jiezi

用Ruby在去中心化交易所OceanOne上挂单买卖任意ERC20-token

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易!在掌握了ERC20 token之后,就可以把任何token在Ocean上买卖。 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Benz币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if cmd == "aw" assetsInfo = walletAccount.read_assets() p "--------The Wallet Assets List-----------------" assetsInfo["data"].each { |x| puts x["symbol"] + " " + x["balance"] + " " + x["public_key"] + x["account_name"] + " " + x["account_tag"]} p "----------End of Wallet Assets --------------"end调用 read_assets API的完整输出如下: "--------The Wallet Assets List-----------------"Benz 10.03 0x822664c2EFb27E2Eb4c4286f421B4BF6FB943fC6ETH 0 0x822664c2EFb27E2Eb4c4286f421B4BF6FB943fC6EOS 0 eoswithmixin b0adfae2f8828d15e11cb1fbe23d6096USDT 1 1KB4RbV5W4MNybpjcJjULKNVXubfR5MJqACNB 0.99999995 0x822664c2EFb27E2Eb4c4286f421B4BF6FB943fC6BTC 0 1KB4RbV5W4MNybpjcJjULKNVXubfR5MJqA"----------End of Wallet Assets --------------"-------------------------------------------------------------------------限价挂单挂限价买单 低于或者等于市场价的单.挂限价卖单 高于或者是等于市场价的单.OceanOne支持三种基类价格: USDT, XIN, BTC, 即: Benz/USDT, Benz/XIN, Benz/BTC, 这儿示范Benz/USDT. ...

May 29, 2019 · 2 min · jiezi

通过-Ruby-买卖Bitcoin使用开放交易所OceanOne

上一章介绍了Exincore,你可以1秒完成资产的市价买卖。如果你想限定价格买卖,或者买卖一些exincore不支持的资产,你需要OceanOne。 方案二: 挂单Ocean.One交易所Ocean.one是基于Mixin Network的去中心化交易所,它性能一流。你可以在OceanOne上交易任何资产,只需要将你的币转给OceanOne, 将交易信息写在交易的memo里,OceanOne会在市场里列出你的交易需求,交易成功后,会将目标币转入到你的MixinNetwork帐上,它有三大特点与优势: 不需要在OceanOne注册不需要存币到交易所支持所有Mixin Network上能够转账的资产,所有的ERC20 EOS代币。预备知识:你先需要创建一个机器人, 方法在 教程一. 安装依赖包我们需要依赖 msgpack and mixin-bot ,第四章 已经做过介绍, 你应该先安装过它了. 充币到 Mixin Network, 并读出它的余额.此处演示用 USDT购买BTC 或者 用BTC购买USDT。交易前,先检查一下钱包地址。完整的步骤如下: 检查比特币或USDT的余额,钱包地址。并记下钱包地址。从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。比特币与USDT的充值地址是一样的。 if cmd == "aw" assetsInfo = walletAccount.read_assets() p "--------The Wallet Assets List-----------------" assetsInfo["data"].each { |x| puts x["symbol"] + " " + x["balance"] + " " + x["public_key"] + x["account_name"] + " " + x["account_tag"]} p "----------End of Wallet Assets --------------"end取得Ocean.one的市场价格信息如何来查询Ocean.one市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. if ocmd == "1" Utils.OceanOneMarketPriceRequest(BTC_ASSET_ID, USDT_ASSET_ID)enddef self.OceanOneMarketPriceRequest(asset_id, base_asset_id) full_url = "https://events.ocean.one/markets/" + asset_id + "-" + base_asset_id + "/book" data = HTTP.get(full_url).body body = "" redData = data.readpartial while redData != nil body = body + redData redData = data.readpartial end result = ActiveSupport::JSON.decode(body).with_indifferent_access result["data"]["data"]["asks"].each { |x| puts x["side"] + " " + x["price"] + " " + x["amount"] + " " + x["funds"] } result["data"]["data"]["bids"].each { |x| puts x["side"] + " " + x["price"] + " " + x["amount"] + " " + x["funds"] }end交易前,创建一个Memo!在第二章里,Ruby比特币开发教程: 机器人接受比特币并立即退还用户, 我们学习过转帐,这儿我们介绍如何告诉Ocean.one,我们给它转帐的目的是什么,信息全部放在memo里. ...

May 27, 2019 · 3 min · jiezi

流程图绘制工具有哪些国产的流程图设计软件

亿图流程图制作软件是一款用于绘制各种流程图,同时兼具跨平台,云储存,分享功能的专业流程图制作软件。操作简单,功能强大,非常容易实现可视化、分析和交流复杂信息。软件内置海量精美的流程图模板与图库,帮助你轻松绘制项目管理流程图,程序流程图,工作流程图,过程流程图等。 如何用来绘制一个流程图呢 第一步 选择从模板创建或者创建一个新页面 方法一:创建一个新的页面 点击文件-新建-流程图。 双击模板下的流程图选择需要绘制的种类,进入编辑状态。 方法二:使用模板创建程图 点击文件-新建-流程图。 当找到需要的模板时,双击模板或者点击右上角预览窗口下的创建导按钮,即可成功创建一个含有预设内容的流程图。 第二步 添加图形 方法一:用图形的浮动按钮添加 从左侧模板库中拖出一个流程形状。 点击四周的浮动按钮。 方法二: 从库里拖放添加 从界面左边的符号库里拖动一个图形。 把拖动的图形移动到要吸附的标题旁,松开鼠标会自动链接。 第三步 排版和连接线样式 排版十分灵活,可以智能的调整大小和对齐,还可以根据已经存在图形的位置标出对齐线,其自动性为我们带来便捷。 第四步 添加文本和其他内容 添加文本 双击流程图图形。 输入文本。 点击绘图页面的任意空白区域或者按 ESC 键完成输入文字。 另外流程图制作软件不仅可以添加文件,还可以添加超链接,附件、图释和其他内容以提供上下文信息。 第五步 美化功能 ...

May 27, 2019 · 1 min · jiezi

如何用-Ruby-买卖Bitcoin

方案一: 通过ExinCore API进行币币交易Exincore 提供了基于Mixin Network的币币交易API. 你可以支付USDT给ExinCore, ExinCore会以最低的价格,最优惠的交易费将你购买的比特币转给你, 每一币交易都是匿名的,并且可以在区块链上进行验证,交易的细节只有你与ExinCore知道! ExinCore 也不知道你是谁,它只知道你的UUID. 预备知识:你先需要创建一个机器人, 方法在 教程一. 安装依赖包正如教程一里我们介绍过的, 我们需要依赖 mixin-bot, 你应该先安装过它了, 这儿我们再安装 easy-uuid, msgpack 两个软件包. gem install msgpack gem install easy-uuid充币到 Mixin Network, 并读出它的余额.ExinCore可以进行BTC, USDT, EOS, ETH 等等交易, 这儿演示如果用 USDT购买BTC 或者 用BTC购买USDT, 交易前,先检查一下钱包地址!完整的步骤如下: 检查比特币或USDT的余额,钱包地址。并记下钱包地址。从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。请注意,比特币与USDT的地址是一样的。 if cmd == "aw" assetsInfo = walletAccount.read_assets() p "--------The Wallet Assets List-----------------" assetsInfo["data"].each { |x| puts x["symbol"] + " " + x["balance"] + " " + x["public_key"] + x["account_name"] + " " + x["account_tag"]} p "----------End of Wallet Assets --------------"end查询ExinCore市场的价格信息如果来查询ExinCore市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. ...

May 25, 2019 · 3 min · jiezi

Ruby-比特币开发教程-创建比特币钱包

我们已经创建过一个回复消息的机器人和一个能自动支付比特币的机器人. 通过本教程的学习,你可以学到如下内容如何创建一个比特币钱包.如何读取比特币钱包的余额.如何支付比特币并即时确认.如何将Mixin Network的比特币提现到你的冷钱包或第三方交易所.前期准备:你要有一个Mixin Network账户。下面的代码创建一个帐号,并写到csv文件里。 if File.file?(WALLET_NAME) p "mybitcoin_wallet.csv has already existed !" nextendyaml_hash = YAML.load_file('./config.yml')MixinBot.client_id = yaml_hash["MIXIN_CLIENT_ID"]MixinBot.session_id = yaml_hash["MIXIN_SESSION_ID"]MixinBot.client_secret = yaml_hash["MIXIN_CLIENT_SECRET"]MixinBot.pin_token = yaml_hash["MIXIN_PIN_TOKEN"]MixinBot.private_key = yaml_hash["MIXIN_PRIVATE_KEY"]access_token = MixinBot.api.access_token("GET","/","")rsa_key = OpenSSL::PKey::RSA.new(1024)private_key = rsa_key.to_pem()p private_keypublic_key = rsa_key.public_key.to_pemsecret_client = public_key.sub("-----BEGIN PUBLIC KEY-----\n","").sub("\n-----END PUBLIC KEY-----\n","")reqInfo = MixinBot.api.create_user("ruby bot",secret_client)p reqInfo["data"]["pin_token"]p reqInfo["data"]["user_id"]p reqInfo["data"]["session_id"]CSV.open(WALLET_NAME, "wb") do |csv| csv << [private_key, reqInfo["data"]["pin_token"], reqInfo["data"]["session_id"], reqInfo["data"]["user_id"]]end上面的语句会在本地创建一个RSA密钥对,然后调用Mixin Network来创建帐号,最后保存帐号信息到csv文件. 现在你需要小心保管好你的帐号信息,在读取该账户的比特币资产余额或者进行其他操作时,将需要用到这些信息. 给新建的帐号创建一个比特币钱包新账号并不默认内置比特币钱包, 现在读一下比特币余额就可以创建一个比特币钱包。 if cmd == "2" table = CSV.read(WALLET_NAME) MixinBot.client_id = table[0][3] MixinBot.session_id = table[0][2] MixinBot.pin_token = table[0][1] MixinBot.private_key = table[0][0] botAssetsInfo = MixinBot.api.read_asset(BTC_ASSET_ID) p botAssetsInfo p "The BTC wallet address is " + botAssetsInfo["data"]["public_key"] p "The BTC wallet balance is " + botAssetsInfo["data"]["balance"]end创建的帐号的比特币资产详细信息如下,其中public key就是比特币的存币地址: ...

May 22, 2019 · 3 min · jiezi

流程图在线制作网站流程图怎么画输入

流程图是一种比较常见的图表,无论是在日常工作中还是生活中都随处可见。如果你是初入职场的新人,可能需要接触到一些简单的工作流程、会议流程图;如果你是产品经理、项目管理者或是软件开发师,更是需要经常接触到这类图表。流程图作为一种使用率非常高的图表,在商业中被誉为项目的基石。想要成为一名优秀的职场人士,掌握和熟练使用流程图,是一项必备的技能。曾经的某一天,你学会用Word绘制流程图,但为了对齐连接线,差点气到吐血。现在,你需要一款专业的流程图绘制工具,来拯救你的小宇宙! 亿图图示流程图制作软件「亿图图示」 是一款专业的图形图表设计软件,它可用于绘制全系列的流程图。一点也不夸张的说,亿图图示绘制流程图速度远高于Word绘图,让原本需要画1小时的流程图,只需10分钟即可完成。毕竟,专业的才是高效的。 与Word机械化的手动绘图方式不同,亿图图示更显智能,特别是以下几点功能尤为突出: 1、具备齐全的流程图符号,拖入画布即可; 2、搭载智能浮动按钮,可实现一键添加或修改符号; 3、画布智能识别连接点,和强迫症说再见; 4、双击符号,即可输入文本; 5、多套主题样式一键替换,所见即所得。 用亿图怎么画流程图使用亿图图示 绘制流程图 ,无论图有多难、多复杂,都可以被分解为简单的6个步骤。在软件里完成绘图后,流程图可以被导出为PDF、Ofiice以及PNG等格式。如果你想让作品进行在线分享,可以选择单独生成网页地址,这样你的同事、好友不用下载,网页在线或者手机扫一扫就能查看文档。 如果说亿图的哪一项功能更受欢迎,那么它的符号库应是当仁不让。据悉,亿图软件公司设计了一万多个矢量符号,使用的时候,可以直接从软件的左侧符号库中搜索获取。在符号库流程图这一分类下,内置了数据、判断、文档等上百个流程图符号。丰富的符号,专业的图形,帮助我们有效绘图,减少错误率,办公效率只增不减。 基本流程图符号素材: 基本流程图常用符号商务流程图常用符号亿图图示还提供了多样化的模板例子,除了流程图,还涉及思维导图、信息图、商业图表、组织架构图、拓扑图、电路图等等。现成的例子,可供我们参考和使用,这对于新手而言,无疑是加速学习、绘图的好办法。 亿图流程图软件实用模板流程图的运用领域很广很杂,或许曾经我们面对它的时候,是捶胸顿足、是不知所措,但如今学会 使用亿图图示画专业的流程图 之后,就再也不用担心。

May 15, 2019 · 1 min · jiezi

CSS语言预处理----SASS一分钟快速入门

1.先安装ruby下载地址https://rubyinstaller.org/2.安装sass和compass gem install sass gem install compass3.创建scss文件@charset “utf-8”;//变量$text-color:#000;//通用样式@mixin el1 { text-overflow:ellipsis; -o-text-overflow:ellipsis; -ms-text-overflow:ellipsis; overflow:hidden; white-space:nowrap;}//方法@mixin border-radius($width){ border-radius:$width; -webkit-border-radius:$width; -moz-border-radius:$width; -o-border-radius:$width; -ms-border-radius:$width;}//继承(缺点:编译后在外面出现该css).commonText { font-size:22px; font-weight:900;}//占位符(与继承的区别是,不会在外面出现该css)%mt15 { margin-top:15px;}body { .box { @extend .commonText; // 继承使用 @extend %mt15; //占位符使用 @include border-radius(5px); // 方法使用 @include el1; // 混合宏使用 color:$text-color; // 变量使用 cursor:pointer; border:1px solid #ccc; width:124px; &:hover { color:red; } } }4.编译监听scss文件sass –watch index.scss:index.css5.愉快的使用css文件吧

April 16, 2019 · 1 min · jiezi

缅怀那些正渐行渐远的编程语言

现代编程语言的祖先 (1801)Joseph Marie Jacquard 用打孔卡为一台织布机编写指令,在挂毯上织出了“hello, world”字样。当时的reddit网友对这项工作的反响并不热烈,因为它既缺少尾递归调用,又不支持并发,甚至都没有注意在拼写时恰当地区分大小写。这套机械编制技巧后来被改良成纸卷钢琴录音,也激发IBM创建者Herman Hollerith使用打洞卡来记录数据和做计算机程序设计。IBM为纪念纺织工业,后来在1994年也将其操作系统命名为OS/2 Warp(warp即是纺织布上的经线)。Ada Lovelace (1824)1842 年拜伦之女 Ada Lovelace 写了世界上第一个程序。她的努力只遇到了一点点小小的麻烦,那就是:实际上并没有任何计算机能够用来运行她的程序。后来的企业架构师们重新吸收了她的这个技能,用来学习如何更好地使用UML进行编程。Ada Lovelace为Charles Babbage的分析机写了一个计算伯努利数的算法实现,因此被后世公认为是世界上第一个程序员。实际上,由于分析机设计思想过于先进,在当时根本没有被制造出来。(Babbage的分析机一般被认为是现代电子通用计算机的先驱。)讽刺现在的某些“软件架构师”顶多只会纸上谈兵地画画UML。Fortran (1957)John Backus 和 IBM 发明了 Fortran(FORmula TRANslator)语言。它是世界上最早出现的计算机高级程序设计语言,广泛应用于科学和工程计算领域。FORTRAN语言以其特有的功能在数值、科学和工程计算领域发挥着重要作用。Fortran 90之前的版本是人们所知晓的FORTRAN(全部字母大写),从Fortran 90以及以后的版本都写成Fortran(仅有第一个字母大写)。关于IBM或Fortran并没有什么特别的地方,除了写 Fortran程序的时候不系蓝领带将被编译器视作是一个 syntax error。蓝领带、白衬衫、深色西装似乎是IBM公司20世纪经典的dress code。早期Fortran(Fortran 77)对程序书写格式的要求那是相当严格。(例如,固定格式缩进)Cobol (1959)在输掉了和 L. Ron Hubbard 之间的一场打赌之后,Grace Hopper 和其他几个发明了所谓的“面向Boilerplate的全大写化语言”(Capitalization Of Boilerplate Oriented Language,Cobol)Cobol(CommonBusinessOrientedLanguage)是数据处理领域最为广泛的程序设计语言,是第一个广泛使用的高级编程语言。在企业管理中,数值计算并不复杂,但数据处理信息量却很大。为专门解决经企管理问题,美国的一些计算机用户于1959年组织设计了专用于商务处理的计算机语言COBOL,并于1961年美国数据系统语言协会公布。COBOL语言以代码极其冗长和通篇大写字母的书写风格而闻名。Pascal (1970)1970年 Niklaus Wirth 创造了Pascal,一个过程式的语言。尽管Pascal非常流行(然而在八十到九十年代时比21世纪更加流行),依据维尔特的对这种语言的定义来构建Pascal,使它不适合在非教学的场合使用,这遭到了广泛的批评。 推广了C语言的Brian Kernighan早在1981年就在他的论文《Why Pascal Is Not My Favourite Programming Language》对Pascal提出了严厉的抨击。Smalltalk (1980)Alan Kay 创造了Smalltalk并发明了“面向对象”这个词。当被问到它的含义时,他回答道:“Smalltalk 程序本身就是对象。”当被问到对象是由什么组成时,他回答到:“对象。”当再一次被问到这个问题时,他说“看,它从里到外都是对象。直到你抽出一只乌龟。”90年代的许多软件开发思想得利于Smalltalk,例如Design Patterns, Extreme Programming(XP)和Refactoring等。20世纪70年代到80年代前期,美国施乐公司的帕洛阿尔托研究中心(PARC)开发了Smalltalk编程语言。从Smalltalk-72、Smalltalk-78到Smalltalk-80,他们开发完成了整个Smalltalk系列,Smalltalk编程语言对近代面向对象编程语言影响很大,所以称之为“面向对象编程之母”。Smalltalk的设计从很大程度上受到了Logo的影响。这门语言在70年代初期就诞生了,但公开可用的第一版是Smalltalk-80 Version 1。Ada (1983)为了纪念伟大的先辈程序员 Ada Lovelace 那能够写出永远也无法被执行的代码的彪悍技能,Jean Ichbiah和美国国防部创造了Ada语言。Ada不仅体现了许多现代软件的开发原理,而且将这些原理付诸实现。同时,Ada语言的使用可大大改善软件系统的清晰性、可靠性、有效性、可维护性。Ada是现有的语言中无与伦比的一种大型通用程序设计语言,它是现代计算机语言的成功代表,集中反映了程序语言研究的成果。Ada的出现,标志着软件工程成功地进入了国家和国际的规模。尽管缺乏证据显示有任何重要的Ada程序曾经被完成过,历史学家仍然确信Ada是个成功的公益项目,它让数以千计的国防承包商免于沦落为与黑帮为伍。Ada 曾经是美国国防部指定的嵌入式计算机系统唯一开发语言,在其研发上耗资巨大。(国防承包商们于是不用靠贩卖军火给黑帮来维持生计了。)以上语言虽然都在不同程度上渐渐不再为现代的多数开发者所用,但每一次的创新与创造,都将关乎未来。近年来年度编程语言排行(来源:TIOBE)语言会迭代升级、有兴衰起落。历年来编程语言排行榜的名次也都是在不断变化,不论是否流行 ,都值得被尊重。仅以此,向正在努力着的开发者们致敬! ...

April 8, 2019 · 1 min · jiezi

对话Ruby创始人松本行弘、阿里高级技术专家朴灵!

4月25日,云栖社区联合阿里云国际站,特别邀请了Ruby创始人Matz(松本行弘)、阿里云高级技术专家朴灵,来为开发者们分享干货。在本次活动上可以了解到Ruby语言最新的动态,Ruby和新语言golang在性能方面的差别。听听Matz畅谈他对云原生发展的看法,了解下他最近的动向。可以听到阿里云高级技术专家朴灵分享阿里云在开发语言上的动向,以及对于开发者的支持。马上免费报名围观:https://yq.aliyun.com/live/920?utm_content=g_1000050058活动议程:讲师介绍及演讲内容:讲师:松本行弘(MatsumotoYukihiro)1965年生。日本鸟取县米子市出身。毕业于筑波大学第三学群情报学类。Ruby程序设计语言的创始人。在“株式会社网络应用通信研究所”担任特别研究员,“一般财团法人Ruby ”担任理事长等多种职务。中学二年级时,在父亲的口袋型电脑 Sharp PC-1210 上以 Basic 写了第一个程式。 1984 年进入筑波大学第三学群资讯(情报)学类。大学其中两年休学,从事基督教传教工作。 大学时在程式语言研究室,1990 年毕业。1993年以来,一直从事Ruby的设计与开发。 1997 年开始,在「株式会社 Network 应用通信研究所」担任特别研究员,专注开发 Ruby。著书:「物件导向Script语言Ruby」(与石冢圭树共同著作),「RubyDesktopReference」,「软体工匠(ソフトウェアの匠)」等。 自称「语言otaku」(语言宅男)。演讲内容:For Matsumoto san’s topic:Introduce the most recent Ruby progress and roadmap, especially on comparison of new language like Go-lang especially performanceBest practise/approach to ruby with cloud native trend讲师:朴灵(田永强)阿里云高级技术专家,负责阿里云多语言SDKs&Tools工作。“深入浅出Node.js”作者,曾经是一个Node.js贡献者 。GitHub ID:JacksonTian田永强,文艺型码农,就职于阿里云基础产品事业部,Node.js布道者,写了多篇文章介绍Node.js的细节。活跃于CNode社区,是线下会议NodeParty的组织者和JSConf China(沪JS和京JS)的组织者之一。热爱开源,多个Node.js模块的作者。叩首问路,码梦为生。演讲内容:阿里巴巴的技术栈ruby sdk 的现状 和未来的计划阿里巴巴在serverless和cloud 的实践马上免费报名围观:https://yq.aliyun.com/live/920?utm_content=g_1000050058本文作者:山哥在这里阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 2, 2019 · 1 min · jiezi

编程高阶用法--词汇

有追求的开发者总会在开发时遇到变量命名困难或者命名冗长庸俗的时候。阅读代码过程中遇到一些很好的命名,也遇到一些不好的。当初并没有记录下来,之后才开始记录,有的也找不到出处了。以下高频词汇供有追求的开发者参考stale 陈腐的,陈旧的 用于需要被替换、刷新的资源transport 传输器restricted 限制的exclusive 专一的of 用于Enum 反例 com.netflix.eureka.Version#toEnum org.springframework.data.domain.PageRequest#of(int, int) HystrixCommandAspect.HystrixPointcutType#ofan /a 对 用于简单封装/适配 com.netflix.discovery.shared.transport.EurekaHttpResponse#anEurekaHttpResponse(int)prefer org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean#preferIpAddresspeer 同等 常见于相互注册scalar 标量的,分等级的; ScalarCallable reactorstream的背压支持anyListOf org.mockito.ArgumentMatchers#anyListOforg.mockito.ArgumentMatchers#argThat 整个mockito都非常简洁,简直就是一套DSLparallelism 平行数,bingfa使用accelerate 使…加速reiterate 重复的做capable 能干的manually 手工relevant 相关的切题的noop 等待 无操作deduce 推断canonical 规范的Indicators 指示灯 candidateIndicatorsdeferred 延期的candidate 候选的slurper 吞噬 json slurperestablished 确定的encapsulate 封装 delimited 限定的capable 能干的,能胜任的 AbstractAutowireCapableBeanFactoryintened 故意的additional 附加的,额外的stub 存根 占位符 corresponding 相当的相应的eligible 合适的mechanism 机制material 重要的,物质的,实质的indicator 指示器 监控系统extern 外来的,走读生alternative 供选择的outBound 向外的、外出的assets 资产neutral 中立的mute 哑的 mute the treadabnormally 反常的intern 软禁 用于进行cache put 出处 com.netflix.discovery.util.StringCache#internsolely 单独的唯一的mutually 相互的 eternal 永恒的compose 排版者demand 要求 ...

March 20, 2019 · 1 min · jiezi

Crystal For Rubyists 简体中文

Crystal :一门年轻的编程语言,语法酷似 Ruby,静态类型,编译型,高性能。“给 Ruby 同学准备的 Crystal 入门教程”,这是一本非常值得 Crystal 新人入门的开源免费书籍,译者也是学习途中,内容不多一共 10 个章节,涵盖了这个新语言上手主要的几个方面,如果你是初学者非常建议阅读此书,当然如果你想进阶深入 Crystal 这里的内容就远远不够了,如果你想交流 Ruby China - Crystal 节点应该会是一个不错的地方,希望能有更多的人关注 Crystal。原作者 @sdogruyol ,同时也是 Crystal 人气最高的 Web 框架 kemal 的作者,该书简体中文翻译也经过原作者授权许可。目录 Index第一章:为什么是 Crystal?第二章:安装 Crystal第三章:编写你的第一个 Crystal 程序第四章:创建一个新项目第五章:测试第六章:FizzBuzz 问题第七章:类型和方法重载第八章:并发和管道第九章:宏和元编程第十章:C 绑定阅读地址isaced/crystal_for_rubyists

February 11, 2019 · 1 min · jiezi

Arthas实践--获取到Spring Context,然后为所欲为

背景Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。https://github.com/alibaba/ar…Arthas提供了非常丰富的关于调用拦截的命令,比如 trace/watch/monitor/tt 。但是很多时候我们在排查问题时,需要更多的线索,并不只是函数的参数和返回值。比如在一个spring应用里,想获取到spring context里的其它bean。如果能随意获取到spring bean,那就可以“为所欲为”了。下面介绍如何利用Arthas获取到spring context。Demo: https://github.com/hengyunabc...Arthas快速开始:https://alibaba.github.io/art…使用tt命令获取到spring contextDemo是一个spring mvc应用,请求会经过一系列的spring bean处理,那么我们可以在spring mvc的类里拦截到一些请求。启动Demo: mvn spring-boot:run使用Arthas Attach成功之后,执行tt命令来记录RequestMappingHandlerAdapter#invokeHandlerMethod的请求tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod然后访问一个网页: http://localhost:8080/可以看到Arthas会拦截到这个调用,index是1000,并且打印出:$ watch com.example.demo.Test * ‘params[0]@sss’$ tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethodPress Ctrl+C to abort.Affect(class-cnt:1 , method-cnt:1) cost in 101 ms. INDEX TIMESTAMP COST(ms IS-RE IS-EX OBJECT CLASS METHOD ) T P1000 2019-01-27 16:31 3.66744 true false 0x4465cf70 RequestMappingHandlerAda invokeHandlerMethod :54 pter那么怎样获取到spring context?可以用tt命令的-i参数来指定index,并且用-w参数来执行ognl表达式来获取spring context:$ tt -i 1000 -w ’target.getApplicationContext()’@AnnotationConfigEmbeddedWebApplicationContext[reader=@AnnotatedBeanDefinitionReader[org.springframework.context.annotation.AnnotatedBeanDefinitionReader@35dc90ec],scanner=@ClassPathBeanDefinitionScanner[org.springframework.context.annotation.ClassPathBeanDefinitionScanner@72078a14],annotatedClasses=null,basePackages=null,]Affect(row-cnt:1) cost in 7 ms.从spring context里获取任意bean获取到spring context之后,就可以获取到任意的bean了,比如获取到helloWorldService,并调用getHelloMessage()函数:$ tt -i 1000 -w ’target.getApplicationContext().getBean(“helloWorldService”).getHelloMessage()’@String[Hello World]Affect(row-cnt:1) cost in 5 ms.更多的思路在很多代码里都有static函数或者static holder类,顺滕摸瓜,可以获取很多其它的对象。比如在Dubbo里通过SpringExtensionFactory获取spring context:$ ognl ‘#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, #context.getBean(“userServiceImpl”).findUser(1)’@User[ id=@Integer[1], name=@String[Deanna Borer],]本文作者:横云断岭阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

January 31, 2019 · 1 min · jiezi

Run.rb - 在浏览器中运行 Ruby

“ 也许你体验过 TryRuby,不妨来看看新的 Run.rb。”Run.rb 由 WebAssembly 编译而成,在浏览器中执行 Ruby,作者计划下一步将支持 Ruby 标准库,后续还有 “代码片段” 分享功能,甚至于提供 JS 库让你可以引用其在自己的网站执行 Ruby 代码,可以小小期待一下哦。https://runrb.io/https://github.com/jasoncharn…<Ruby 技术栈> 微信公众号

January 26, 2019 · 1 min · jiezi

Rails 6.0.0 beta1 发布

概要:新增 Action Mailbox 用于邮件处理新增 Action Text 以 Trix editor 为基础的富文本编辑器多数据库支持并行测试默认使用 Webpacker 作为 JS 打包工具Proper Action Cable testing、Action Cable JavaScript 用 ES6 重写Rails 6.0 beta1 要求 Ruby 2.5.0 以上版本支持预告 beta2 将迎来新的 Zeitwerk autoloader 自动加载器Rails 6 的第一个测试版在这里!这绝对是我们非常高兴分享的令人赞叹的新东西。有两个主要的新框架 - Action Mailbox 和 Action Text - 以及两个重要的默认扩展升级,多数据库支持和并行测试。Action Mailbox 将新邮件路由到类似邮箱控制器在 Rails 处理,支持 Amazon SES,Mailgun,Mandrill,Postmark 和 SendGrid。您还可以通过内置的 Exim,Postfix 和 Qmail 插件直接处理入邮件。Action Mailbox 的基础工作由 George Claghorn 和你完成。Action Text 为 Rails 带来了富文本以及其编辑能力,它包括 Trix 编辑器处理从格式化到链接到列表到嵌入图像和图库的链接等所有内容,Trix 编辑器生成的富文本内容保存在自己的 RichText 模型中,该模型与应用中的任何现有的 Active Record 模型相关联。使用 Active Storage 自动存储任何嵌入图像(或附件),并与包含的 RichText 模型相关联。Action Text 的基础工作由 Sam Stephenson,Javan Makhmali 和你完成。新的多数据库支持轻松让单应用程序同时连接多个数据库!您可以执行此操作,因为您希望将某些记录分段到自己的数据库中以进行扩展或隔离,或者因为您正在使用副本数据库进行读/写拆分以提高性能。无论哪种方式,都有一个新的简单的 API,不用了解 Active Record 内部就可实现这一目标。Eileen Uchitelle 和 Aaron Patterson 完成其基础工作。通过并行测试支持,您最终可以利用计算机中的所有核心来更快地运行大型测试套件。每个测试任务都有自己的数据库,并在自己的线程中运行,所以你不会将一个 CPU 跑到100%,而另外 9 个处于闲置状态(你们都有一个10核的iMac Pro,对吧 ????)。欢呼!并行测试支持的基础工作由 Eileen Uchitelle 和 Aaron Patterson 完成。Webpacker 现在是 Rails 默认 JavaScript 打包工具,在新的 app/javascript 目录 。不过,我们仍在使用 Sprockets asset pipeline 处理 CSS 和静态资源。这两者非常完美地集成在一起,提供了高级 JavaScript 功能的最佳权衡,以及其他资源合适的处理方式。这些只是部分品牌的增加,但 Rails 6.0 也包含了一些细微的变化,包括修复和升级。我只向提这一些:Proper Action Cable testing、Action Cable JavaScript 用 ES6 重写,DNS Rebinding 攻击的保护,和 per-environment credentials。此外,Rails 6 现在需要 Ruby 2.5.0+ 支持。您可以查看各个框架 CHANGELOG 文件了解详细信息。最后,你应该注意 Xavier Noria 用于 Ruby 的新 Zeitwerk 代码加载器。它没有集成到 beta1,但从 beta2 开始它将成为 Rails 的新自动加载器。准备好在代码中告别任何挥之不去的 require 或 require_dependency 调用!我们仍然按照我们发布的最终 Rails 6.0 版本的时间表大致按计划进行,因此请参考该计划进行迁移规划,但请通过在 beta1 上测试您的应用程序来帮助我们!我还鼓励任何具有中等 Rails 经验的人使用 beta1 而不是 Rails 5.2.x 系列启动任何新应用程序。Basecamp 已经在生产中运行 Rails 6.0.0.beta1,Shopify 和 GitHub 以及其他人肯定会在此后跟进。这应该是比较稳定的版本。这个版本和所有走向 Rails 6.0 最终的所有版本都由发布经理 RafaelFrança 在 Kasper Timm Hansen 的支持下进行。再次感谢所有致力于使 Rails 更好的人!令人难以置信的是,这些年来我们仍然能够保持这种强劲的改善速度。Rails 从未像现在这样适合帮助最广泛的 Web 开发人员以他们喜欢的方式构建优秀的应用程序。让快乐雄起! ...

January 20, 2019 · 1 min · jiezi

Bundler 2.0 发布

Bundler 团队很高兴地宣布发布 Bundler 2.0 ????!这个版本的重点是删除已经达到其生命周期的 Ruby 和 RubyGems 版本的官方支持,以及其他一些小的突破性变化。以下是 Bundler 2 的所有变动:移除支持 Ruby < 2.3移除支持 RubyGems < 3.0.0默认更换源 github: ‘some/repo’ 开启 https错误/警告现在将打印到 STDERRBundler 现在基于 Lockfile 在版本 1 和 2 之间自动切换

January 17, 2019 · 1 min · jiezi

RubyGems 3.0.2 发布

RubyGems 3.0.2 包含一些小的增强功能和错误修复。要更新到最新的 RubyGems,您可以运行:gem update –system如果您需要升级或降级,请按照 <如何升级/降级 RubyGems 说明> 进行操作。若要手动安装 RubyGems,请参阅 <下载> 页面。次要改进:使用 Bundler-1.17.3。PR #2556 by SHIBATA Hiroshi.修复文档标记描述。 PR #2555 by Luis Sagastume.Bug修复:在没有 rubygems -format-executable 的情况下使用 ruby -program-suffix 时修复测试。PR #2549 by Jeremy Evans.使用 ~> 运算符时修复 Gem::Requirement 相等比较。PR #2554 by Grey Baker.在测试用例中取消设置 SOURCE_DATE_EPOCH。PR #2558 by Sorah Fukumori.修复 SOURCE_DATE_EPOCH。PR #2560 by SHIBATA Hiroshi.SHA256 Checksums:rubygems-3.0.2.tgz7bacd882b258a4efbfdc1e56f34f85ce0ac2e83f1c41dbc9c8e1ac53021366d2rubygems-3.0.2.zip3181e37b7add41353e0c82776e82c5fbd17fa8ac6dcedbc6d2ed2693f4c13003rubygems-update-3.0.2.gem311dbf1f1d62d59c861be213b03fd326bde81da7f560f89ea170610e013cdbc6

January 17, 2019 · 1 min · jiezi

如何在 Ruby 2.6 中开启 JIT?

在命令行或 $RUBYOPT 环境变量中指定 –jit 参数开启 JIT:ruby –jit test.rbruby –jit-verbose=1 test.rbRUBYOPT="–jit" rails serverRUBYOPT="–jit-verbose=1" rails serverRUBYOPT="–jit" sidekiq

January 17, 2019 · 1 min · jiezi

Rails 6.0 发布时间表

我们在实现 Rails 6.0 的愿景上取得了足够的进展,因此分享我们的发布时间表是有意义的。关键词是 “进取(Aspirational)”,我们觉得比 “发布(Release)” 更为重要。其实软件很少按时发布,我们有过很多理想发布日期,但总是会错过。但如果乐观主义不是开源乐趣的一部分,那么我们为了啥?所以,这是我们目前希望看到的时间表:1月15日:Beta 1,我们将为此版本合并两个新框架,Action Mailbox 和 Action Text。2月1日:Beta 2,我们将确保包含任何所有重大改进。3月1日:RC 1 (Release Candidate),我们在这里完善功能。4月1日:RC 2 (Release Candidate), 这里准备好发布。4月30日:最终发布,在 RailsConf 2019 上庆祝发布 Rails 6.0 !这样规划看起来还不错吧?像一些认真的工程师实现了一些严肃的工程学来保证按计划发展,而不仅仅是一群软件作家在凭空策划他们想要的。值得注意的是:Rails 6.0 将需要 Ruby 2.5+!所以你最好提前升级好 Ruby 版本来做好准备迎接 Rails。另请注意,在 Rails 6.0 发布之后,只有 Rails 6.x 和 Rails 5.2.x 可以保证 Rails 核心同时接收主要 (major) 和次要 (minor) 安全修复。(一如既往,我们可能仍可以选择进一步提供补救措施,但不能保证)。与往常一样,如果您可以承担高风险(遇到 BUG 也没有被炒鱿鱼的风险),请帮助我们通过为新应用程序和现有应用程序运行 rails/master 分支来实现这一目标。Basecamp 3 已在生产中运行 rails/master,所以其实主分支也工作良好!我们 Rails 6.0 发布管理人将是 Rafael França,Kasper Timm Hansen 候补!????给 Rails 比心 666!????????

January 17, 2019 · 1 min · jiezi

Ruby 2.6.0 发布

Ruby 2.6.0 正式版已经发布,引入了许多新功能和性能改进,最值得关注的有亮点:新的 JIT 编译器RubyVM::AbstractSyntaxTree 模块JIT [实验]Ruby 2.6 引入了 JIT (Just-in-time) 编译器实现。JIT 编译器旨在提高 Ruby 性能。与其他语言的普通 JIT 编译器不同,Ruby 的 JIT 编译器以一种独特的方式进行 JIT 编译,它先将 Ruby 编译成 C 代码,然后通过生成通用的 C 编译器过程 (compiler process) 来生成原生机器码。详情可查阅 Vladimir Makarov 的 MJIT 组织。要启用 JIT 编译器,在命令行或 $RUBYOPT 环境变量中指定 –jit 参数即可。在一个名叫 Optcarrot 的 CPU 密集计算基准测试中,Ruby 2.6 与 Ruby 2.5 相比,性能提高了 1.7 倍。不过目前仍然处于试验阶段,详见 Ruby 2.6 JIT - 进程与未来。请保持对 Ruby 新时代性能的关注。RubyVM::AbstractSyntaxTree [实验]Ruby 2.6 引入了 RubyVM::AbstractSyntaxTree 模块,此模块向后兼容性不做保证。此模块提供一个 parse 方法,传入 Ruby 代码字符串,返回 AST(抽象语法树)节点。而 parse_file 方法则接受一个 Ruby 代码文件作为参数,返回 AST 节点。同时引入了 RubyVM::AbstractSyntaxTree::Node 类,你可以从 Node 对象中获取位置信息和子节点。此功能尚处于实验性质。其它新特性Kernel#yield_self 添加新别名 then。[Feature #14594]常量名现在可以以非 ASCII 大写字母开头。[Feature #13770]无限范围 [Feature #12912]引入了无限范围 (1..)。这个范围没有终点,以下是使用场景的举例。ary[1..] # 等价于 ary[1..-1] 而不需要魔法 -1(1..).each {|index| … } # 从 1 开始无限循环ary.zip(1..) {|elem, index| … } # ary.each.with_index(1) { … }新增 Enumerable#chain 与 Enumerator#+ [Feature #15144]为 Proc 和 Method 新增了函数构造操作符 << 与 >>。 [Feature #6284]f = proc{|x| x + 2}g = proc{|x| x * 3}(f << g).call(3) # -> 11; identical to f(g(3))(f >> g).call(3) # -> 15; identical to g(f(3))新增 Binding#source_location。[Feature #14230]此方法以一个二元组数组 FILE 和 LINE 的形式返回 binding 的源代码路径。传统上,这可以通过执行 eval("[FILE, LINE]", binding) 来获得相同的数据。但我们计划改变这一行为让 Kernel#eval 忽略 binding 的源代码路径 [Bug #4352]。所以,用户需要通过新加入的方法来替代之前的 Kernel#eval。增加 :exception 选项,以让 Kernel.#system 抛出错误而不是返回 false。[Feature #14386]新增 oneshot 模式 [Feature #15022]此模式检查「每一行代码是否都至少被执行一次」,而不是「每行代码被执行了几次」。每行代码的 hook 至多被调用一次,并会在调用后将 hook 标识移除。换句话说,移除后的代码运行将没有额外的性能开销。为 Coverage.start 方法新增 :oneshot_lines 关键字参数。为 Coverage.result 方法新增 :stop 和 :clear 关键字参数。如果 clear 被设置为 true,它会清空计数器。如果 stop 被设置为 true,它会禁用覆盖测量。新增 Coverage.line_stub,其为从源代码新建代码覆盖存根(stub)提供了一个简单的帮助函数。FileUtils#cp_lr。[Feature #4189]性能提升由于移除了对 $SAFE 临时赋值的支持,提升 Proc#call 的速度。[Feature #14318]通过 lc_fizzbuzz 多次使用 Proc#call 的 benchmark 我们测量到了 1.4 倍性能提升 [Bug #10212]。提升了当 block 是代码块参数时 block.call 的性能。[Feature #14330]通过与 Ruby 2.5 中引入的提升代码块传递的性能的方法结合,Ruby 2.6 进一步提升了传递代码块调用时的性能。通过 micro-benchmark 测试有 2.6 倍性能提升。[Feature #14045]引入了瞬态堆 (theap)。 [Bug #14858] [Feature #14989]瞬态堆是用于管理指向特定类(Array、Hash、Object 和 Struct)短生命周期内存对象的堆。例如,创建小而短生命周期的哈希对象的速度提升到了 2 倍快。根据 rdoc benchmark,我们观察到了 6% 到 7% 的性能提升。协程采用了原生实现(arm32、arm64、ppc64le、win32、win64、x86、amd64)显著提升了 Fiber 的性能。 [Feature #14739]Fiber.yield 与 Fiber#resume 方法在 64 位 Linux 上提升了 5 倍性能。对于使用 Fiber 密集的程序,约有最高 5% 的性能提升。其它自 2.5 以来值得注意的新特性$SAFE 成为了进程全局状态,我们可以再次将其设为 0。[Feature #14250]不再建议将 safe_level 参数传递给 ERB.new 的行为。trim_mode 和 eoutvar 参数被转换成了关键词参数。[Feature #14256]升级支持的 Unicode 版本至 11。我们计划在未来 Ruby 2.6 的小更新中升级至 12 和 12.1。其将引入新的日本年号。合并 RubyGems 3.0.1,–ri 和 –rdoc 选项已被移除。请使用 –document 和 –no-document 选项来替代他们。合并 Bundler 作为默认 gem 安装。不含 rescue 的 else 现在会引起语法错误。实验性更多详情见 NEWS 或 提交日志 以查看详情。随着这些变动,自 Ruby 2.5.0 已发生了 6437 个文件变更,231471 行新增(+),98498 行删除(-)!圣诞快乐!享受你 Ruby 2.6 的编程之旅吧!原文连接:https://www.ruby-lang.org/en/… ...

January 17, 2019 · 2 min · jiezi

为什么我们要使用 RVM / Bundler ?

作为一名 iOS 工程师,cocoapods 是我们所不会陌生的。然而在我们的日常开发中,编写 cocoapods 的 Ruby 语言我们可能不甚了解,更不要说 Bundler 以及 RVM 了。因此,当我们遇到一些 Ruby 环境相关的问题时,可能完全不知道发生了什么。如果恰好你对这两个工具做了什么感到好奇,那么,在这篇文章中,我会尽量由浅入深的去说明 RVM / Bundler 的原理和作用,帮助大家对 Ruby 的环境管理有一个更加深入的理解。TLDR使用 RVM 来安装 Rubygem install rubygems-Bundler && gem regenerate_binstubs 可以让你免去每次都要在 pod install 之前添加 bundle exec 的痛苦我们所使用的 Ruby 从哪里来?我们都知道,macOS 是自带 Ruby 的。也就是说,当我们拿到一台新的 MacBook Pro,进入系统,打开终端执行 whereis ruby,我们会得到 /usr/bin/ruby 这样的结果。在目前的 macOS 10.14 版本中,系统自带的 Ruby 版本为 2.3.7。为什么需要使用 RVM?在没有安装 RVM 或者 rbenv 这样的工具以前,大家在执行 gem install cococapods 这一行命令的时候一定会遇到这样的报错:You don’t have write permissions for the /Library/Ruby/Gems/2.3.0 directory为什么会出现这样的错误?因为 gem 作为 Ruby 默认的包管理器,会将所有下载的 gem 安装在某个特定的目录下,我们暂且称呼这个目录为 Gem Path ,对于系统的 Ruby 来说,这个目录就是 /Library/Ruby/Gems/2.3.0,这是一个需要启用 sudo 才能写入的目录。这也就导致我们在每次 gem install 的时候都需要在命令之前增加 sudo 才能让命令正确执行。为了解决这个问题,我们需要让 Gem Path 指向一个我们拥有写权限的目录。比较简单直接的办法就是我们利用 homebrew 去安装一个新的 Ruby。似乎很完美,但有个问题:我们如何约束大家所有人都使用同样版本的 Ruby 呢?答案是使用 Ruby 的版本管理工具。以 RVM 为例,当你安装 RVM 以后,你在命令行中执行的每一个 cd 命令其实都被 RVM 所替换了。RVM 会在每一次切换目录后检查当前目录中是否有 .ruby-version 文件,如果有,就检查当前使用的 Ruby 是否是文件中指定的版本。如果不是,他会给出类似 Required ruby-x.x.x is not installed 这样的警告。在我司工程的早期阶段,我们除了使用 cocoapods,还需要使用 Ruby 编写一些打包和发布的脚本,而当时系统提供的 Ruby 版本还比较低(2.0.0),开发起来不太方便,而利用 RVM ,我们不仅可以方便的安装一个新版本的 Ruby,还可以利用 .ruby-version 来保证大家可以使用相同版本的 Ruby(尽管只是一个比较弱的约束)。相信到这里,大家已经能够理解,在我们的项目中使用 RVM 是很有必要的。我们接下来看第二个问题:为什么要用 Bundler?为什么要使用 Bundler?为了回答这个问题,我们需要先把目光转向 gem,回顾一下 gem 诞生时要解决的问题。gem 所要解决的问题在 Ruby 中,如果你想使用另外一个 Ruby 文件中的内容,你需要使用 require 关键字来加载另外一个 Ruby 文件中的内容。require 会在 Ruby 预设的 $LOAD_PATH 中去查找对应的文件。你可以通过执行 ruby -e ‘puts $LOAD_PATH’ 来看看当前 Ruby 中的 $LOAD_PATH 都有什么内容。例如如果你写了一个简单的 Ruby 脚本:require ‘foo’当执行到 require ‘foo’ 这一行时, Ruby 就会在 $LOAD_PATH 中出现的所有目录下去查找是否有一个叫做 foo.rb 的文件。如果有,就去加载这个文件的内容。如果在所有的 $LOAD_PATH 中都没有找到这样的一个文件,Ruby 解释器就会抛出异常。异常通常长这个样子:LoadError - cannot load such file – foo在没有 gem 以前,如果你想用别人已经写好的 Ruby 脚本,就需要手动把这些脚本下载下来,放到 $LOAD_PATH 中的某个目录下,然后你才能在你的脚本中正确的使用别人的脚本文件。这样的代码分发过程是非常原始而繁琐的。为了解决这个问题,gem 横空出世,提供了这样的一个脚本分发解决方案:首先用 gemspec 来描述你即将分发的脚本的元信息利用 gem 提供的命令,将脚本打包成一个 .gem 文件(.gem 实质就是一个 POSIX tar archive),然后上传到服务器当有其他人想要使用你的脚本时,执行 gem install 即可前面的内容很好理解,我们来着重看一下执行 gem install 之后发生了什么。当你执行 gem install foo 的时候,gem 会帮你把 foo.gem 下载下来,解压缩,放到一个目录下。一般这个目录都是我们前面提到 Gem Path 的子目录,我们这里暂时称其为 Gems Install Path。如果 foo 的 gemspec 中声明了对其他 gem 的依赖,gem install foo 还会帮你把 foo 所依赖的 gem 下载下来。除此之外,在你安装了 gem 后,gem 就会修改 Ruby 中 require 的实现,使得 require 在执行的时候,除了 $LOAD_PATH,还会在 Gems Install Path 中查找文件(你可以通过执行 gem env | grep -A2 ‘GEM PATHS’ 找到你的 gem 所安装的路径,GEMS INSTALL PATH 就在这个目录的 gems 子目录下)。当 gem 在 GEMS INSTALL PATH 中找到对应文件后,就会把这个路径加入到 $LOAD_PATH 中,然后调用 Ruby 本来的 require。此时由于 $LOAD_PATH 中增加了新的路径,require 就可以正确的加载到你所安装的 gem 的对应文件了。这里我们可以做一个小实验,找一个没有 Gemfile 的目录执行 irb,然后依次输入注释以外的内容:old_load_path = $LOAD_PATH.duprequire ‘cocoapods’new_load_path = $LOAD_PATH.dup# 执行下面的代码可以看看 LOAD_PATH 数量的变化"new: #{new_load_path.count} old: #{old_load_path.count}"# 执行下面的代码可以看看 LOAD_PATH 到底变了什么。你会看到 cocoapods 以及他的依赖库所在的目录new_load_path - old_load_path至此,gem 已经完美解决了分发 Ruby 脚本的问题。当你想要使用任何一个别人已经提供好的 gem 的时候,只需要简单输入 gem install,你的脚本就可以快乐的使用这个 gem 了。gem 所带来的新的问题到目前为止,一切似乎很美好,但是随着 Ruby 应用于各种大型项目以后,Ruby 的开发者们发现了新的问题:当你的项目依赖了十几个 gem 后,新接手的人的配置环境时需要输入十几次 gem install 才能正确的配置好环境。这样的事情开发者们当然不能忍,于是他们开始使用各种脚本文件将这个过程简化,这些脚本可能叫做 setup.sh ,他们的内容一般是这样的:gem install foogem install bar在这里我们暂时可以称呼类似这种 setup.sh 文件为 Gem List 文件,因为他就是一个装满了所有你需要安装的 Gem 的 List ????????????。当 Ruby 的开发者们解决了批量安装 gem 的问题以后,他们又发现了新的问题:多版本环境不隔离。什么意思?我们来举个例子说明一下这个问题。假如你是一名 Ruby 开发者,你维护着一个你的项目 A,在这个项目中你使用了 2.0.0 版本的 foo。一段时间后,你又开始接手维护另外一个项目 B,不幸的是,这个项目最开始使用的 foo 的版本是 3.0.0。于是令人头疼的事情发生了:当你配置好了项目 B 的环境以后,你的机器上就会同时存在两个版本的 foo 的 gem。同时你会发现,你的项目 A 跑不起来了,因为你在运行项目 A 时,gem 默认会去找多个版本中最新的版本,于是在项目 A 中你用到了 3.0.0 版本的 foo 而不是 2.0.0 版本。于是各种有趣但无奈的事情发生了:你的项目在你本地可能好好的,但是在服务器上就是不对。你查了好几天,发现是因为服务器上的另外一个项目装了一个高版本的 gem,导致服务器上的环境根本没法跑你的项目。你痛苦,你绝望,但你又无能为力 ????????????。即便你只维护一个项目,由于你的 Gem List 文件中并没有指定 gem 的版本号,所以很有可能一周前利用这个 Gem List 文件安装出来的 gem 和一周后安装出来的完全不同。以至于很久以前 Ruby 开发者们都会开玩笑:“你好啊新人,这是一台新的电脑,我们希望你能花一周把项目的依赖配置好,如果一切顺利的话”Bundler 的解决方案为了解决上面使用 gem 所产生的这些问题,Bundler 横空出世,提供给开发者两个救命一般的命令:bundle installbundle execbundle install 为我们提供了统一安装多个 gem 的便捷方式。在执行 bundle install 后,Bundler 会将他所使用的 Gem List 文件 —— Gemfile 中声明的 gem 全部安装,同时将此次决议的最终版本号保存在 Gemfile.lock 中,保证不同时刻不同机器执行 bundle install 能够安装同样版本的 gem。bundle exec 则替我们解决了多版本环境不隔离的问题。当你执行 bundle exec 的时候,Bundler 会把 $LOAD_PATH 中不相干的那些 gem 的路径全都去掉,然后读取 Gemfile.lock 中的 gem 版本(如果没有 Gemfile.lock 会决议版本后创建一个 Gemfile.lock),保证 $LOAD_PATH 中只存在 Gemfile.lock 中已经固定版本的 gem 的路径。你可以执行一下下面两行代码,看看 $LOAD_PATH 的区别:bundle exec ruby -e ‘puts $LOAD_PATH’ruby -e ‘puts $LOAD_PATH’Bundler 带来的新问题至此,Bundler 已经很好的解决了 gem 安装和环境隔离的问题了,但是 Bundler 也带来了新的麻烦:每次我们执行 Ruby 相关的命令之前都要重复的输入 bundle exec ????????♂️????????♂️????????♂️。还好 Ruby 的开发者们都很懒,他们开发了一个新的 gem —— rubygems-Bundler 来解决这个问题。当你安装这个 gem 以后,只要执行一次 gem regenerate_binstubs,rubygems-Bundler 就会帮你在任何 gem 安装的命令行执行之前检查一下当前目录以及父目录是否存在 Gemfile。如果存在,就自动帮你的命令行之前加上 bundle exec 再执行。完美的解决了这个问题。小提示:1.11.0 以上版本的 RVM 在安装 Ruby 时,默认会安装 rubygems-Bundler。你可以通过 gem list rubygems-Bundler 来检查自己是否安装了这个 gem。如果你用 homebrew 安装 Ruby,则不会享受到这个隐藏的福利。扩展练习:来看看一些常见的报错,现在你知道发生了什么了么?练习一LoadError - cannot load such file – macho练习二Could not find proper version of cocoapods (1.1.1) in any of the sourcesRun bundle install to install missing gems.练习三Required ruby-2.3.7 is not installed.To install do: ‘rvm install “ruby-2.3.7”‘参考Rbenv — How it worksrbenv vs rvmA Ruby workflow with RVM and BundlerBundler: The best way to manage a Ruby application’s gemsHow Bundler Works: A History of Ruby Dependency ManagementA History of Bundles: 2010 to 2017Understanding ruby load, require, gems, Bundler and rails autoloading from the bottom upHow does Bundler work, anyway? ...

December 22, 2018 · 3 min · jiezi

8支团队正在努力构建下一代Ethereum

“我们不想在构建 Ethereum 2.0时重新造轮子。”谈到开发人员为 Ethereum 区块链进行两个独立的升级(一个称为 Ethereum 2.0,另一个称为 Ethereum 1x)所作出的补充努力,劳尔·乔丹坚持认为,在较短的时间内将升级包括在 Ethereum 1x 中,将对正在进行的 Ethereum 2.0研究有好处。Jordan是当前为ethereum 2.0构建软件客户端的八个不同开发团队之一的共同领导。(作为背景,客户端通常是用不同的编程语言编写的软件实现,用户部署这些语言以连接到以太网并参与以太网。)Jordan对CoinDesk说,保持在以太坊1x内提出的“增量增强”不影响主链的长期路线图:“我认为这两个组相当正交,但我们至少必须了解每个组正在执行什么。”目前,这两种升级的技术指导方针也称为规范,仍在进行中。在以太开发人员中仅在最近几周认真讨论过ethereum 1x之后,它打算成为侧重于对当前以太网络的增强的中间升级。另一方面,Ethereum 2.0具有一个更雄心勃勃的议程,该议程可追溯到2014年,包括对连锁平台的根本性改变。在以太坊2.0的早期项目名称为Serenity这众所周知,目前的规范可以概括为三个主要组件的组合:从当前被称为工作量证明(PoW)的能源密集型共识协议切换到PoS。一种称为分片的网络范围扩展解决方案的实现。EVM(负责在块链上部署去中心化式应用程序(dapps)的引擎)的改进,可以在称为 WebAssembly(WASM)的新编程代码上运行。尽管这些组件之一——即ethereum对WASM的实现——有可能在早期的ethereum 1x路线图中进行测试,但是构建ethereum 2.0的大部分工作仍然作为一个单独的项目进行。这项工作正在由分布在全球的八个不同小组进行。1.ChainSafe SystemsChainSafe Systems总部位于多伦多,是一家区块链研发公司,为许多不同的基于以太坊的项目提供咨询服务,包括Shyft,Bunz,Aion和Polymath。ChainSafe的项目负责人Mikerah Quintyne-Collins告诉CoinDesk,他希望“做出更大的贡献”。“对我而言,开发以太坊2.0是我在互联网未来的标志。”被称为Lodestar的Collins和她的团队目前正在构建一个用Javascript编写的ethereum 2.0客户端——这是Web开发的主要编程语言。通过以太坊基金会拨款计划的私人资助并寻求额外支持,据柯林斯称,Lodestar设想“将一大批网络开发者带到以太坊生态系统”。“所有这些编程语言都有自己的社区。整个社区可能不是都想做出贡献,但它们足够大,以至它的一部分需要贡献并建立在以太坊之上,“柯林斯说。柯林斯甚至怀疑开发工作有助于其他区块链平台的进展,他强调说,在她看来,以太坊2.0并不是要确保以太坊的未来成为“主要区块链”,他说:“这不是关于谁将成为下一件大事件。它更多的是尝试使这些系统工作。匆匆忙忙赶上另一个假想的以太坊杀手,就无法实现这个目标。“2.PegaSys“我们的目标是将企业带入主网。我们希望通过创建更容易被企业采用的软件来实现这一目标。“这就是区块链协议工程组PegaSys的战略和业务开发负责人Faisal Khan。由Consensys全力支持——由ethereum联合创始人Joseph Lubin领导的以太坊自称的“风险投资制作工作室”——PegaSys正在为现有的以太坊Java客户端Pantheon构建以太坊2.0规范。Pantheon最近在布拉格的以太坊开发商聚会上亮相,使用一种名为Apache 2.0的开源软件许可证,使企业能够在以太坊平台上构建产品,从而将其知识产权货币化。Khan在谈到CoinDesk时强调,扩展对以太坊2.0规范的支持意味着与以太坊基金会研究人员和其他客户开发团队密切合作。“有很多接触点。每周都有一个电话。有一个研究论坛,ETH研究。有一个Gitter频道。沟通非常频繁。显然,有加密Twitter。任何ethereum 2.0团队和基金会之间的谈话都非常丰富。“ Khan说。除此之外,ethereum 2.0将在平台上启动一个新的“网络效应循环,dapp开发和用户增长”,Khan重申,目前该项目最大的需求是“更多人参与”。3.HarmonyHarmony是去年10月推出的,它是以太坊最初的Java客户端,以前由一群名为Ether Camp的独立开发人员维护。现在简称为Harmony团队,这些开发团队最近通过以太坊基金会拨款计划获得了90,000美元,以建立以太坊2.0的规范。由以太坊基金会资助,Harmony预计将继续作为以企业为中心的Pantheon的替代Java客户端运行。Harmony与Pantheon的Apache 2.0软件许可证分开,根据通用公共许可证(GPL)运营,旨在确保代码的任何实现仍为免费软件,如官方GPL指南中所述。Harmony开发商Mikhail Kalinin告诉CoinDesk:“将建设新的互联网”推向市场。“最大的挑战是保持研究领域的所有变化,并跟踪每项工作的进展。它的范围很广。“4.Parity TechnologiesParity Technologies是由以前的以太坊基金会首席安全官Jutta Steiner共同创立的,是一家区块链基础设施公司,负责维护当今平台上第二大最受欢迎的以太坊客户端。名为Parity Ethereum的客户名称被自称为“最快,最先进的以太坊客户端。”。正如官方Wiki页面上详细介绍的那样,Parity Ethereum在Rust中编程,专为“关键任务型应用”而构建,意味着同步速度快速并且有最大的正常操作运行时间。对于在组织内部建立以太坊2.0客户的重新努力,Parity公共事务负责人Peter Mauric解释说,以太坊2.0实际上是以太坊区块链的准备生产production-ready版本。他告诉CoinDesk:“从广义上讲,我相信现在存在的以太坊已经处于测试阶段……以太坊2.0正在从几年前Vitalik推出的这个实验性项目转向更具生产能力的区块链协议。”5.Prysmatic Labs在编程语言Go中首次实现了ethereum 2.0,Prysmatic Labs于今年1月推出,旨在帮助以太坊区块链实现可扩展性。谈到这一努力,Prysmatic Labs Raul Jordan的团队负责人告诉CoinDesk:“以太坊2.0系统可以根据全球计算机的需求进行扩展……这意味着它将能够处理现实世界必需品的负载……从简单的东西到建立在它之上的完全庞大的金融系统“。名为Prysm的ethereum 2.0客户端将作为区块链目前最流行的客户端实现的对应物,也就是用Go编写的Geth。Jordan没有将客户端开发视为一个竞争过程,他强调,在以太坊区块链中,多种不同的客户端实施是非常必要的。“原因是当你在开发像这样的区块链时,你需要尽可能多的去中心化的实现。因此,例如,如果以太坊区块链在Prysm上运行并且Prysm中存在错误,则每个人都可以切换到另一个客户端。这样你有其他选择。“Jordan说。尽管如此,Jordan认为比较强调对建设“公益事业”的努力,对开发工作的支持主要来自以太坊基金会和其他私人捐助者的捐赠。迄今为止,Jordan告诉CoinDesk,建立一个以太坊2.0客户端的最大挑战之一是确保工作与“研究密切相关”。他解释说:“每周,每天都有新的想法出现,我们基本上建立在不断变化的规范上……所以我认为最大的挑战之一是开发之间的多任务处理,同时也确保研究总体是好的,这样我们可以评估前进的选择。“6.Sigma PrimeSigma Prime成立于2016年,是一家信息安全和区块链技术咨询公司。最近从以太坊基金会获得了150,000美元的资助,该公司正在建立一个名为Lighthouse的ethereum 2.0客户端,用编程语言Rust编写。作为第二个如同Parity一样采用Rust客户端,Sigma Prime Paul Hauner的联合创始人告诉CoinDesk他并不认为这两种产品之间存在“任何根本差异”。Hauner解释说,强调重复工作实际上是“区块链中真正需要的”。“软件有漏洞。所以,如果每个人都运行相同的客户端并且存在错误,那么每个人都会失败。如果有这种多样化的客户端,他们很可能会有不同的错误。一个客户端被拒绝这很好。网络的其余部分仍然保持不变。“谈到以太坊2.0升级的重要性,Hauner补充说,不仅用户会注意到“每秒交易量的大幅增加”,而且还会在股权证明共识协议下获得显着的环境收益。“就个人而言,我觉得人们会使用它,它会起作用。就实际技术而言,我没有任何担心是否可行。这个时间点需要设防吗?绝对不。它尚未建成。“Hauner说。7.StatusStatus是一个消息传递平台和移动浏览器,专门用于吸引以太坊区块链上的用户,Status公布了今年8月用编程语言Nim编写的名为Nimbus的ethereum 2.0客户端的很活跃的开发项目。部分由以太坊基金会提供的500,000美元赠款资助,该官方网站上强调的项目目标是“通过优化Nimbus在资源受限设备上的性能来推动大量采用以太坊”。因此,利用运行Nim代码的轻量级功能,Nimbus有望成为以太坊首款将智能手机设备和其他手持电子设备连接到区块链平台的移动客户端。该项目有八个核心贡献者,几个月前在博客文章中突出显示,它正在寻找额外的开发人员支持。Status Jacek Sieka的研究开发负责人写道:“我们完全是开源的,并鼓励那些想要参与的人做出贡献。”此外,在谈到CoinDesk时,Sieka补充说,他预计ethereum 2.0的开发工作将分多个阶段推出,其中一个可疑的测试网络将在明年的某个时间推出,称为beacon信标链。“据说这项研究正在进行中,任何时间表都在不断变化,但从终端用户的角度来看,一年,两年是期望ethereum 2.0普遍有用的合理时间表。”Sieka说。8.Trinity最后但同样重要的是,Trinity是一个用编程语言Python编写的当前以太坊客户端。作为以太坊的新标准Python实现,Trinity将最新代码升级为最初由ethereum Vitalik Buterin创始人撰写的休眠PyEthApp。今年已经在初步的alpha阶段推出,Trinity由包括Merriam在内的六位开发人员组成,除了其中一人外都与以太坊基金会合作。预计也将为以太坊2.0规范提供支持,Trinity Piper Merriam的首席架构师强调,“在研究和实现之间的边界”开发是他最擅长的。“相对理论研究来说我更喜欢理论的应用。协议研究很简洁,但实施协议更符合我的擅长。“Merriam说。Merriam认为,这项工作实际上“只是刚刚起步”,将以太坊2.0客户端开发的过程比作“拼图”。需要解决很多难题,所有八个团队的集体工作预计将相互加强,并确保以太坊区块链的未来。Merriam告诉CoinDesk:“通过对任何协议进行多次实现……我们可以确信协议的书面定义是准确的并且个别客户端是正确的。”======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文8支团队正在努力构建下一代Ethereum

December 17, 2018 · 1 min · jiezi

Rails Docker开发环境配置

rails mysql redis 的开发环境首先构建自己的镜像Dockerfile.developmentFROM ruby:2.3.4-slimRUN apt-get update && apt-get install -y \ build-essential \ nodejs \ libmysqlclient-devRUN mkdir -p /appWORKDIR /appCOPY Gemfile Gemfile.lock /app/RUN gem install bundler && bundle install –jobs 20 –retry 5COPY . /appEXPOSE 4000ENTRYPOINT [“bundle”, “exec”]CMD [“rails”, “server”, “-b”, “0.0.0.0”, “-p”, “4000”]docker-compose.yml 配置version: ‘3’services: mysql: image: mysql:5.7.17 command: –sql-mode="" restart: always volumes: - ./mysql_data/:/var/lib/mysql ports: - “3306:3306” environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: shiji_development redis: image: redis command: redis-server volumes: - ./redis_data:/data ports: - 6379:6379 web: build: context: . dockerfile: Dockerfile.development command: bash -c “rm -f tmp/pids/server.pid && bundle exec rails s -p 4000 -b ‘0.0.0.0’” stdin_open: true tty: true volumes: - .:/app ports: - “4000:4000” depends_on: - mysql - redis ...

October 26, 2018 · 1 min · jiezi