最近在看微软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)
前端实现页面截图 -- 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
【动手学深度学习】#1PyTorch基础操作
-一杯为品-
机器学习 深度学习 人工智能
主要参考学习资料:《动手学深度学习》阿斯顿·张等著【动手学深度学习PyTorch版】哔哩哔哩@跟李牧学AI目录1.1数据操作1.1.1入门1.1.2运算符1.1.3广播机制1.1.4索引和切片1.1.5节省内存1.1.6转换为其他Python对象1.2数据预处理1.2.1读取数据集1.2.2处理缺失值1.2.3转换为张量格式1.3线性代数1.3.1标量1.3.2向量1.3.3矩阵1.3.4张量1.
软件开发面试题C#,.NET知识点(续)
.房东的猫
c# .net
1.C#中的封装是什么,以及它的重要性。封装(Encapsulation)是面向对象编程(OOP)的一个基本概念。它指的是将对象的状态(属性)和行为(方法)绑定在一起,并且将这些细节隐藏起来,只暴露必要的接口给外部使用。这样做的好处包括:提高代码的安全性:通过将数据隐藏在类内部,并通过公共方法(getters和setters)来访问和修改这些数据,可以防止外部代码直接修改类的内部状态,从而保护数据
moonligh串流教程以及3大问题解决
kalada82
win10电脑常见问题解决方案 职场和发展 小程序
首先说明,ml和steamlink我不是高下评判,大家自己喜欢用那个就行。ml可以关笔记本屏幕用,不用打开steam手动,我喜欢,还能当远程桌面问题;1软件下载,网上找的,随便用就是了2软件使用,开启gefoce的sheld功能·,把软件串流进去3ml使用闪屏,应为串流打开的屏幕是集显,就会这样,就要屏幕独显直连。台式连接一个外接显示器就行,笔记本买个hdmi欺骗器就行4设置hdmi的分辨率,设置
(十一)CSharp-LINQ-标准查询运算符(3)
CRongQ
CSharp linq c#
一、标准查询运算符1、概念标准查询运算符由一系列API方法组成,API能让我们查询任何.NET数组或集合。标准运算符的要点:标准查询运算符使用方法语法。一些运算符返回Ienumerable对象(或其他序列),而其他运算符返回标量。返回标量的运算符立即执行查询,并返回一个值,而不是一个可枚举类型对象。ToArray()、ToList()等ToCollection运算符也会立即执行。很多操作都以一个谓
S7-1200 博途V18 与 win11-24H2 系统 通信问题 有IP但显示节点不兼容????
Zp_4944
tcp/ip 网络协议 信息与通信 windows 人机交互
博途V18-plc1200在笔记本win11-24H2系统上可访问在线设备时可以搜到plc的ip,但是显示节点不兼容,不能与plc设备建立连接,同时plc显示的ip地址是红色的。换了一个win10的笔记本在线没问题,就把原来win11上的博途V18软件删了,重新安装win10上的博途V18软件,同样的安装发式,设置这些也绝对没有问题,但还是同样连不上plc。关防火墙,以管理员身份运行这些都试过了。
Linq的理解
It_sharp
C# Linq 匿名类型
前面的话这篇文章主要是在工具书中linq的基础上,我做了一些归纳。目录什么是Linq方法语法和查询语法查询表达式的结构标准查询运算符什么是Linq?Linq(link)代表语言集成查询(LanguageIntegratedQuery)Linq是.NET框架的扩展,它允许我们以使用SQL查询数据库的方式来查询数据集合。使用Linq,你可以从数据库、程序对象的集合以及XML文档中查询数据。一个例子st
【练习】PAT 乙 1078 字符串压缩与解压
柠石榴
输入输出 PAT 题解 有阻碍 算法 c++
题目文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如ccccc就用5c来表示。如果字符没有重复,就原样输出。例如aba压缩后仍然是aba。解压方法就是反过来,把形如5c这样的表示恢复为ccccc。本题需要你根据压缩或解压的要求,对给定字符串进行处理。这里我们简单地假设原始字符串是完全由英文字母和空格组成的非空字符串。
【C++语言】特殊类设计
加油,旭杏
c++ 开发语言
一、请设计一个类,不能被拷贝拷贝只会发生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。C++98将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。原因:设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就介意不能禁止拷贝了只声明不定义:不定义是因为该函数根本不会调用,定
【go语言】Gin框架介绍和使用
加油,旭杏
Go语言 gin
一、简单使用Gin框架搭建一个服务器packagemainimport("github.com/gin-gonic/gin")funcmain(){//创建一个默认的路由引擎r:=gin.Default()//GET请求方法r.GET("/hello",func(c*gin.Context){//c.JSON返回的是JSON格式的数据c.JSON(200,gin.H{"message":"hell
javaweb中@Component和@Mapper和@Service和@RestController这几个注解要加在哪?为什么?
瑞金彭于晏
maven java spring boot spring
在JavaWeb开发中特别是在使用Spring框架(包括SpringBoot)时,@Component、@Mapper、@Service、@RestController这些注解扮演着非常重要的角色,它们用于定义组件的类型,并帮助Spring框架进行自动装配和依赖注入。下面分别解释这些注解应该加在哪里以及为什么:1.@Component加在哪里:@Component可以加在任何类上,表示这个类是一个
python网格插值站点_在python中,在二维零网格上两点之间插值一条值线
weixin_39965490
python网格插值站点
TLDR:在2dnumpy数组中找到2个点后,如何在0数组中在它们之间插值一条1行?在上下文:目前我正在尝试从二值化的医学图像数据(0和1)对一个3d数组执行2d操作。最终目标是在填充体素/像素(即第一个和最后一个实例)的起点和终点之间添加一条1s的线。在为此,我使用SimpleITK分割一行,然后将其转换为numpy数组。在其他示例之后,我编写了返回一组数组的函数,这些数组显示填充(1)个像素和
python 网格数据插值_python – 网格数据的快速插值
weixin_39747399
python 网格数据插值
当然!有两个选项可以做不同的事情,但是既能利用原始数据的定期网格性质。第一个是scipy.ndimage.zoom.如果你只想通过内插原始数据生成一个更加密集的规则网格,那就是要走的路。第二个是scipy.ndimage.map_coordinates.如果你想在你的数据中插入一些(或许多)任意点,但仍然利用原始数据的定期网格性质(例如,不需要四叉树),那就是去的方式。作为一个快速示例(这将使用三
springboot是如何在没有web.xml的情况下在外部tomcat启动的
菜鸟王老汉
spring
最近在公司部署测试环境的时候遇到了问题,本地用springboot内嵌tomcat启动没有问题,部署到测试环境的外部tomcat就不加载,在咨询了同事之后在启动类上继承了SpringBootServletInitializer之后就没有了问题,但并没有深入去想。由于servlet的规范是要配置web.xml的,包括Struts2和spring都是要在web.xml配置的,有一天在服务器上看编译后的
CMake 保姆级教程
爱吃巧克力的程序媛
CMake c++
CMake是一个跨平台的构建工具,用于生成适合不同平台和编译器的构建系统文件(如Makefile或VisualStudio项目文件)。在Windows下使用CMake构建项目时,CMake会根据CMakeLists.txt文件生成适合Windows的构建系统文件(如VisualStudio项目文件)。以下是Windows下使用CMake的基本规则和步骤:https://subingwen.cn/c
@Component—@Autowired—@Mapper—@Bean
追JAVA的小菜鸟
零碎知识点 bean java mybatis spring component
注解详解一、@Component二、@Autowired注解支持context:annotation-config——手动注入beancontext:component-scanbase-package="zy.pojo"——扫描包并自动注入总结三、@Mapper@Mapper与@Repository四、@Bean@Bean与@Component区别一、@Component作用:表明了此类为一个组
HarmonyOS NEXT开发实战:Navigation页面跳转对象传递案例
一晃有一秋
鸿蒙实例 鸿蒙 harmonyos 华为 鸿蒙 鸿蒙系统 android
介绍本示例主要介绍在使用Navigation实现页面跳转时,如何在跳转页面得到转入页面传的类对象的方法。实现过程中使用了第三方插件class-transformer,传递对象经过该插件的plainToClass方法转换后可以直接调用对象的方法,效果图预览使用说明从首页进入本页面时,会传递一个类对象UserBookingInfo。点击“换个座位”按钮会调用该类对象的generateRandSeatN
ubuntu 24.10安装mysql
linuxxx110
ubuntu mysql
1.更新软件包列表在安装MySQL之前,先更新系统的软件包列表sudoaptupdate2、安装MySQL服务器sudoaptinstallmysql-server3.启动MySQL服务sudosystemctlstatusmysql4、运行安全脚本MySQL提供了一个安全脚本,用于设置root密码、移除匿名用户、禁止远程root登录等。运行以下命令sudomysql_secure_install
ServerStatus牛逼!!
架构文摘JGWZ
学习 工具 开源软件
作为一名攻城狮,面对各种服务器内存飙高、CPU猛增、磁盘打满等等服务器问题,可谓是伤透了我们的心。不仅要开发,还要处理这些问题,大把的时间浪费了,这时候一个好的全面的监控工具尤为重要了。所以,带着这个问题,为大家一个酷炫高逼格的服务器探针的监控工具:ServerStatus介绍ServerStatus是一个免费开源的监控工具,并且提供了一个直观的Web页面,极大的方便了开发人员。特性实时监控,如在
SQLite?低调不是小众...
架构文摘JGWZ
sqlite 数据库 学习 后端
前几天在一个群里看到一位同学说:“SQLite这么小众的数据库,到底是什么人在用啊?”首先要说的是SQLite可不是小众的数据库,相反,SQLite是世界上装机量最多的数据库,远超MySQL,只不过比较低调而已。低调到我想在官网上找一个好看的用来当插图的图片都找不到,只能截一张官网首页来撑一撑,看起来十分朴素。我最早听说SQLite是刚毕业工作的时候,我们部门做微软内容管理产品的二次开发,其中有一
一个简单的语音识别实现---百度在线语音识别REST API SDK(Python)简单使用
DerrickOzil
语音识别 python sdk 语音识别
百度在线语音识别RESTAPISDK(Python)简单使用首先申请开发者权限注册开发者信息完成注册创建新应用下载SDK并查看key在应用管理中,选择查看key,记录AppID、APIKey、SecretKey三个参数值。测试音频链接:http://pan.baidu.com/s/1o8Ue4B4密码:o5r1]注意事项音频格式限制pcm(不压缩)、wav、amr采样频率及位数支持评测8k/16k
加固与脱壳05 - 壳类型识别
二手的程序员
加固与脱壳 网络安全 安全 网络 开发语言 前端
以前一些老旧的技术就不介绍了,比如,动态加载、内存不落地加载的方式。现在的加壳类型分为3种:指令抽取VMPdexc2chttps://www.dingxiang-inc.com/blog/post/2指令抽取android的指令抽取,主要在于函数基本的抽取保护。通过使用android虚拟机自带的解释器进行执行代码。将原始App中dex文件的函数内容进行清除,并将单独移动到一个加密文件中,在App运
python_学习爬虫遇到的第一个问题_urllib获取baidu首页源代码
KJDETL
python_爬虫 python 学习 爬虫
第一天学习爬虫,学习的是urllib的基本用法,通过urllib.request获取baidu首页源代码。#导入urllib所需要的库importurllib.request#左边自定义名称,右边是要访问的地址url='https://www.baidu.com/Index.htm'#左边自定义名称可以叫做响应,右边是通过urllib.request.urlopen方法向url发出请求respon
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