目录
一、什么是kafka?
1.使用消息队列的好处?
2.典型应用:日志系统架构模型
二、架构
1.Kafka的一些重要相关概念
2.工作流程
3.副本原理
4.生产者
4.1.为什么分区可以水平扩展?
4.2.分区策略
1.轮询策略(Round-robin)
2.随机策略(Randomness)
3.按消息键保序策略(Key-ordering)
4.默认分区策略
5.消费者
5.1 消费方式
5.2 分区分配策略
5.2.1 Range(默认策略)
5.2.2 RoundRobin
6.数据可靠性保证
6.1 副本数据同步策略
6.2 ACK应答机制
参考
一、什么是kafka? kafka本质上是一个消息队列MQ(Message Queue),用做数据流转。
1.使用消息队列的好处? 1.1、解耦:允许独立扩展或修改队列两头的处理过程;
1.2、可恢复性:即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理;
1.3、缓冲:解决生产消息和消费消息速度不一致的问题; 1.4、灵活、峰值处理能力:不会因为突发的超负荷请求而完全崩溃,消息队列能使关键组件顶住突发的访问压力;
1.5、异步通信:允许用户将消息放入队列,但不立即处理它。
2.典型应用:日志系统架构模型 v1.日志系统架构模型| ProcessOn免费在线作图,在线流程图,在线思维导图
Logstash是一个开源数据收集引擎,具有实时管道功能。Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地。
Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。
二、架构 注意:因为篇幅原因,没有画zookeeper,broker都是由zookeeper管理。 Kafka 存储的消息来自任意多被称为 Producer 生产者的进程。数据从而可以被发布到不同的 Topic 主题下的不同 Partition 分区。
在一个分区内,这些消息被索引并连同时间戳存储在一起。其它被称为 Consumer 消费者的进程可以从分区订阅消息。
Kafka 运行在一个由一台或多台服务器组成的集群上,并且分区可以跨集群结点分布。
1.Kafka的一些重要相关概念 Producer:消息生产者,向 Kafka Broker 发消息的客户端。
1. **公司背景**:仲利国际融资租赁有限公司成立于2005年,是台湾地区租赁业龙头中租控股在中国大陆投资设立的融资租赁公司。截至2021年,公司已开设52家分公司及8个专业金融服务事业部门,并设有3家子公司。累计业务投放额近2000亿人民币,服务企业超60000家 。
2. **校招岗位**:公司提供的校招岗位包括融资租赁客户经理、风险控制岗等,涉及多个部门,如供货商营销业务部、营建运输金融业务部、汽车租赁业务部等 。
3. **任职要求**:对于校招岗位,公司通常要求应聘者具备大学本科及以上学历,相关专业优先,具备良好的沟通能力、团队合作精神以及一定的金融风险和财务分析能力 。
4. **招聘流程**:校招流程可能包括在线测评、面试等环节。例如,有应聘者提到在线测评使用的是阿里录用Java工程师的题目,面试则是由部门主管进行 。
5. **面试经验分享**:根据面试者的分享,面试难度通常被认为是普通难度,面试过程可能包括自我介绍、对租赁业务的了解、家庭情况等常规问题。有的面试还包括了笔试环节,考题涉及财务相关知识 。
6. **招聘信息获取**:对于感兴趣的应聘者,可以通过公司官网、前程无忧、智联招聘等渠道获取更多招聘信息,并进行简历投递 。
Python 之 Click 介绍及简单使用 引言 在Python编程中,编写命令行接口(CLI)是许多应用程序的重要组成部分。而click库作为Python中一个强大的第三方库,极大地简化了这一过程。click不仅提供了创建命令行工具的简便方法,还保证了代码的易读性和可扩展性。本文将介绍click的基本概念,并通过几个简单的例子来展示如何使用它。
Click概述 click是一个Python包,用于创建命令行接口。它旨在让编写复杂的命令行接口变得简单且易于扩展。click的设计哲学包括:
简洁性:通过简洁的API减少代码量。嵌套命令:支持命令的嵌套,从而创建结构化的命令行工具。参数类型:提供多种参数类型,自动处理类型转换和验证。文档生成:自动从命令函数生成帮助文档。 安装Click 在开始之前,你需要确保已经安装了click。可以通过pip轻松安装:
pip install click 基本使用 创建一个基本的命令 首先,我们来看一个创建基本命令的例子:
import click @click.command() @click.option('--count', default=1, help='Number of greetings.') def hello(count): """Simple program that greets NAME for a total of COUNT times.""" for x in range(count): click.echo('Hello World!') if __name__ == '__main__': hello() 在这个例子中,我们定义了一个hello命令,它接受一个--count选项(默认值为1)。命令的主体是一个简单的循环,用于打印“Hello World!”指定次数。
运行命令 将上述代码保存为hello.py,然后通过命令行运行:
python hello.py --count 3 输出将会是:
Hello World! Hello World! Hello World! 嵌套命令 click还支持命令的嵌套,这对于创建具有多个子命令的复杂CLI工具非常有用。
import click @click.group() def cli(): pass @cli.
目录
前言:C++——为弥补C缺陷而生的语言
C++的输入与输出 1.引子:C++的第一个程序
2.C++的输入与输出
3.命名空间
疑难解答
1.对输入输出流的一个基本概念
2.从流当中存入及提取数据
前言:C++——为弥补C缺陷而生的语言 C++起源于 1979 年,当时 Bjarne Stroustrup 在贝尔实验室工作,面对复杂软件开发任务,他感到 C 语言在表达能力、可维护性和可扩展性方面存在不足。
1983 年,Bjarne Stroustrup 在 C 语言基础上添加面向对象编程特性,设计出 C++雏形,有了类、封装、继承等核心概念。因此,C++是兼容了C语言的(用过Dev-C++的同学应该不难理解,文件后缀明明是.cpp却可以编译C语言)。
C++的标准化工作于 1989 年开始,1994 年提出第一个标准化草案。之后联合标准化委员会投票通过将惠普实验室开发的 STL 包含到 C++标准中,这延缓了 C++标准化进程。
1997 年 11 月 14 日,通过最终草案,1998 年,C++的 ANSI/IS0 标准投入使用。总之,C++是在 C 语言基础上发展而来,弥补了 C 语言的一些不足。
该文将深入剖析cout和cin两个基本的输入输出函数及其对应运算符,阐述输入输出流的概念,为日后的学习打下牢靠基础。
C++的输入与输出 1.引子:C++的第一个程序 按照传统惯例,第一个程序当然是Hello World了。我们来写一下代码:
// 这⾥的std cout等看不懂没关系,下⾯我们会依次讲解 #include<iostream> using namespace std; int main() { cout << "hello world\n" << endl; return 0; } 虽然还没学过,但相信以你的聪明才智,不难看出cout就是输出语句吧。下面我们来正式学习一下。
一.概念与结构 链表的结构丰富多样,基本分为以下的八种(2×2×2)
1.1 单项或双向 双向链表区别于单向链表的是,其多了一个指针区域,指向其前一个结点,这样就可以通过任意一个结点进行前后遍历.
1.2 带头或不带头 带不带头指的是其有无头结点,即下图的head结点,这个结点是一个特殊的结点,他不存放数据,只是存放指向头节点的地址,那么这样有什么好处呢,在为什么实现双向链表的过程中会有提及.
1.3 循环或不循环 循环或不循环指的是该链表的头尾是否相连接,如果这个链表为一个循环链表那么他的尾节点的next指针则不再是指向空,而是于指向了头结点,实现了头尾相连.
在上一篇博客中,我们论述的单链表,严谨的说法应该是单向不带头不循环链表,这是比较常用到的链表结构之一.
而在本篇章中,我们就要实现的双链表,即是另一个比较常用的链表结构:双向带头循环链表.
既然双链表的全称为双向带头循环链表,由此我们不难推断出他节点结构:一个数值域,两个指针域,分别是指向该节点的前驱节点prev与其后驱节点pcur.
typedef int LTDatatype; typedef struct ListNode { LTDatatype data; struct ListNode* next; struct ListNode* prev; }LTNode; 二.双链表的实现 双链表的实现基本分为以下的三个部分
2.1 List.h #pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> typedef int LTDatatype; typedef struct ListNode { LTDatatype data; struct ListNode* next; struct ListNode* prev; }LTNode; //创建结点 LTNode* LTCreat(LTDatatype x); //初始化 LTNode* LTInit(); //打印 void LTPrint(LTNode* phead); //插入 void LTPushBack(LTNode* phead, LTDatatype x); void LTPushFront(LTNode* phead, LTDatatype x); //删除 void LTPopBack(LTNode* phead); void LTPopFront(LTNode* phead); //查询结点函数 LTNode* LTFind(LTNode* phead, LTDatatype x); //指定位置之后插入 void LTInsert(LTNode* pos, LTDatatype x); //指定位置删除 void LTErase(LTNode* pos); //销毁 void LTDestroy(LTNode* pphead); 2.
二叉树相关的算法题 单值二叉树 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false。
示例 1:
输入:[1,1,1,1,1,null,1] 输出:true 示例 2:
输入:[2,2,2,5,2] 输出:false 提示:
给定树的节点数范围是 [1, 100]。每个节点的值都是整数,范围为 [0, 99] 。 思路如下:
代码如下:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ typedef struct TreeNode TreeNode; bool isUnivalTree(struct TreeNode* root) { //根节点为空 if(root==NULL) { return true; } //根节点不为空 if(root->left&&root->left->val!=root->val) { return false; } if(root->right&&root->right->val!
SSE(Streaming SIMD Extensions)家族是由英特尔引入的一组指令集扩展,用于提高多媒体、科学计算和其他领域的处理性能。SSE家族随着时间的发展,增加了多个版本和子集。以下是SSE家族的主要分类:
SSE (SSE1):
引入时间:1999年,随Pentium III处理器发布。特点:增加了70条新指令,主要用于加速浮点运算和多媒体任务。 SSE2:
引入时间:2001年,随Pentium 4处理器发布。特点:扩展了SSE1指令集,包括144条新指令,支持双精度浮点运算和整数运算。 SSE3:
引入时间:2004年,随Prescott内核的Pentium 4处理器发布。特点:增加了13条新指令,优化了线程同步和浮点数水平加法等操作。 SSSE3 (Supplemental SSE3):
引入时间:2006年,随Intel Core 2处理器发布。特点:增加了16条新指令,进一步优化了多媒体处理和加密计算。 SSE4:
SSE4.1: 引入时间:2007年,随Penryn内核的处理器发布。特点:增加了47条新指令,支持文本处理和视频编解码等任务。 SSE4.2: 引入时间:2008年,随Nehalem内核的处理器发布。特点:增加了7条新指令,进一步优化了字符串和文本处理。 SSE4a:
引入时间:2007年,随AMD K10处理器(如Phenom)发布。特点:包含4条新指令,用于加速某些特定的计算任务。需要注意的是,SSE4a是由AMD引入的,而不是英特尔。 AES-NI (Advanced Encryption Standard New Instructions):
引入时间:2010年,随Westmere内核的处理器发布。特点:虽然不完全属于SSE家族,但常与SSE相关联。AES-NI包含一组指令,用于优化AES加密算法的处理性能。 总的来说,SSE家族通过逐步增加新指令和优化现有指令,显著提高了处理器在多媒体、科学计算、加密等领域的性能。这些改进使得SSE成为了现代处理器中不可或缺的一部分。
AVX(Advanced Vector Extensions)家族是英特尔和AMD处理器中用于提高浮点和整数运算性能的一组指令集扩展。AVX家族包含多个版本和子集,每个版本都在前一版本的基础上增加了新的功能和优化。以下是AVX家族的主要分类:
AVX (AVX1):
引入时间:2011年,随英特尔Sandy Bridge处理器发布。特点:扩展了128位的SSE指令集到256位,支持更高效的浮点和整数运算。 AVX2:
引入时间:2013年,随英特尔Haswell处理器发布。特点:增加了对整数操作的支持,扩展了FMA(Fused Multiply-Add)指令,进一步提高了数据处理能力。 AVX-512:
引入时间:2016年,随英特尔Xeon Phi处理器和Skylake-X系列处理器发布。特点:扩展到512位宽度,提供更高的并行处理能力和更丰富的指令集。AVX-512包含多个子集,例如AVX-512F(基础指令)、AVX-512CD(冲突检测)、AVX-512ER(指数和倒数计算)、AVX-512PF(预取指令)等。 AVX-512子集:
AVX-512 Foundation (AVX-512F): 基础指令集,包含了最基本的512位宽向量操作指令。AVX-512 Conflict Detection Instructions (AVX-512CD): 提供冲突检测指令,主要用于优化并行算法。AVX-512 Exponential and Reciprocal Instructions (AVX-512ER): 包括指数和倒数计算的专用指令,主要用于科学计算和金融应用。AVX-512 Prefetch Instructions (AVX-512PF): 包含预取指令,用于加速内存访问。AVX-512 Byte and Word Instructions (AVX-512BW): 扩展了字节和字的操作,增加了对更小数据类型的支持。AVX-512 Vector Length Extensions (AVX-512VL): 允许使用128位和256位的向量操作,这使得它可以与AVX和AVX2指令集兼容。AVX-512 Doubleword and Quadword Instructions (AVX-512DQ): 扩展了对双字和四字操作的支持。AVX-512 Vector Bit Manipulation Instructions (AVX-512VBMI): 提供了向量比特操作的指令,主要用于数据压缩和加密。AVX-512 Vector Bit Manipulation Instructions 2 (AVX-512VBMI2): 这是AVX-512VBMI的扩展版本,增加了更多的比特操作指令。AVX-512 Population Count (AVX-512VPOPCNTDQ): 包含了向量人口计数指令,用于计算向量内每个元素的二进制1的数量。AVX-512 Neural Network Instructions (AVX-512NNI): 优化了神经网络相关的计算。AVX-512 Neural Network Instructions 2 (AVX-512NNI2): 扩展了神经网络指令集,以支持更多的神经网络操作。AVX-512 Bit Algorithms (AVX-512BITALG): 包括了一些新的比特操作算法指令。AVX-512 GFNI (AVX-512 GFNI): 包含了基于有限域的指令,主要用于加密计算。AVX-512 VP2INTERSECT (AVX-512 VP2INTERSECT): 提供了新的交集指令。 AVX-512 BFloat16 (AVX512_BF16):
文章目录 乐观锁和悲观锁重量级锁和轻量级锁挂起等待锁和自旋锁公平锁和非公平锁可重入锁和不可重入锁读写锁相关面试题 锁:非常广义的概念,不是指某个具体的锁,所有的锁都可以往这些策略中套
synchronized:只是市面上五花八门的锁种,其中一种典型的实现,Java 内置的,推荐使用的锁
乐观锁和悲观锁 这两个词不是指某个具体的锁,而是锁的一种“特性”,描述了“一类”
乐观锁:加锁的时候,假设出现冲突的概率不大
接下来围绕加锁要做的工作就会更少
悲观锁:加锁的时候,假设出现锁冲突的概率很大接下来围绕加锁要做的工作就会更多 使用 synchronized,初始情况下,是乐观的(预估接下来锁冲突概率不大)
同时会在背后偷偷地统计锁冲突了多少次如果发现锁冲突达到一定程度了,就会转变为“悲观的”
乐观锁和悲观锁需要做的事情是不同的乐观做的事情少一点悲观做的事情往往更重量级 站在预测锁冲突的概率是否高
synchronized 是自适应的
重量级锁和轻量级锁 效果和悲观乐观是重叠的,只是站在的角度不一样
重量级锁:加锁的开销比较大,要做的工作更多
往往悲观的时候,会做的重
轻量级锁:加锁的开销比较小,要做的工作相对更少往往乐观的时候,会做的轻
但也不能认为是 100%等价,因为:乐观和悲观是站在“预估所冲突”角度重量轻量是站在“加锁开销“角度 站在加锁的开销角度
synchronized 也是自适应的
挂起等待锁和自旋锁 挂起等待锁:属于是悲观锁/重量级锁的一种典型实现
自旋锁:乐观锁/轻量级锁的一种典型实现
比如:
你去追你的女神:
女神女神,我好喜欢你,
你尝试对女神加锁
女神表示:我有男朋友了
女神表示她这把锁已经被别的线程给加了
你就可以选择“等待”,等到女神锁被释放,比如:
你选择每天仍然会给女神不停地问候“早安,午安…”,这里的行为称为“自旋锁”
这里的等待是“忙等”,等待的过程中 CPU 的资源不会释放某天女神和男朋友吵架了,不开心,你就立刻能感知到,机会来了。这样你就可以在女神锁释放的第一时间,立刻抓住机会,能够上位不停地,循环地检测锁是否被释放,一旦锁释放,就能立即有机会能获得锁 你选择把女神拉黑,先不联系了,若干年后你从别人那里听说,女神分手了,你再去联络女神,这种行为就是“挂起等待锁”
不联系,就相当于“让出 CPU 资源”CPU 就可以去做别的事了不理女神之后,我们就可以有心思好好学习,好好敲代码,好好找工作了,在过程中做成更多的事情。过了一段时间后,我们通过一些途径听说女神分手了,再伺机而动,但“听说”的时效性很低,这个中间可能有很长的时间跨度。在这个时间跨度里,女神是否由谈了男朋友?分手了多少次?你是不知道的挂机时间更长,但能节省下 CPU 资源去做别的事情 注意:
只有在假定锁冲突概率不高的情况下,才能“忙等”。如果好几个线程都在竞争同一个锁,一个线程拿到锁,其他的都在“忙等”,这样总的 CPU 消耗就会非常高而且,由于竞争太激烈,导致有些线程要等待很久才能拿到锁锁冲突很高的概率很高的话就不适合“自旋锁”方案 挂起等待锁也就适合“悲观锁”这样的场景了锁竞争非常激烈,预测拿到锁的概率本身就不打,不放吧 CPU 让出来,充分的做其他事情 synchronized“自适应”
轻量级锁就是基于自旋的方式实现的(JVM 内部,用户态代码实现)重量级锁就是基于挂起等待的方式实现的(调用操作系统 API,在内核中实现)
纯用户态代码往往执行效率比内核态代码的高一些,总体来说,我们还是认为“自旋”的效率更高的,但是 CPU 开销更大
挂起等待锁的操作虽然 CPU 开销变少了,但整体的等待时间更多 公平锁和非公平锁 日常生活中,说的公平可能有不同的含义
当女神分手了,该轮到谁上位呢?
公平锁: 在计算机中,约定“先来后到”为公平
总结:去重用for循环,插值可用for循环和迭代器(可以方便在中间插值),如果要修改集合,就用listIterator,防止父类的Iterator没有add添加功能,也避免版本号不一致报错
去重:用contains方法,确认新集合中是否存在旧值
1、基本数据类型String去重
public class ArrayListQuChong { public static void main(String[] args) { ArrayList arr=new ArrayList();//Ait+右键竖向编辑 arr.add("java"); arr.add("hadoop"); arr.add("hive"); arr.add("java"); arr.add("hello"); arr.add("hadoop"); //使用for循环遍历,去重 ArrayList arr1=new ArrayList();//创建一个新的集合 for (int i=0;i<arr.size();i++){//可以将集合当作数组处理,ArriList底层代码就是数组结构 // arr1.get(i)=arr.get(i);//不能这样写,因为两边都是变量 if(!arr1.contains(arr.get(i))){ arr1.add(arr.get(i)); } }System.out.println("for循环去重"+arr1);//ArrayList自带重写了toString方法,所以可以直接打印 2、引用数据类型的去重,去重之前首先要在ArrayListYingYong类修改toString方法 //便于直接比较内容,如果是插其他值,看是否有相同的,就用equals方法 //第一题、使用for循环去重
/*使用for循环*/ ArrayList arr2=new ArrayList(); ArrayListYingYong yingYong0=new ArrayListYingYong("程啊伟",22); ArrayListYingYong yingYong1=new ArrayListYingYong("小强",20); ArrayListYingYong yingYong2=new ArrayListYingYong("韩韩",18); ArrayListYingYong yingYong3=new ArrayListYingYong("小强",20); ArrayListYingYong yingYong4=new ArrayListYingYong("程啊伟",22); arr2.add(yingYong0); arr2.add(yingYong1); arr2.add(yingYong2); arr2.add(yingYong3); arr2.add(yingYong4); ArrayList arr3=new ArrayList();//创建新集合接收 for(int j=0;j<arr2.size();j++){ if(!arr3.contains(arr2.get(j))){ arr3.add(arr2.get(j)); } } System.
Temu跨境电商是一个由拼多多公司开发并运营的跨境电商平台,以其独特的理念、丰富的商品种类和便捷的购物体验赢得了消费者的青睐。随着国际业务的不断拓展和市场环境的变化,Temu竞争力不断提升,为全球消费者提供了更多优质、实惠的商品和服务。
此接口可获取TEMU平台商品详细数据信息,包括价格规格评论等。
请求API http://api.xxxx.com/temu/ll/detail?good_id=601099517783669&country=us¤cy=USD&token=test
请求参数 返回实例 联系我们(更多接口详见主页专栏) 如有更多需要,请私信或访问官网联系我们:https://isaas.top/zh
系列文章目录 运维中心
4.1 功能概述
4.2 操作流程
4.2.1 操作流程概览
4.2.2 步骤一:查看周期任务配置
4.2.3 步骤二:测试周期任务
4.2.4 步骤三:周期任务补历史数据
4.2.5 步骤四:查看周期实例
4.2.6 步骤五:查看执行结果
4.2.7 步骤六:创建自定义监控规则 文章目录 系列文章目录前言4. 运维中心4.1 功能概述4.2 操作流程4.2.1 操作流程概览4.2.2 步骤一:查看周期任务配置4.2.3 步骤二:测试周期任务4.2.4 步骤三:周期任务补历史数据4.2.5 步骤四:查看周期实例4.2.6 步骤五:查看执行结果4.2.7 步骤六:创建自定义监控规则 前言 本文主要详解了DataWorks的数据运维,
后续章节:flink业务开发
4. 运维中心 4.1 功能概述 运维中心包括运维大屏、实时任务运维、周期任务运维、手动任务运维、智能监控、智能诊断、资源运维和引擎运维功能模块,为用户提供任务操作与状态、引擎、资源等多方位的运维能力。
4.2 操作流程 登录DataWorks控制台,单击左侧导航栏的数据建模与开发 > 运维中心,在下拉框中选择对应工作空间后单击进入运维中心。或者直接点击上方的运维中心进入。
4.2.1 操作流程概览 操作流程可以分为两个阶段:
阶段一:测试验证调度任务
步骤一:查看周期任务配置
为避免周期任务调度不符合预期,建议在任务发布后先检查周期任务配置的调度参数、调度资源组等是否正确。若不符合预期,请修改相应配置并重新发布。
步骤二:测试周期任务
通过冒烟测试功能验证周期任务在生产环境执行是否正确。若执行出错,请根据报错及时处理,保障任务可正常运行。
步骤三:周期任务补历史数据
通过补数据功能可重新计算历史时间段内的数据。
步骤四:查看周期实例
周期任务发布成功后会根据调度周期生成周期实例,如果在DataStudio中配置的实例生成方式为T+1次日生成,则任务将在第二天开始调度;如果配置为发布后即时生成,则任务当天便会调度。用户可查看调度实例的生成及运行情况,判断任务的周期调度是否正常。
步骤五:查看执行结果
节点执行测试或补数据操作后,用户可查看数据的写入情况。
阶段二:监控周期调度任务
步骤六:创建自定义监控规则
用户可根据业务需求,为周期调度任务配置智能监控规则,监控任务的调度运行状况,保障该任务后续可以正常调度。
步骤七:创建资源组自动运维规则
通过自定义独享资源组的监控规则,对独享资源组的使用率及资源组上等待的实例数设置监控报警,并进行相关运维操作。
4.2.2 步骤一:查看周期任务配置 为避免周期任务调度不符合预期,建议在任务发布后先查看该任务的配置(例如,任务的调度参数、节点依赖关系等)是否正确。
(1)进入运维中心。
(2)查找目标节点。
一、混合应用开发 混合应用顾名思义就是网页html和原生APP共同作用的结果
好处在一既有web的跨平台优势(安卓、苹果,电脑、国产电脑、平板电脑,自助机都能用)
好处二可以离线使用,比较稳定
好处三可以与本地硬件交互
二、web调用本地资源 web调用本地交互采用jsapi
代码示例
public WebView cwpd_Web;
java未来之窗内部插件 csp = new java未来之窗内部插件d(main_instance); webview.addJavascriptInterface(new 未来之窗交互(this, this), "未来之窗交互名称"); js调用方式
未来之窗交互名称.读取酒店门锁(酒店门锁厂家)
三、android调用web android 一般不知道当前web情况,一般采用2中方式
1.web不断轮询查询检测结果
缺点:消耗web资源,优点,技术要求低
2.采用webview内部通知机制
优点:不消耗内部资源,缺点:需要了解系统底层
四、webview调用NFC 权限
<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" /> nfc 资源库
import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.MifareClassic; import android.nfc.tech.MifareUltralight; import android.nfc.tech.NfcA; nfc 服务
private NfcAdapter NFC_mAdapter2023; private NdefMessage mNdefPushMessage; private PendingIntent mPendingIntent; nfc 服务启动
resolveIntent(getIntent()); NFC_mAdapter2023 = NfcAdapter.
人工智能时代,程序员如何保持核心竞争力? 在人工智能的浪潮中,程序员的角色和工作方式正在经历前所未有的变革。AIGC技术的兴起,如ChatGPT、Midjourney、Claude等,预示着AI辅助编程工具的日益普及。面对这一趋势,程序员如何保持并提升自身的核心竞争力,成为了一个值得深思的问题。本文将从AI辅助编程对程序员工作的影响、程序员应重点发展的核心能力以及人机协作模式下的职业发展规划三个方向进行探讨。
方向一:AI辅助编程对程序员工作的影响 1.1AI工具改变编码实践 人工智能辅助编程工具的兴起,为程序员的日常工作带来了革命性的变化。这些工具通过深度学习技术,能够理解编程语言的语法和逻辑,从而提供智能的代码补全、错误检测、代码生成甚至重构建议。以下是AI工具在编码实践中的几个关键应用:
自动补全:AI工具能够根据程序员的编码习惯和上下文信息,预测并补全代码,极大地加快了编码速度。代码生成:在某些情况下,程序员只需描述功能需求,AI即可生成相应的代码片段或整个功能模块。错误检测与修复:AI工具能够实时检测代码中的错误,并提供修改建议,甚至自动修复一些常见的编程错误。代码优化:通过分析现有代码,AI工具可以提出性能优化建议,帮助程序员编写更高效的代码。 4个代码经典案例:
1、假设一个程序员正在使用一个支持AI自动补全的集成开发环境(IDE)。当他开始输入一个熟悉的编程模式时,AI工具可能会预测并补全剩余的代码。
# 程序员开始输入一个循环结构 for i in range(10): # AI自动补全循环体 print(i) 2、在一个支持AI代码生成的环境中,程序员可以描述他们想要的功能,而AI工具将生成相应的代码。
# 程序员描述需求:生成一个函数,计算两个数的和 """ Generate a function that calculates the sum of two numbers. """ # AI生成的函数代码 def add_numbers(a, b): return a + b # 使用生成的函数 result = add_numbers(3, 5) print("Sum:", result) 3、程序员可能不小心在代码中引入了一个错误,AI工具可以检测到这个错误并提供修复建议。
# 程序员编写的代码,但忘记了括号 print("Hello World! # AI检测到错误并提供修复建议 # 建议添加缺失的括号 print("Hello, World!") 4、AI工具分析现有代码,并提出性能优化建议。
# 程序员编写的原始代码,可能效率不高 def calculate_sum(numbers): sum = 0 for num in numbers: sum += num return sum # AI工具分析并提出优化建议 # 建议使用内置函数sum()来提高效率 def calculate_sum_optimized(numbers): return sum(numbers) 1.
文章目录 内存和地址内存编址 指针变量和地址取地址操作符指针变量和解引用操作符指针变量指针变量类型解引用操作符指针变量的大小 指针变量类型的意义指针的解引用指针+-整数void*指针 const修饰指针指针运算指针+-整数指针-指针指针的关系运算 野指针野指针成因如何规避野指针 assert断言传值调用和传址调用写在最后 内存和地址 内存 在讲内存和地址之前,先看一个⽣活中的案例:
假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩, 如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给每个房间编上号,如:
//⼀楼:101,102,103... //⼆楼:201,202,203... //... 有了房间号,如果你的朋友得到房间号,就可以快速的找房间,找到你。
⽣活中,每个房间有了房间号,就能提⾼效率,能快速的找到房间。
如果把上⾯的例⼦对照到计算机中,⼜是怎么样呢?
我们知道计算机上 CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何⾼效的管理呢?
其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。
计算机中常⻅的单位:
bit - ⽐特位 Byte - 字节 KB MB GB TB PB 1Byte = 8bit 1KB = 1024Byte 1MB = 1024KB 1GB = 1024MB 1TB = 1024GB 1PB = 1024TB 其中,每个内存单元,相当于⼀个学⽣宿舍,⼀ 个字节空间⾥⾯能放8个⽐特位,就好⽐同学们住的⼋⼈间,每个⼈是⼀个⽐特位。
每个内存单元也都有⼀个编号(这个编号就相当于宿舍房间的⻔牌号),有了这个内存单元的编号,CPU就可以快速找到⼀个内存空间。
⽣活中我们把⻔牌号也叫地址,在计算机中我们 把内存单元的编号也称为地址。C语⾔中给地址起了新的名字叫:指针。
内存单元的编号 == 地址 == 指针
编址 CPU访问内存中的某个字节空间,必须知道这个 字节空间在内存的什么位置,⽽因为内存中字节 很多,所以需要给内存进⾏编址(就如同宿舍很 多,需要给宿舍编号⼀样)。
计算机中的编址,并不是把每个字节的地址记录下来,⽽是通过硬件设计完成的
CPU和内存之间有⼀组线,叫做地址总线。
我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表⽰0,1【电脉冲有⽆】,那么 ⼀根线,就能表⽰2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表⽰232种含 义,每⼀种含义都代表⼀个地址。 地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据再通过数据总线传⼊ CPU内寄存器。
一、用户信息 MySQL中的用户信息,都存储在系统数据库mysql的表user中
user表的结构如下 这里主要介绍以下几个字段
host : 表示这个用户可以从哪个主机登陆,如果是 localhost ,表示只能从本机登陆 user: 用户名 authentication_string: 用户密码通过 password 函数加密后的 *_priv : 用户拥有的权限 二、创建用户 由于mysql的用户管理也是放在表中的,所以我们可以直接对user表插入用户信息,但是这种做法不推荐。我们一般使用sql的语句创建,如下
create user ' 用户名 ' @ ' 登陆主机 /ip' identified by ' 密码 ' ; 说明:
一般网页登录在服务器端存放的也不是我们的密码,都是被加密过的,防止数据库被盗,用户信息被泄露,所以我们在查看用户密码只能看到一串字符串。host 设置为 hostlocal 表示只允许本地登录,和 127.0.0.1 一样如果 host 设置为 '%' 表示任意ip地址都能登录,但是一般不推荐flush privileges 用来刷新权限设置数据库一般被放在内网,不允许外网ip直接访问,外网ip也无法得知内网的ip,这样保证了数据库安全 远程连接数据库的语句如下
mysql -h 远程数据库IP地址 -P 端口号 -u 用户名 -p
三、删除用户 我们可以直接对user表进行删除操作(不推荐),也可以通过sql语句,如下
drop user '用户名'@'主机名';
四、修改用户密码 自己改自己密码 set password=password( ' 新的密码 ' ); root用户指定用户的密码 set password for ' 用户名 ' @ ' 主机名 ' =password( ' 新的密码 ' ); 五、数据库的权限管理 权限有 create,drop,alter,insert,update,delete,select,.
介绍 Kettle(也称为Pentaho Data Integration)是一款开源的ETL(Extract, Transform, Load)工具,由Pentaho(现为Hitachi Vantara)开发和维护。它提供了一套强大的数据集成和转换功能,用于从各种数据源提取数据、进行数据转换和清洗,并将数据加载到目标系统中。
ETL功能:Kettle专注于提供ETL功能,即从不同的数据源(如数据库、文件、Web服务等)中提取数据,并对数据进行转换和整理,最后将数据加载到目标系统中。它支持各种数据处理操作,如过滤、排序、聚合、连接、转换等,以满足不同的数据集成需求。
可视化设计:Kettle提供了一个可视化的设计界面,称为Spoon。通过Spoon,用户可以通过拖拽和连接各种组件来创建数据转换和工作流程。这种可视化的设计方式使得ETL过程更加直观和易于理解。
多种数据源支持:Kettle支持多种数据源的连接和操作,包括关系型数据库(如MySQL、Oracle、SQL Server等)、非关系型数据库(如MongoDB、Hadoop等)、文件(如CSV、Excel等)、Web服务(如REST API、SOAP等)等。这使得Kettle可以处理各种不同类型和格式的数据。
强大的转换和清洗功能:Kettle提供了丰富的转换和清洗功能,可以对数据进行各种操作,如字段映射、数据类型转换、数据清洗、数据合并、数据拆分等。这些功能使得数据在整个ETL过程中能够得到有效的处理和准备。
可扩展性:Kettle提供了一套插件机制,允许用户根据自己的需求进行功能扩展和定制。用户可以编写自定义的插件,以满足特定的数据集成和处理需求。
Kettle是一款功能强大、灵活可扩展的ETL工具,适用于各种数据集成和转换任务。在开源系统中,它的可视化设计界面和丰富的功能使得数据处理变得更加简单和高效。
尽管目前市面上开源ETL老牌工具有Sqoop,datax,Canal、StreamSets等,新晋ELT工具有airbyte, seaTunnel等。但kettle作为传统老牌ETL工具,在易用性,资料丰富性等方面仍然有一席之地,对于千万级内的数据量级处理,仍是不可替代的优秀ETl工具之一。
本人是KETTLE使用爱好者以及二次开发者,拥有8年的丰富使用经验。在使用过程中针对kettle的弱项,以及对市面上一些kettle二开工具的对比发现,目前尚未有一款好用的调度管理工具。经此,于是准备开发一款简单易用,灵活部署,可以水平扩展的分布式调度管理平台。
功能介绍和对比 废话不多说,上才艺:
比较维度功能本产品第三方产品设计及架构框架springcloud微服务springboot或springmvc单体设计前后端分离ui层管理,调度,执行耦合在一个服务中调度层agent层执行层调度层基于xxl-job封装和优化,支持集群和动态分片,集群模式下支持数十万至百万级任务调度基于quartz或者spring schedule组件agent层springcloud微服务模式,用来管理kettle的carte服务,支持水平扩展,接受调度层的指令,来向执行层发送转换做作业的任务。
1、支持carte服务的管理和探活,自动剔除异常节点,和故障转移
2、支持8种负载均衡策略
3、基于分片模式的任务执行状态定时检测,不存在单点压力和故障。
4、任务异常告警,carte服务监控告警可视化配置无执行层基于kettle的carte模式采用插件策略二次开发,无代码入侵,不集成任何kettle源码,兼容kettle5.x, kettle6.x, kettle7.x, kettle8.x,kettle9.xkettle源码嵌入单体服务中,不利于版本升级和管理前端UI框架vue2.XeasyUI, jquery, bootstrap权限设计基于RBAC模式设计部门,岗位,角色无菜单,按钮,资源层精细化控制数据权限业务模块设计数据集成任务报表概览任务管理项目管理无任务管理无集群管理无节点管理无无元数据管理血缘分析无数据源管理数仓管理ODS原始数据层无DWD数据明细层无DWS服务数据层无ADS数据应用层无数据服务数据发布无授权管理无api管理无监控模块服务器监控Prometheus,hertzbeat无服务级监控grafana无jvm监控无日志观测;链路追踪模块loki日志可视化loki日志可视化无oss日志存储oss日志存储无jaeger链路追踪jaeger链路追踪无 架构设计 详细功能介绍 1、ETL概览 首先是ETL概览,最上面是统计当前管理的任务数,以及任务执行情况。下面的折线图是展示每日执行的转换和作业的成功失败数。
2、项目管理 2.1 项目管理
对ETL任务进行项目维度的包装,将ETL任务和业务进行绑定,使之具备生命周期属性,更易于理解和管理。
2.2 项目新增
3、任务管理 整个系统的最核心地方,对ETL任务进行封装,与项目映射为多对一的关系。一个项目任务绑定一个carte集群,和一个调度任务,并拥有任务状态属性。可以实时查看当前任务执行状态,以及执行日志。
任务新增
新增任务,需要绑定项目,和ETL资源库的转换或作业信息,然后再指定要执行的carte集群。
支持运行中的任务实时修改转换或作业信息。改动下次执行生效。
任务执行
任务创建完成之后,可以点击右侧按钮执行执行一次,此时agent层会从集群中根据负载均衡策略,选取一个可用的slave节点,将转换做作业信息发送到该节点上执行,并将改任务添加到状态监控队列,对任务的执行状态进行更新和日志监控
当任务启动后,状态栏会切换为动态转换的蓝色小齿轮,同时可以实时查看进行中的日志
任务定时执行
对于ETL任务,90%的都要定时重复执行,这里可以设置定时执行:
这里可以对定时方式进行配置,指定agent作为执行器,以及agent的路由策略,cron表达式,以及失败策略等。
启动定时任务
点击定时管理按钮,可以对定时任务进行执行,停止,以及删除操作。
任务修改
支持实时的任务修改,和集群修改,下次执行时会自动生效。
任务DAG查看 4、集群管理 这里重新设计了carte的集群配置,carte本身的集群只是简单的主从模式,这里设计了master动态选举集群模式,
master节点挂掉之后,会自动选择其他slave节点作为master节点。
新建集群
每个slave可以加入到多个集群中,互不冲突。集群策略支持8种负载均衡模式,如果对任务执行成功率有严格要求,可以设置为故障转移模式,但这种情况可能会存在任务倾斜的情况,导致某个carte节点任务数很多,而有的carte又很闲。后面会考虑增加一个组合模式的负载均衡策略,将故障转移和轮询或者一致性hash结合在一起。正常情况建议选择一致性hash或者轮询策略。
5、节点管理 节点是集群的组成核心之一,所有集群都是从节点池中选择一批进行组合。
管理列表这里优先展示节点身上的任务数,以及cpu和内存使用情况。
节点操作
可以对节点进行刷新,编辑,停止等操作。
6、日志观测平台 日志观测平台基于分布式轻量级日志存储系统loki, 和采集器vector, 以及grafana可视化展示平台组成,方便开发实时排查系统日志和快速定位问题。 7、监控告警平台 基于jmx和prometheus非入侵方式对carte服务进行jvm维度的监控,一旦服务状态异常,秒级响应告警,方便运维实时处理问题,保证ETL任务的稳定性和可靠性。
文章目录 MySQL1. 视图1.1 视图的概念1.2 为什么要使用视图1.3 视图的基本使用1.4 视图规则和限制 MySQL 1. 视图 1.1 视图的概念 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表,基表的数据变化也会影响到视图。
视图的主要作用包括:
简化数据操作:对于复杂的查询结果,通过创建视图,可以将其以一种更简单、直观的方式呈现,方便用户进行后续的数据操作。
例如,如果有一个包含大量字段的订单表,而用户经常只需要查看订单号、客户名称和订单金额,就可以创建一个只包含这三个字段的视图,使得数据操作更简便。
数据安全性:可以通过视图限制用户对某些敏感数据的访问。只将用户需要的数据展示在视图中,而隐藏其他不相关或敏感的信息。
比如,在员工信息表中,可以创建一个视图只显示员工姓名和部门,而不显示工资等敏感信息。
逻辑数据独立性:当底层的表结构发生变化时,如果视图的定义没有改变,那么对于使用视图的用户来说,他们的操作方式不需要改变。
1.2 为什么要使用视图 1. 数据抽象和简化:
视图能够将复杂的数据结构和关系简化为更易于理解和使用的形式。 例如,一个包含多个关联表的复杂数据库结构,通过创建视图,可以将相关数据整合为一个直观的单一数据源,减少用户处理复杂查询的需求。
2. 数据安全性增强:
可以通过视图控制用户对特定数据的访问权限。 只在视图中展示允许用户查看的数据,而隐藏敏感或不必要的信息。比如,在一个包含员工个人信息的数据库中,可以创建一个视图,只显示员工的姓名、部门和职位,而不包括工资、社保号等敏感数据。
3. 逻辑数据独立性:
当底层的表结构发生更改时,如果视图的定义不受影响,那么用户基于视图的操作无需修改。 这使得数据库的维护和升级对用户的影响最小化。
4. 一致性和标准化:
视图确保用户始终以相同的方式访问和处理特定的数据子集,有助于保持数据的一致性和标准化。
5. 提高查询性能:
对于一些经常使用的复杂查询,将其创建为视图可以避免重复编写相同的查询语句,提高查询效率。而且,数据库系统在某些情况下可以对视图进行优化,提高数据获取的速度。
6. 隐藏复杂性:
数据库管理员可以使用视图来隐藏底层数据存储和处理的复杂性,让用户专注于他们需要的数据和操作。
例如,在一个销售数据库中,创建一个视图来计算每个产品的月销售总额。这样,销售人员无需了解复杂的计算逻辑,只需使用这个视图获取所需的信息。
综上所述,视图在数据库管理和数据使用中发挥着重要的作用,能够提高数据管理的效率、安全性和可用性。
1.3 视图的基本使用 创建视图:create view 视图名 as select语句 from 表明 where 限制条件;
删除视图:drop view 视图名;
案例:
create view v_ename_dname as select ename, dname from EMP, DEPT where EMP.
在Java中,方法调用会被编译为invokeStatic,invokeSpecial,invokVirtual以及invokeInterface四种指令。这些指令与包含目标方法类名、方法名以及方法描述符的符号引用捆绑,在实际运行之前,JVM根据这个符号引用链接到具体目标方法。
JDK7 引入新的指令invodeDynamic该指令的调用机制抽象出调用点这一个概念,并允许应用程序将调用点链接至任意符合条件的方法上。同时JDK7 还配套引入了更加低层、更加抽象的方法抽象:方法句柄(invokedynamic 底层机制的基石:方法句柄。)。
一、方法句柄 1.方法句柄概念 强类型,能够被直接执行的引用。
方法句柄的类型是由所指向方法的参数以及返回类型组成的。它是用来确认方法句柄是否适配的唯一关键。
方法句柄的获取 class Foo { private static void bar(Object o) { .. } public static Lookup lookup() { return MethodHandles.lookup(); } } // 获取方法句柄的不同方式 MethodHandles.Lookup l = Foo.lookup(); // 具备 Foo 类的访问权限 Method m = Foo.class.getDeclaredMethod("bar", Object.class); MethodHandle mh0 = l.unreflect(m); MethodType t = MethodType.methodType(void.class, Object.class); MethodHandle mh1 = l.findStatic(Foo.class, "bar", t); 方法句柄的权限
与反射 API 不同,其权限检查是在句柄的创建阶段完成的。在实际调用过程中,JVM不会检查方法句柄的权限。 方法句柄的访问权限不取决于方法句柄的创建位置,而是取决于 Lookup对象的创建位置
举个例子,对于一个私有字段,如果 Lookup 对象是在私有字段所在类中获取的,则这个Lookup对象便拥有对该私有字段的访问权限, 即使是在所在类的外边,也能够通过该 Lookup 对象创建该私有字段的getter 或 setter 2.
从去年下边年 Friend.tech 引发的新一轮社交热,到去年年底铭文赛道高潮不断,加密市场情绪不断被点燃。但事实上,链游板块在最近几轮热潮中显得有些冷清,无论是彼时的 GameFi 龙头 Axie Infinity,还是在上一轮 GameFi 热潮中表现亮眼的 Immuatable X、WAX、Klaytn 等游戏公链,都展现出了一片门可罗雀的景象。
那么 GameFi 赛道缘何走向衰落?
技术因素成为链游世界发展最大的阻碍 GameFi 的早期构想
以“P2E”为特性的 GameFi,代表着这个游戏时代的新盈利模式,它将 NFT 或其他形式的代币化资产作为游戏内容,游戏内资产的寿命,则会随着这些资产继续存在于玩家的钱包中而延长(即便游戏关闭),资产的互操作性和可组合性使它们能够与其他游戏、应用或区块链进行交互。尤其是 NFT 要素,为游戏提供了各种好处,包括资产所有权、资产可编程性,并为激励和创新提供了新的机会。此外,这些资产也同样可以以绝对去中心化的形式,在基于区块链的市场上流通并交易以获得潜在的利润,这也让众多 GameFi 玩家乐此不疲。
从另一个角度看,随着传统游戏市场因竞争激烈而导致过度内卷化,且传统游戏市场资金分配愈发复杂,获取用户的成本越来越高,导致游戏商业生态内各个角色的收入、利润不断下降,尤其是核心角色游戏开发者。我们看到,区块链游戏及其基于代币的新盈利模式,则为游戏开发者提供了一个独特的机会,让他们能够创造更多的每用户平均收入,扩大他们的用户基数,并探索新的收益流。
技术的发展落后于意识形态的迭代
不过从实际出发,GameFi 赛道的发展始终未能突破瓶颈。就目前绝大多数 GameFi 应用而言,与其说它们是 Web3 ,不如将其描述为 Web2.5。
实际上,如果将游戏所有的元素嵌入至链上时,玩家在游戏中的每一笔交易都将是一笔交易,玩家可能需要为其每一步操作签署交易、支付一笔燃气费,并等待将移动日志“最终化”,这也会导致游戏循环中发生“卡顿”。为了保持游戏的流畅性,绝大多数 GameFi 开发团队都会选择向中心化妥协,开发者通常都会选择仅将经济模型链上化,即将资产 Crypto 化并支持链上实时交易,但游戏引擎还是保持传统状态,即将其他要素构建在中心化服务器堆栈上。
所以除了资产的自主流通外,链游仍旧保持着传统游戏的意识形态,即当游戏开发者建立了既定的规则与游戏轮廓后,玩家通常需要遵循规则且毫无自主性可言,游戏生态缺乏自下而上的可拓展性与可组合性。而当中心化的服务器不再为这些游戏服务时,玩家的游戏数据、角色将荡然无存。
同样,行业基建设施对于链游赛道也缺乏支持。一方面区块链秉承去中心化的特性,所有链上数据通常公开且透明的,缺乏隐私性的支持导致众多场景不得不移步至链下,对于玩家而言缺乏一定的公平性。同时区块链本身承载上存在一定的限制,当链上行为载荷过高时,交易成本飙升、交易效率骤降并对游戏产生直接的影响。比如前不久铭文市场爆火很多链上交易飙升,就扒光了一众 Layer2、EVM 兼容链的底裤。所以就目前而言,即便是很多游戏依托于中心化服务器作为底层堆栈的情况下,现有行业设施也同样难以对很多交互逻辑复杂、用户基数庞大的大型游戏进行支持。
这也就导致绝大多数局链游缺乏可玩性,尤其在缺乏合理经济模型的情况系游戏难以长期存续,开发者除早期代币销售外通常难以持续获利,而玩家则会因代币激励陷入死亡螺旋而不得不从中撤出。
大型游戏厂商链游化转型难
传统游戏厂商入局 GameFi 一般有两个选择,一个是开发新的游戏,比如以 Zynga、Ubisoft、Konami 为代表的具备一定开发实力的巨头厂商,正在向这个领域探索并开发新的游戏。而另一个则是将现有的成熟游戏进行链改,对原有游戏的生态进行延续包括游戏玩法、游戏文化IP、玩家粘性等。但无论哪种方式,都存在相当的实现难度。
链游本身是一个较为复杂的事物,一方面在于其构建在链上,一些游戏逻辑很难在链上实现,当然它不仅仅包含游戏模型,其还包含基于Crypto的经济模型、公链选择、钱包支持、智能合约开发方案(审计)、NFT的设计与开发方案,以及游戏上线后,公会DAO构建、DeFi模型嵌入、项目运营等等。从区块链行业的角度看,开发一款大型的链游或者将传统游戏进行链改,通常需要一支15人以上,且具备相当经验的区块链开发团队。
而目前区块链领域开发人员稀缺,短期内很难快速招募一支有经验的区块链开发团队,并且开发周期则至少需要半年至一年,漫长的开发周期也意味着其开发成本将不低于80万美元。而像 Zynga、Ubisoft、Konami 等具备一定开发实力的厂商,还属少数。
MetaArena 正在成新“解题者” 在整体链游赛道对现状仍未有合理解决方案的背景下,MetaArena 率先成为了“解题者”。目前,MetaArena 构建了一套由 ZKP (零知识证明)驱动的区块链游戏引擎,基于一套模块化的主权 Layer3 Rollup、各种由 zk 驱动的 Services SDK 等组件,为全链游游戏提供所需的可组合性、可编程性、可扩展性和隐私性,该引擎正在推动区块链游戏向全新的形态发展。
🍊 编程有易不绕弯,成长之路不孤单! 大家好,我是熊哈哈,这个项目从我接手到现在有了两个多月的时间了吧,其实本来我在七月初就做完的吧,但是六月份的时候生病了,在家里休息了一个月的时间,后来回到学校考试,考完试之后就出来实习了,这个项目也就一直拖了下去,最近时间够了就在努力的去完成这个项目。
总体来说这个项目不是很难,有很多的东西不够细节,处理的也不是很到位,请大家谅解一下。在我考虑到的不充分的地方一个就是在删除电子书的时候,并没有删除电子书对应存在数据库当中的文章,还有就是在登录的时候,密码加密应该在前端就开始加密了,不应该传到后端在进行加密处理,其实还有很多不到位的地方需要大家去查找,我在提示一下,有没有考虑到为接口添加事物?
此外,项目还可以有改进部分,一个是添加AOP做日志管理,还有自定义异常类,这些都是很重要的模块,在实际的开发当中,一定不要像代码当中的那么随意。其他的我还没有想到,不过我记得我之前说过这个项目的权限校验不太合理,有兴趣的可以了解一下RBAC还有SpringSecurity。
目录
🍊 编程有易不绕弯,成长之路不孤单!
一、今日目标
二、SpringBoot代码修改
2.1 新增IpUtil
2.2 添加访问量统计功能
2.3 新增点赞功能
2.4 实现数据统计
2.4.1 定时更新ebook数据
2.4.2 定时更新ebook_snapshot
2.5 展示总浏览量和30天内的数据变化
一、今日目标 上篇文章链接:【wiki知识库】08.添加用户登录功能--后端SpringBoot部分-CSDN博客
上篇文章做了登录功能的后端逻辑,实现了登录拦截还有权限校验部分,为网站提供了一定的安全性保障,在这篇文章就要实现最后的部分:浏览量的统计和点赞功能。
这一部分就是纯Sql,还有自动化任务。
二、SpringBoot代码修改 2.1 新增IpUtil 这个工具类的作用就是在你访问接口的时候,可以获取到你的真实IP。
public class IpUtil { private static final String UNKNOWN = "unknown"; private static final String LOCALHOST = "127.0.0.1"; private static final String SEPARATOR = ","; public static String getIpAddr(HttpServletRequest request) { System.out.println(request); String ipAddress; try { ipAddress = request.