最近在看微软eShopOnContainers 项目,看到事件总线觉得不错,和大家分享一下
看完此文你将获得什么?
eShop中是如何设计事件总线的
实现一个InMemory事件总线eShop中是没有InMemory实现的,这算是一个小小小的挑战
发布订阅模式
发布订阅模式可以让应用程序组件之间解耦,这是我们使用这种模式最重要的理由之一,如果你完全不知道这个东西,建议你先通过搜索引擎了解一下这种模式,网上的资料很多这里就不再赘述了。
eShop中的EventBus就是基于这种模式的发布/订阅 。 发布订阅模式核心概念有三个:发布者、订阅者、调度中心 ,这些概念在消息队列中就是生产者、消费者、MQ实例 。
在eShop中有两个EventBus的实现:
基于RabbitMq的EventBusRabbitMQ
基于AzureServiceBus的EventBusServiceBus
。
从IEventBus
开始
先来看一看,所有EventBus的接口IEventBus
public interface IEventBus
{
void Publish(IntegrationEvent @event);
void Subscribe()
where T : IntegrationEvent
where TH : IIntegrationEventHandler;
void SubscribeDynamic(string eventName)
where TH : IDynamicIntegrationEventHandler;
void UnsubscribeDynamic (string eventName)
where TH : IDynamicIntegrationEventHandler;
void Unsubscribe()
where TH : IIntegrationEventHandler
where T : IntegrationEvent;
}
嗯,乍一看看是有点眼晕的,仔细看它的核心功能只有三个:
Publish 发布
Subscribe 订阅
Unsubscribe 取消订阅
这对应着发布订阅模式的基本概念,不过对于事件总线的接口添加了许多约束:
发布的内容(消息)必须是IntegrationEvent
及其子类
订阅事件必须指明要订阅事件的类型,并附带处理器类型
处理器必须是IIntegrationEventHandler
的实现类
Ok,看到这里先不要管Dynamic
相关的方法,然后记住这个两个关键点:
事件必须继承IntegrationEvent
处理器必须实现IIntegrationEventHandler
且T
是IntegrationEvent
子类
另外,看下 IntegrationEvent
有什么
public class IntegrationEvent
{
public IntegrationEvent()
{
Id = Guid.NewGuid();
CreationDate = DateTime.UtcNow;
}
public Guid Id { get; }
public DateTime CreationDate { get; }
}
IEventBusSubscriptionsManager是什么
public interface IEventBusSubscriptionsManager
{
bool IsEmpty { get; }
event EventHandler OnEventRemoved;
void AddDynamicSubscription(string eventName)
where TH : IDynamicIntegrationEventHandler;
void AddSubscription()
where T : IntegrationEvent
where TH : IIntegrationEventHandler;
void RemoveSubscription()
where TH : IIntegrationEventHandler
where T : IntegrationEvent;
void RemoveDynamicSubscription(string eventName)
where TH : IDynamicIntegrationEventHandler;
bool HasSubscriptionsForEvent() where T : IntegrationEvent;
bool HasSubscriptionsForEvent(string eventName);
Type GetEventTypeByName(string eventName);
void Clear();
IEnumerable GetHandlersForEvent() where T : IntegrationEvent;
IEnumerable GetHandlersForEvent(string eventName);
string GetEventKey();
}
这个接口看起来稍显复杂些,我们来简化下看看:
public interface IEventBusSubscriptionsManager
{
void AddSubscription()
void RemoveSubscription()
IEnumerable GetHandlersForEvent()
}
最终,这三个方法就是我们要关注的,添加订阅、移除订阅、获取指定事件的订阅信息。
SubscriptionInfo
是什么?
public bool IsDynamic { get; }
public Type HandlerType{ get; }
SubscriptionInfo
中只有两个信息,这是不是一个Dynamic类型的Event以及这个Event所对应的处理器的类型。
这是你可能会有另一个疑问:
这个和IEventBus
有什么关系?
IEventBusSubscriptionsManager
含有更多功能:查看是否有订阅,获取事件的Type,获取事件的处理器等等
IEventBusSubscriptionsManager
由IEventBus
使用,在RabbitMq和ServiceBus的实现中,都使用Manager去存储事件的信息,例如下面的代码:
public void Subscribe()
where T : IntegrationEvent
where TH : IIntegrationEventHandler
{
// 查询事件的全名
var eventName = _subsManager.GetEventKey();
//向mq添加注册
DoInternalSubscription(eventName);
// 向manager添加订阅
_subsManager.AddSubscription();
}
private void DoInternalSubscription(string eventName)
{
var containsKey = _subsManager.HasSubscriptionsForEvent(eventName);
if (!containsKey)
{
if (!_persistentConnection.IsConnected)
{
_persistentConnection.TryConnect();
}
using (var channel = _persistentConnection.CreateModel())
{
channel.QueueBind(queue: _queueName,
exchange: BROKER_NAME,
routingKey: eventName);
}
}
}
查询事件的名字是manager做的,订阅的时候是先向mq添加订阅,之后又加到manager中,manager管理着订阅的基本信息。
另外一个重要功能是获取事件的处理器信息,在rabbit mq的实现中,ProcessEvent方法中用manager获取了事件的处理器,再用依赖注入获得处理器的实例,反射调用Handle
方法处理事件信息:
private async Task ProcessEvent(string eventName, string message)
{
// 从manager查询信息
if (_subsManager.HasSubscriptionsForEvent(eventName))
{
using (var scope = _autofac.BeginLifetimeScope(AUTOFAC_SCOPE_NAME))
{
// 从manager获取处理器
var subscriptions = _subsManager.GetHandlersForEvent(eventName);
foreach (var subscription in subscriptions)
{
// Di + 反射调用,处理事件(两个都是,只是针对是否是dynamic做了不同的处理)
if (subscription.IsDynamic)
{
var handler = scope.ResolveOptional(subscription.HandlerType) as IDynamicIntegrationEventHandler;
dynamic eventData = JObject.Parse(message);
await handler.Handle(eventData);
}
else
{
var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
var handler = scope.ResolveOptional(subscription.HandlerType);
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
}
}
}
}
}
IEventBusSubscriptionsManager的默认实现
在eShop中只有一个实现就是InMemoryEventBusSubscriptionsManager
类
这个类中有两个重要的字段
private readonly Dictionary> _handlers;
private readonly List _eventTypes;
他们分别存储了事件列表和事件处理器信息词典
接下来就是实现一个
基于内存的事件总线
了
我们要做什么呢?IEventBusSubscriptionsManager 已经有了InMemory的实现了,我们可以直接拿来用,所以我们只需要自己实现一个EventBus就好了
先贴出最终代码:
public class InMemoryEventBus : IEventBus
{
private readonly IServiceProvider _provider;
private readonly ILogger _logger;
private readonly ISubscriptionsManager _manager;
private readonly IList _events;
public InMemoryEventBus(
IServiceProvider provider,
ILogger logger,
ISubscriptionsManager manager)
{
_provider = provider;
_logger = logger;
_manager = manager;
}
public void Publish(IntegrationEvent e)
{
var eventType = e.GetType();
var handlers = _manager.GetHandlersForEvent(eventType.FullName);
foreach (var handlerInfo in handlers)
{
var handler = _provider.GetService(handlerInfo.HandlerType);
var method = handlerInfo.HandlerType.GetMethod("Handle");
method.Invoke(handler, new object[] { e });
}
}
public void Subscribe()
where T : IntegrationEvent
where TH : IIntegrationEventHandler
{
_manager.AddSubscription();
}
public void SubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler
{
throw new NotImplementedException();
}
public void Unsubscribe()
where T : IntegrationEvent
where TH : IIntegrationEventHandler
{
_manager.RemoveSubscription();
}
public void UnsubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler
{
throw new NotImplementedException();
}
}
首先构造函数中声明我们要使用的东西:
public InMemoryEventBus(
IServiceProvider provider,
ILogger logger,
ISubscriptionsManager manager)
{
_provider = provider;
_logger = logger;
_manager = manager;
}
这里要注意的就是IServiceProvider provider
这是 DI容器,当我们在切实处理事件的时候我们选择从DI获取处理器的实例,而不是反射创建,这要做的好处在于,处理器可以依赖于其它东西,并且可以是单例的
public void Subscribe()
where T : IntegrationEvent
where TH : IIntegrationEventHandler
{
_manager.AddSubscription();
}
public void Unsubscribe()
where T : IntegrationEvent
where TH : IIntegrationEventHandler
{
_manager.RemoveSubscription();
}
订阅和取消订阅很简单,因为我们是InMemory的所以只调用了manager的方法。
接下来就是最重要的Publish方法,实现Publish有两种方式:
使用额外的线程和Queue让发布和处理异步
为了简单起见,我们先写个简单易懂的同步的
public void Publish(IntegrationEvent e)
{
// 首先要拿到集成事件的Type信息
var eventType = e.GetType();
// 获取属于这个事件的处理器列表,可能有很多,注意获得的是SubscriptionInfo
var handlers = _manager.GetHandlersForEvent(eventType.FullName);
// 不解释循环
foreach (var handlerInfo in handlers)
{
// 从DI中获取类型的实例
var handler = _provider.GetService(handlerInfo.HandlerType);
// 拿到Handle方法
var method = handlerInfo.HandlerType.GetMethod("Handle");
// 调用方法
method.Invoke(handler, new object[] { e });
}
}
OK,我们的InMemoryEventBus就写好了!
要实践这个InMemoryEventBus,那么还需要一个IntegrationEvent
的子类,和一个IIntegrationEventHandler
的实现类,这些都不难,例如我们做一个添加用户的事件,A在添加用户后,发起一个事件并将新用户的名字作为事件数据,B去订阅事件,并在自己的处理器中处理名字信息。
思路是这样的:
写一个 AddUserEvent:IntegrationEvent
,里面有一个UserId和一个UserName
。
写一个AddUserEventHandler:IIntegrationEventHandler
,在Handle
方法中输出UserId和Name到日志。
注册DI,你要注册下面这些服务:
IEventBus=>InMemoryEventBus
ISubscriptionsManager=>InMemorySubscriptionsManager
AddUserEventHandler=>AddUserEventHandler
在Startup中为刚刚写的事件和处理器添加订阅(在这里已经可以获取到IEventBus实例了)
写一个Api接口或是什么,调用IEventBus的Publish方法,new 一个新的AddUserEvent
作为参数传进去。
OK!到这里一个切实可用的InMemoryEventBus就可以使用了。
你可能感兴趣的:(看eShopOnContainers学一个EventBus)
深度剖析苹果签名与应用程序的紧密关系
ios
在苹果的生态系统中,应用程序的发布和使用有着一套严格且独特的规则,而苹果签名在其中扮演着举足轻重的角色。对于广大苹果用户和应用开发者来说,深入了解苹果签名与应用程序之间的关系,有助于更好地把握苹果应用市场的运行机制。一、苹果签名的基本概念苹果签名是苹果公司为了确保应用程序来源可靠、内容安全,以及维护整个应用生态的有序性而采用的一种数字认证技术。简单来说,它就像是给应用程序贴上了一个“数字身份证”。
如何从GitHub上克隆项目
仿生阿尔泰人
github
1.在本地新建一个文件夹作为本地仓库如demo2.进入demo文件夹右键选择gitbushhere3.进入下面的界面输入gitinit将本地仓库初始化4.使用gitcloneurl的格式将你需要的项目从GitHub上下载下来(url为为项目服务器地址或github地址)注:GitHub中的项目下载地址
s1K 数据集:是一个用于提升语言模型推理能力的高质量数据集。
数据集
2025-02-07,由斯坦福大学、华盛顿大学等研究机构创建了s1K数据集,该数据集包含1,000个精心挑选的问题,并配以推理轨迹和答案,为语言模型推理能力的提升提供了重要的数据基础。一、研究背景近年来,语言模型(LMs)在大规模预训练的基础上取得了显著进展,其性能提升主要依赖于训练时计算资源的增加。然而,随着模型规模的不断扩大,训练成本也急剧上升。为了在有限的资源下进一步提升模型性能,研究者们开
HTML 样式与布局初体验:学习进程中的关键节点(二)
计算机毕设定制辅导-无忧学长
# HTML html 学习 css
学习中的困难与突破在学习HTML样式与布局的过程中,我也遇到了不少困难,这些困难就像是学习道路上的绊脚石,但也正是在克服它们的过程中,我实现了自我的突破和成长。(一)样式冲突:规则的碰撞样式冲突是我遇到的第一个难题。当使用多个CSS规则来定义同一个元素的样式时,由于选择器的优先级和规则的先后顺序不同,经常会出现样式不符合预期的情况。比如,我在一个项目中,同时使用了外部样式表和内嵌样式来设置按钮的样
(1)【个人使用篇】github代码管理
RoboticsTechLab
开发技术管理 git github ssh
文章目录(1)第一步【下载、新建代码】:clone拉取下载项目/新建自己的项目方法(1)方式一:【clone拉取下载项目到本地目录】步骤一:创建本地版本库(repository)第一步:创建一个目录第二步:把目录进行git初始化步骤二:从远程库拉取项目到本地第1步:创建SSHKey第2步:登陆GitHub,打开“Accountsettings”,“SSHKeys”页面,设置SSH和keys第3步:
ChatGPT智能聊天机器人实现
云端源想
chatgpt 机器人
以下是一个从零实现类ChatGPT智能聊天机器人的完整开发指南,包含技术选型、核心代码逻辑和推荐学习资源:—云端平台整理一、技术架构与工具核心模型基座模型:HuggingFaceTransformers库(如GPT-2/GPT-3.5TurboAPI/LLaMA2)轻量化方案:微软DeepSpeed或MetaFairScale(降低显存占用)训练框架PyTorchLightning+Acceler
【面试经验】华为 AI软开 计算产品线(面经+时间线)
litterfinger
面试 华为 人工智能
一.岗位:AI软开二.时间线:投递08.09,机试08.28,测评08.29;面试均线上,一面09.12,二面09.27,三面09.29(本来是09.19线下二三面,但由于本人有事推迟)三.一面(50min)自我介绍简单介绍一下传统知识图谱建设和大模型对于知识的构建的差异和整体的趋势聊聊实习经历中的提示工程和sft具体的工作AI的一个发展历史流程和相关算法的引进知识图谱建设的总体流程回顾机试:老鼠
纯代码非插件实现wordpress右侧悬浮在线客服咨询台
wodrpress资源分享
wordpress wordpress
为了创建一个悬浮在右侧的在线客服咨询台,您可以使用HTML和CSS。以下是一个简单的示例,包含了QQ咨询和微信咨询的链接。HTML代码:在线客服咨询台QQ咨询微信咨询CSS代码:#right-sidebar{width:200px;height:100vh;position:fixed;right:0;top:0;background-color:#f5f5f5;padding:20px;}#on
wordpress导入mysql数据库文件的方法及注意事项
wodrpress资源分享
wordpress 数据库 mysql wordpress
WordPress是一个流行的开源内容管理系统,通常用于构建网站和博客。它使用MySQL数据库来存储和管理网站数据。在某些情况下,您可能需要将现有的MySQL数据库导入到新的WordPress安装中。本文将介绍如何导入MySQL数据库文件到WordPress以及需要注意的事项。一、备份现有数据库在进行任何数据库导入操作之前,强烈建议您先备份现有的数据库。这样可以确保在导入过程中出现问题时,您不会丢
CSS 自适应图片根据 div 大小进行均匀填充
前端小助手
css tensorflow 前端
目录前言使用object-fit属性示例代码HTMLCSS总结相关阅读1.前言在Web开发中,经常需要图片根据其容器的大小进行自适应填充,使得图片在任何设备和屏幕尺寸下都能保持良好的显示效果。本文将介绍如何使用CSS中的object-fit属性来实现这一需求。2.使用object-fit属性object-fit是一个CSS属性,专门用于控制替换元素(如、等)在其容器内的显示方式。常用的值有:fil
解决 Flutter Device Daemon 启动失败问题的实践记录
又吹风_Bassy
flutter Flutter Daemon file handles Daemon Crash AndroidStudio
解决FlutterDeviceDaemon启动失败问题的实践记录最近在使用Flutter开发时踩了一个坑。看似是个小问题,但折腾了好久,最终通过日志分析和查阅资料才找到了解决办法。这里记录一下整个问题的排查过程,希望能帮助到遇到类似问题的小伙伴。问题背景事情是这样的,我在启动AndroidStudio时突然弹出了一个错误窗口:提示Flutterdaemon启动失败,过了一会儿之后,又弹出下面的弹窗
错误记录: git 无法连接到github
agctXY
错误记录 git github
错误记录:git无法连接到github今天,新建了一个github仓库,但从本地怎么都push不上去.并报错
[email protected] :Permissiondenied(publickey).fatal:Couldnotreadfromremoterepository.Pleasemakesureyouhavethecorrectaccessrightsandtherepositoryexist
GitHub图床
Thinking_calculus
Linux github
GitHub之图床github当图床使用的方法了解了,最简单的、安全的方式是创建一个私有库,通过发起issue的方式把想要保存的图片放在issue区title中可以添加便于记忆的字段,虽然大概率以后不会用到,但如果需要时可以使用爬虫爬取issue保存下来,也便于查找之前还有些照片以仓库的形式同步在这个仓库中,但取url这个过程十分麻烦,不过如果是用于储存大量照片的话,使用仓库同步的方式可能不会差,
训练数据重复采样,让正负样本比例1:1
kimi-222
机器学习 人工智能 深度学习
详细解释resample函数:resample函数来自sklearn.utils,用于从数据集中重新抽样。replace=True表示允许重复抽样,即同一个样本可以被多次选中。n_samples指定抽样的数量。确保训练集数量相同:通过resample函数,你可以确保正训练集和负训练集的数量相同,即使其中一个集的数量小于另一个集的数量。如果n_train_num小于max_train_num,res
组件化/Kotlin
Ice_Lemon_dc
android kotlin 开发语言
七、组件化组件化原理引入组件化的原因:项目随着需求的增加规模变得越来越大,规模的增大导致了各种业务错中复杂的交织在一起,每个业务模块之间,代码没有约束,带来了代码边界的模糊,代码冲突时有发生,更改一个小问题可能引起一些新的问题,牵一发而动全身,增加一个新需求,需要熟悉相关的代码逻辑,增加开发时间避免重复造轮子,可以节省开发和维护的成本。可以通过组件和模块为业务基准合理地安排人力,提高开发效率。不同
如何在GitHub上Clone项目:一步步指南
Fanstay985
github
GitHub作为全球最大的代码托管平台,汇聚了无数开发者的智慧结晶。对于初学者和资深开发者来说,学会如何从GitHub上克隆(Clone)项目是一项基本且重要的技能。本文将详细介绍如何在GitHub上克隆项目的步骤,帮助你轻松将他人的代码库下载到本地进行学习和开发。一、准备工作在开始之前,请确保你已经安装了Git。Git是一个分布式版本控制系统,用于代码的版本管理。如果你还没有安装Git,可以从G
探索大模型应用:构建基于检索的RAG实战指南
李逍遥猿
人工智能 计算机视觉 microsoft AIGC 开源 深度学习 神经网络
在AI技术的浪潮中,大模型以其强大的问题回答能力,正逐渐渗透到各行各业,成为推动行业发展的新引擎。然而,大模型并非万能,它在实时性和私有领域知识覆盖上存在局限。为了克服这些限制,本文将带你深入了解如何利用检索增强生成模型(RAG)来扩展大模型的能力,并通过一个实战案例,展示如何构建一个基于RAG的AI知识库。一、大模型的局限与RAG的机遇大模型虽然在处理通用问题上表现出色,但在面对实时数据和私有领
面试中必会的Java基础(一)
每次的天空
面试 java 学习
Java是面向对象编程所以第一就是面向对象编程的特点是什么?面向对象编程类与对象:掌握类的定义、成员变量和成员方法的声明与使用,以及如何通过类创建对象。理解对象的生命周期,包括创建、使用和销毁。封装:明白封装的概念,即把数据和操作数据的方法封装在一个类中,通过访问修饰符(public、private、protected等)来控制对类成员的访问。继承:理解继承的概念和作用,掌握通过extends关键
MVC/MVP/MVVM框架学习总结(二)
每次的天空
mvc 学习 java
上次已经了解到MVC的知识,现在是扩展实现MVP/MVVM的框架改进本身项目MVVM框架即Model-View-ViewModel框架,是一种软件架构设计模式,以下是具体介绍:核心组件Model(模型):代表应用程序的数据结构和业务逻辑,负责数据的存储、检索、验证和处理,定义业务规则和算法,是应用程序的数据核心。比如在一个电商应用中,商品数据、用户订单数据等的存储和相关逻辑处理都属于Model层。
Python学习第十九天
Leo来编程
Python学习 学习 python
Django-分页后端分页Django提供了Paginator类来实现后端分页。Paginator类可以将一个查询集(QuerySet)分成多个页面,每个页面包含指定数量的对象。fromdjango.shortcutsimportrender,redirect,get_object_or_404from.modelsimportUserfrom.formsimportUserFormfromdja
【时间复杂度常见的计算】
xihongshi547
算法 leetcode 数据结构
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档时间复杂度的简单介绍前言一、时间复杂度是什么?二、时间复杂度的计算1.基本步骤2.常见的时间复杂度总结前言对于判断一段代码的好坏,取决于该代码运行的时间与占用的空间,也就是时间复杂度与空间复杂度,本章就先讲一下时间复杂度,主要包含常见的时间复杂度的计算。一、时间复杂度是什么?时间复杂度是衡量算法运行效率的一个重要指标,它表示随着输入规
Python入门到精通(三):数据结构第一部分
love9599
Python入门到精通 python 开发语言
python的常用数据结构类型字符型字典列表元组、集合一、序列序列:是python中的一类数据类型,比如字符串、列表序列类型的对象是可以进行循环变例的1.1序列特性索引:指的是在序列中找到指定元素的索引编号切片:指的是从序列中提取一部分内容加法:序列对象可以将多个序列合并成一个乘法:可以将序列通过乘法输出多个相同的1.2序列操作索引操作格式:序列名[索引值]#案例1:str1="hello"#定义
前端实现页面截图 -- html2canvas
浮桥
前端
方案:canvaspuppeteer(无头浏览器)html2canvas使用html2canvas实现:考虑:1.截图区域:全页面截图,局部截图、特定区域截图2.函数式、组件式实现代码:页面截图页面截图示例这是一个简单的页面截图示例。截图functionhtml2canvasToImage(dom){//使用html2canvas将页面转换为canvashtml2canvas(dom).then(
c夏普语言输入方法,c sharp 的输入,输入,switch语句。
愚夫股份
c夏普语言输入方法
创建一个控制台应用程序,从键盘输入一个小写字母,要求输出该小写字母,其对应的大写字母,以及值。usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceConsoleApplication1{classProgram{stati
微服务调试:多环境 env 组件详解
时雨h
算法 JAVA 面试 java python 运维
微服务调试:多环境env组件详解一、多环境env组件(一)微服务调试的痛点在微服务架构下,开发人员在调试过程中常常会遇到各种挑战。其中一个常见的问题就是在多人协作的开发环境中,如何确保自己的调试请求能够准确地到达自己本地的服务实例,而不是被其他开发者的实例所拦截。例如,假设团队中有两位开发人员A和B,他们都在本地启动了名为"user-service"的微服务实例。当A发起一个针对"user-ser
C Sharp委托、事件、多线程
微笑伴你而行
# c sharp c语言 开发语言
文章目录委托(Delegate)——你的“遥控器”事件(Event)——安全的“通知系统”多线程(Multithreading)——“同时做多件事”委托(Delegate)——你的“遥控器”是什么?想象你有一个万能遥控器,可以控制家里的电视、空调、灯光。委托就是这个“遥控器”,它允许你通过一个东西调用多个不同的方法。为什么需要它?比如你想写一个程序,让用户点击按钮时执行某些操作,但具体操作可能随时
Python常用数据结构
我真的不会做啊
python 数据结构 开发语言
背景:最近在学习自动化测试,发现基本是用python写的脚本就顺带好好学一学python,准备以后也深入学习一下今天简单的介绍一下python里面常用的数据结构吧Python数据结构原生数据结构原生数据结构元组Tuple()tup1=('Python','Java',1,2)tup2=(9527,)注意:1、使用()、tuple()创建元组,元组可以为空且元素类型可以不同;2、若元组中仅包含一个数
.NET c#知识点小补充
豆皮没有豆
.Net基础-c# c#基础 .net
1.面向对象:(1)对象:在程序中我们可以把任何事物来映射显示生活中的万事万物,那么我们把这些事物称之为对象。对象:属性、方法(主动)、事件(被动)。(2)面向对象:使用这种语言通过描述属性以及行为进行构造一个对象。(3)集成开发环境:具有代码的编辑、编译、检测、运行。a.所有的文件(.cs/.java/.py/.html。。。。)只是装载代码的一个载体文件。b.其承载的代码若要实现其具有的功能,
doris:认证与鉴权概述
向阳1218
大数据 doris
Doris的权限管理系统参照了MySQL的权限管理机制,做到了行级别细粒度的权限控制,基于角色的权限访问控制,并且支持白名单机制。名词解释用户标识UserIdentity在权限系统中,一个用户被识别为一个UserIdentity(用户标识)。用户标识由两部分组成:username和host。其中username为用户名,由英文大小写组成。host表示该用户链接来自的IP。UserIdentity以
Ollama 基本概念
Mr_One_Zhang
学习Ollama ai
Ollama是一个本地化的、支持多种自然语言处理(NLP)任务的机器学习框架,专注于模型加载、推理和生成任务。通过Ollama,用户能够方便地与本地部署的大型预训练模型进行交互。1.模型(Model)在Ollama中,模型是核心组成部分。它们是经过预训练的机器学习模型,能够执行不同的任务,例如文本生成、文本摘要、情感分析、对话生成等。Ollama支持多种流行的预训练模型,常见的模型有:deepse
ViewController添加button按钮解析。(翻译)
张亚雄
c
<div class="it610-blog-content-contain" style="font-size: 14px"></div>// ViewController.m
// Reservation software
//
// Created by 张亚雄 on 15/6/2.
mongoDB 简单的增删改查
开窍的石头
mongodb
在上一篇文章中我们已经讲了mongodb怎么安装和数据库/表的创建。在这里我们讲mongoDB的数据库操作
在mongo中对于不存在的表当你用db.表名 他会自动统计
下边用到的user是表明,db代表的是数据库
添加(insert):
log4j配置
0624chenhong
log4j
1) 新建java项目
2) 导入jar包,项目右击,properties—java build path—libraries—Add External jar,加入log4j.jar包。
3) 新建一个类com.hand.Log4jTest
package com.hand;
import org.apache.log4j.Logger;
public class
多点触摸(图片缩放为例)
不懂事的小屁孩
多点触摸
多点触摸的事件跟单点是大同小异的,上个图片缩放的代码,供大家参考一下
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener
有关浏览器窗口宽度高度几个值的解析
换个号韩国红果果
JavaScript html
1 元素的 offsetWidth 包括border padding content 整体的宽度。
clientWidth 只包括内容区 padding 不包括border。
clientLeft = offsetWidth -clientWidth 即这个元素border的值
offsetLeft 若无已定位的包裹元素
数据库产品巡礼:IBM DB2概览
蓝儿唯美
db2
IBM DB2是一个支持了NoSQL功能的关系数据库管理系统,其包含了对XML,图像存储和Java脚本对象表示(JSON)的支持。DB2可被各种类型的企 业使用,它提供了一个数据平台,同时支持事务和分析操作,通过提供持续的数据流来保持事务工作流和分析操作的高效性。 DB2支持的操作系统
DB2可应用于以下三个主要的平台:
工作站,DB2可在Linus、Unix、Windo
java笔记5
a-john
java
控制执行流程:
1,true和false
利用条件表达式的真或假来决定执行路径。例:(a==b)。它利用条件操作符“==”来判断a值是否等于b值,返回true或false。java不允许我们将一个数字作为布尔值使用,虽然这在C和C++里是允许的。如果想在布尔测试中使用一个非布尔值,那么首先必须用一个条件表达式将其转化成布尔值,例如if(a!=0)。
2,if-els
Web开发常用手册汇总
aijuans
PHP
一门技术,如果没有好的参考手册指导,很难普及大众。这其实就是为什么很多技术,非常好,却得不到普遍运用的原因。
正如我们学习一门技术,过程大概是这个样子:
①我们日常工作中,遇到了问题,困难。寻找解决方案,即寻找新的技术;
②为什么要学习这门技术?这门技术是不是很好的解决了我们遇到的难题,困惑。这个问题,非常重要,我们不是为了学习技术而学习技术,而是为了更好的处理我们遇到的问题,才需要学习新的
今天帮助人解决的一个sql问题
asialee
sql
今天有个人问了一个问题,如下:
type AD value
A  
意图对象传递数据
百合不是茶
android 意图Intent Bundle对象数据的传递
学习意图将数据传递给目标活动; 初学者需要好好研究的
1,将下面的代码添加到main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http:/
oracle查询锁表解锁语句
bijian1013
oracle object session kill
一.查询锁定的表
如下语句,都可以查询锁定的表
语句一:
select a.sid,
a.serial#,
p.spid,
c.object_name,
b.session_id,
b.oracle_username,
b.os_user_name
from v$process p, v$s
mac osx 10.10 下安装 mysql 5.6 二进制文件[tar.gz]
征客丶
mysql osx
场景:在 mac osx 10.10 下安装 mysql 5.6 的二进制文件。
环境:mac osx 10.10、mysql 5.6 的二进制文件
步骤:[所有目录请从根“/”目录开始取,以免层级弄错导致找不到目录]
1、下载 mysql 5.6 的二进制文件,下载目录下面称之为 mysql5.6SourceDir;
下载地址:http://dev.mysql.com/downl
分布式系统与框架
bit1129
分布式
RPC框架 Dubbo
什么是Dubbo
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。其核心部分包含: 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。 集群容错: 提供基于接
那些令人蛋痛的专业术语
白糖_
spring Web SSO IOC
spring
【控制反转(IOC)/依赖注入(DI)】:
由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
简单的说:对象的创建又容器(比如spring容器)来执行,程序里不直接new对象。
Web
【单点登录(SSO)】:SSO的定义是在多个应用系统中,用户
《给大忙人看的java8》摘抄
braveCS
java8
函数式接口:只包含一个抽象方法的接口
lambda表达式:是一段可以传递的代码
你最好将一个lambda表达式想象成一个函数,而不是一个对象,并记住它可以被转换为一个函数式接口。
事实上,函数式接口的转换是你在Java中使用lambda表达式能做的唯一一件事。
方法引用:又是要传递给其他代码的操作已经有实现的方法了,这时可以使
编程之美-计算字符串的相似度
bylijinnan
java 算法 编程之美
public class StringDistance {
/**
* 编程之美 计算字符串的相似度
* 我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
* 1.修改一个字符(如把“a”替换为“b”);
* 2.增加一个字符(如把“abdd”变为“aebdd”);
* 3.删除一个字符(如把“travelling”变为“trav
上传、下载压缩图片
chengxuyuancsdn
下载
/**
*
* @param uploadImage --本地路径(tomacat路径)
* @param serverDir --服务器路径
* @param imageType --文件或图片类型
* 此方法可以上传文件或图片.txt,.jpg,.gif等
*/
public void upload(String uploadImage,Str
bellman-ford(贝尔曼-福特)算法
comsci
算法 F#
Bellman-Ford算法(根据发明者 Richard Bellman 和 Lester Ford 命名)是求解单源最短路径问题的一种算法。单源点的最短路径问题是指:给定一个加权有向图G和源点s,对于图G中的任意一点v,求从s到v的最短路径。有时候这种算法也被称为 Moore-Bellman-Ford 算法,因为 Edward F. Moore zu 也为这个算法的发展做出了贡献。
与迪科
oracle ASM中ASM_POWER_LIMIT参数
daizj
ASM oracle ASM_POWER_LIMIT 磁盘平衡
ASM_POWER_LIMIT
该初始化参数用于指定ASM例程平衡磁盘所用的最大权值,其数值范围为0~11,默认值为1。该初始化参数是动态参数,可以使用ALTER SESSION或ALTER SYSTEM命令进行修改。示例如下:
SQL>ALTER SESSION SET Asm_power_limit=2;
高级排序:快速排序
dieslrae
快速排序
public void quickSort(int[] array){
this.quickSort(array, 0, array.length - 1);
}
public void quickSort(int[] array,int left,int right){
if(right - left <= 0
C语言学习六指针_何谓变量的地址 一个指针变量到底占几个字节
dcj3sjt126com
C语言
# include <stdio.h>
int main(void)
{
/*
1、一个变量的地址只用第一个字节表示
2、虽然他只使用了第一个字节表示,但是他本身指针变量类型就可以确定出他指向的指针变量占几个字节了
3、他都只存了第一个字节地址,为什么只需要存一个字节的地址,却占了4个字节,虽然只有一个字节,
但是这些字节比较多,所以编号就比较大,
phpize使用方法
dcj3sjt126com
PHP
phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块,下面介绍一个它的使用方法,需要的朋友可以参考下
安装(fastcgi模式)的时候,常常有这样一句命令:
代码如下:
/usr/local/webserver/php/bin/phpize
一、phpize是干嘛的?
phpize是什么?
phpize是用来扩展php扩展模块的,通过phpi
Java虚拟机学习 - 对象引用强度
shuizhaosi888
JAVA虚拟机
本文原文链接:http://blog.csdn.net/java2000_wl/article/details/8090276 转载请注明出处!
无论是通过计数算法判断对象的引用数量,还是通过根搜索算法判断对象引用链是否可达,判定对象是否存活都与“引用”相关。
引用主要分为 :强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Wea
.NET Framework 3.5 Service Pack 1(完整软件包)下载地址
happyqing
.net 下载 framework
Microsoft .NET Framework 3.5 Service Pack 1(完整软件包)
http://www.microsoft.com/zh-cn/download/details.aspx?id=25150
Microsoft .NET Framework 3.5 Service Pack 1 是一个累积更新,包含很多基于 .NET Framewo
JAVA定时器的使用
jingjing0907
java timer 线程 定时器
1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。
对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。
privatejava.util.Timer timer;
timer = newTimer(true);
timer.schedule(
newjava.util.TimerTask() { public void run()
Webbench
流浪鱼
webbench
首页下载地址 http://home.tiscali.cz/~cz210552/webbench.html
Webbench是知名的网站压力测试工具,它是由Lionbridge公司(http://www.lionbridge.com)开发。
Webbench能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况。webbench的标准测试可以向我们展示服务器的两项内容:每秒钟相
第11章 动画效果(中)
onestopweb
动画
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/
windows下制作bat启动脚本.
sanyecao2314
java cmd 脚本 bat
java -classpath C:\dwjj\commons-dbcp.jar;C:\dwjj\commons-pool.jar;C:\dwjj\log4j-1.2.16.jar;C:\dwjj\poi-3.9-20121203.jar;C:\dwjj\sqljdbc4.jar;C:\dwjj\voucherimp.jar com.citsamex.core.startup.MainStart
Java进行RSA加解密的例子
tomcat_oracle
java
加密是保证数据安全的手段之一。加密是将纯文本数据转换为难以理解的密文;解密是将密文转换回纯文本。 数据的加解密属于密码学的范畴。通常,加密和解密都需要使用一些秘密信息,这些秘密信息叫做密钥,将纯文本转为密文或者转回的时候都要用到这些密钥。 对称加密指的是发送者和接收者共用同一个密钥的加解密方法。 非对称加密(又称公钥加密)指的是需要一个私有密钥一个公开密钥,两个不同的密钥的
Android_ViewStub
阿尔萨斯
ViewStub
public final class ViewStub extends View
java.lang.Object
android.view.View
android.view.ViewStub
类摘要: ViewStub 是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件。当 ViewSt