servlet帮助文档提交后总出现异常,求帮助

求帮助:javax.servlet.jsp.JspException:Input/output error_百度知道
求帮助:javax.servlet.jsp.JspException:Input/output error
我有更好的答案
在运行的时候,因为会优先加载项目中的包.jar跟tomcat6的lib中同样的包,但版本比tomcat6的版本要低因为项目中有像jsp-api,所以 产生了错误,把项目中和tomcat相同的包删除(必须删除.jar servlet-api
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Spring-Session实现Session共享实现原理以及源码解析 - 阿飞-dufyun - 博客园
随笔 - 69, 文章 - 0, 评论 - 20, 引用 - 0
知其然,还要知其所以然 !
本篇介绍Spring-Session的整个实现的原理。以及对核心的源码进行简单的介绍!
实现原理介绍
实现原理这里简单说明描述:
就是当Web服务器接收到http请求后,当请求进入对应的Filter进行过滤,将原本需要由web服务器创建会话的过程转交给Spring-Session进行创建,本来创建的会话保存在Web服务器内存中,通过Spring-Session创建的会话信息可以保存第三方的服务中,如:redis,mysql等。Web服务器之间通过连接第三方服务来共享数据,实现Session共享!
整个实现流程和源码详细介绍
本次源码介绍基于上一篇内容,并且在保存Session的时候只会分析使用JedisConnectionFactory实现的RedisConnectionFactory !
1.SessionRepositoryFilter和JedisConnectionFactory注册过程
1.、启动WEB项目的时候,会读取web.xml,读取顺序content-param --& listener --& filter --& servlet
2.、ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息
3、初始化根web应用程序上下文。
4、SpringHttpSessionConfiguration注册 springSessionRepositoryFilter :bean,RedisHttpSessionConfiguration 注册 sessionRedisTemplate : bean
和 sessionRepository : bean
45、配置文件配置JedisConnectionFactory implements RedisConnectionFactory ,创建 jedisConnectionFactory bean
代码分析如下:
web.xml ,加载了xml配置文件,并初始化web应用上下文
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&classpath*:spring/*xml&/param-value&
&/context-param&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
2.application-session.xml中,配置 RedisHttpSessionConfiguration的bean和JedisConnectionFactory的bean,web应用初始化加载bean!
&!--创建一个Spring Bean的名称springSessionRepositoryFilter实现过滤器。
筛选器负责将HttpSession实现替换为Spring会话支持。在这个实例中,Spring会话得到了Redis的支持。--&
&bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/&
&!--创建了一个RedisConnectionFactory,它将Spring会话连接到Redis服务器。我们配置连接到默认端口(6379)上的本地主机!--&
&!--集群Redis--&
&bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"&
&!--Redis-CLuster--&
&constructor-arg index="0" ref="redisClusterConfig"/&
&!--配置Redis连接池 ,可以不配置,使用默认就行!--&
&constructor-arg index="1" ref="jedisPoolConfig"/&
* 初始化根web应用程序上下文。
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
4.RedisHttpSessionConfiguration类图
RedisHttpSessionConfiguration继承了SpringHttpSessionConfiguration
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
implements EmbeddedValueResolverAware, ImportAware {
4.1 SpringHttpSessionConfiguration 创建一个名称为springSessionRepositoryFilter的bean
public &S extends ExpiringSession& SessionRepositoryFilter&? extends ExpiringSession& springSessionRepositoryFilter(
SessionRepository&S& sessionRepository) {
SessionRepositoryFilter&S& sessionRepositoryFilter = new SessionRepositoryFilter&S&(
sessionRepository);
sessionRepositoryFilter.setServletContext(this.servletContext);
if (this.httpSessionStrategy instanceof MultiHttpSessionStrategy) {
sessionRepositoryFilter.setHttpSessionStrategy(
(MultiHttpSessionStrategy) this.httpSessionStrategy);
sessionRepositoryFilter.setHttpSessionStrategy(this.httpSessionStrategy);
return sessionRepositoryF
4.2 创建RedisHttpSessionConfiguration#RedisTemplate bean的名称为sessionRedisTemplate
public RedisTemplate&Object, Object& sessionRedisTemplate(
RedisConnectionFactory connectionFactory) {
//实例化 RedisTemplate
RedisTemplate&Object, Object& template = new RedisTemplate&Object, Object&();
//设置key序列化 StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
//设置Hash key
StringRedisSerializer
template.setHashKeySerializer(new StringRedisSerializer());
if (this.defaultRedisSerializer != null) {
template.setDefaultSerializer(this.defaultRedisSerializer);
//设置 connectionFactory。第五步创建的(实际connectionFactory加载过程和讲解过程顺序不一样)
template.setConnectionFactory(connectionFactory);
4.3 创建RedisHttpSessionConfiguration#RedisOperationsSessionRepository bean的名称为sessionRepository
public RedisOperationsSessionRepository sessionRepository(
//使用sessionRedisTemplate bean
@Qualifier("sessionRedisTemplate") RedisOperations&Object, Object& sessionRedisTemplate,
ApplicationEventPublisher applicationEventPublisher) {
//實例化RedisOperationsSessionRepository
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
sessionRedisTemplate);
//設置applicationEventPublisher
sessionRepository.setApplicationEventPublisher(applicationEventPublisher);
//設置最大的失效時間 maxInactiveIntervalInSeconds = 1800
sessionRepository
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
if (this.defaultRedisSerializer != null) {
sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);
String redisNamespace = getRedisNamespace();
if (StringUtils.hasText(redisNamespace)) {
sessionRepository.setRedisKeyNamespace(redisNamespace);
sessionRepository.setRedisFlushMode(this.redisFlushMode);
return sessionR
创建 RedisConnectionFactory bean为 jedisConnectionFactory
&bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"&
2.SessionRepositoryFilter添加到FilterChain
1 2、在Servlet3.0规范中,Servlet容器启动时会自动扫描javax.servlet.ServletContainerInitializer的实现类,在实现类中我们可以定制需要加载的类。 通过注解@HandlesTypes(WebApplicationInitializer.class),让Servlet容器在启动该类时,会自动寻找所有的WebApplicationInitializer实现类。
2.1、insertSessionRepositoryFilter 方法通过filterName获取 SessionRepositoryFilter ,并创建了 new DelegatingFilterProxy(filterName);
3 4、然后将filter添加到FilterChain中
(WebApplicationInitializer.class)实现类的加载
//加载实现类
@HandlesTypes(WebApplicationInitializer.class)
//SpringServletContainerInitializer实现ServletContainerInitializer
public class SpringServletContainerInitializer implements ServletContainerInitializer {
//------------
2.AbstractHttpSessionApplicationInitializer实现WebApplicationInitializer进行加载
@Order(100)
public abstract class AbstractHttpSessionApplicationInitializer
implements WebApplicationInitializer {
2.1 onStartup
public void onStartup(ServletContext servletContext) throws ServletException {
beforeSessionRepositoryFilter(servletContext);
if (this.configurationClasses != null) {
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
rootAppContext.register(this.configurationClasses);
servletContext.addListener(new ContextLoaderListener(rootAppContext));
//添加Filter
insertSessionRepositoryFilter(servletContext);
afterSessionRepositoryFilter(servletContext);
2.1.1.insertSessionRepositoryFilter
* 注册springSessionRepositoryFilter
* @param servletContext the {@link ServletContext}
private void insertSessionRepositoryFilter(ServletContext servletContext) {
// DEFAULT_FILTER_NAME = "springSessionRepositoryFilter"
String filterName = DEFAULT_FILTER_NAME;
//通过filterName创建 DelegatingFilterProxy
DelegatingFilterProxy springSessionRepositoryFilter = new DelegatingFilterProxy(
filterName);
String contextAttribute = getWebApplicationContextAttribute();
if (contextAttribute != null) {
springSessionRepositoryFilter.setContextAttribute(contextAttribute);
//根据filterName和上下文添加Filter到FilterChain
registerFilter(servletContext, true, filterName, springSessionRepositoryFilter);
registerFilter
private void registerFilter(ServletContext servletContext,
boolean insertBeforeOtherFilters, String filterName, Filter filter) {
Dynamic registration = servletContext.addFilter(filterName, filter);
if (registration == null) {
throw new IllegalStateException(
"Duplicate Filter registration for '" + filterName
+ "'. Check to ensure the Filter is only configured once.");
//是否支持异步,默认 true
registration.setAsyncSupported(isAsyncSessionSupported());
//得到DispatcherType springSessionRepositoryFilter
EnumSet&DispatcherType& dispatcherTypes = getSessionDispatcherTypes();
//添加一个带有给定url模式的筛选器映射和由这个FilterRegistration表示的过滤器的分派器类型。 过滤器映射按照添加它们的顺序进行匹配。
registration.addMappingForUrlPatterns(dispatcherTypes, !insertBeforeOtherFilters,
addFilter将Filter添加到ServletContext中
public FilterRegistration.Dynamic addFilter(
String filterName, Filter filter);
3.SessionRepositoryFilter拦截过程
1、请求被DelegatingFilterProxy : 拦截到,然后执行doFilter方法,在doFilter中找到执行的代理类。
2、OncePerRequestFilter : 代理Filter执行doFilter方法,然后调用抽象方法doFilterInternal
3、SessionRepositoryFilter 继承了OncePerRequestFilter,实现了doFilterInternal,这个方法一个封装一个wrappedRequest,通过执行commitSession保存session信息到redis
1请求进来,被DelegatingFilterProxy 拦截到,在web.xml中进行了配置
1.1 执行doFilter
如果没有指定目标bean名称,请使用筛选器名称。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 如果需要,延迟初始化委托。 necessary.
Filter delegateToUse = this.
if (delegateToUse == null) {
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: " +
"no ContextLoaderListener or DispatcherServlet registered?");
this.delegate = initDelegate(wac);
delegateToUse = this.
// 让委托执行实际的doFilter操作
invokeDelegate(delegateToUse, request, response, filterChain);
1.2 initDelegate
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
//可以获取到SessionRepositoryFilter [备注1]
Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
//[备注1] 因为 :SessionRepositoryFilter是一个优先级最高的javax.servlet.Filter
@Order(SessionRepositoryFilter.DEFAULT_ORDER)
public class SessionRepositoryFilter&S extends ExpiringSession&
extends OncePerRequestFilter {
delegate.doFilter();
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//代理去执行doFilter,代理为SessionRepositoryFilter
delegate.doFilter(request, response, filterChain);
2.1 OncePerRequestFilter#doFilter
public final void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
if (!(request instanceof HttpServletRequest)
|| !(response instanceof HttpServletResponse)) {
throw new ServletException(
"OncePerRequestFilter just supports HTTP requests");
HttpServletRequest httpRequest = (HttpServletRequest)
HttpServletResponse httpResponse = (HttpServletResponse)
boolean hasAlreadyFilteredAttribute = request
.getAttribute(this.alreadyFilteredAttributeName) !=
if (hasAlreadyFilteredAttribute) {
//在不调用此过滤器的情况下进行…
filterChain.doFilter(request, response);
// 调用这个过滤器…
request.setAttribute(this.alreadyFilteredAttributeName, Boolean.TRUE);
//doFilterInternal是个抽象方法
doFilterInternal(httpRequest, httpResponse, filterChain);
// 删除此请求的“已过滤”请求属性。
request.removeAttribute(this.alreadyFilteredAttributeName);
执行SessionRepositoryFilter#doFilterInternal
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
//使用HttpServletRequest 、HttpServletResponse和servletContext创建一个SessionRepositoryRequestWrapper
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(
request, response, this.servletContext);
SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(
wrappedRequest, response);
//使用CookieHttpSessionStrategy重新包装了 HttpServletRequest
HttpServletRequest strategyRequest = this.httpSessionStrategy
.wrapRequest(wrappedRequest, wrappedResponse);
HttpServletResponse strategyResponse = this.httpSessionStrategy
.wrapResponse(wrappedRequest, wrappedResponse);
//执行其他过滤器
filterChain.doFilter(strategyRequest, strategyResponse);
//保存session信息
wrappedRequest.commitSession();
4 .wrappedRequest.commitSession() 看下第四大点分析
4.SessionRepository保存session数据
1、提交session保存
2、获取当前session,这一步比较重要,获取了一个HttpSessionWrapper,这个HttpSessionWrapper替换了HTTPSession
3、wrappedSession获取当前的Session
4、使用 RedisTemplate 保存Session内容,并通过调用RedisConnection 使用它的实现类JedisClusterConnection获取redis连接
1.commitSession
*使用HttpSessionStrategy将会话id写入响应。 *保存会话。
private void commitSession() {
HttpSessionWrapper wrappedSession = getCurrentSession();
if (wrappedSession == null) {
if (isInvalidateClientSession()) {
SessionRepositoryFilter.this.httpSessionStrategy
.onInvalidateSession(this, this.response);
S session = wrappedSession.getSession();
SessionRepositoryFilter.this.sessionRepository.save(session);
if (!isRequestedSessionIdValid()
|| !session.getId().equals(getRequestedSessionId())) {
SessionRepositoryFilter.this.httpSessionStrategy.onNewSession(session,
this, this.response);
2.getCurrentSession
会话存储库请求属性名。
public static final String SESSION_REPOSITORY_ATTR = SessionRepository.class
.getName();
private static final String CURRENT_SESSION_ATTR = SESSION_REPOSITORY_ATTR
+ ".CURRENT_SESSION";
private HttpSessionWrapper getCurrentSession() {
return (HttpSessionWrapper)
//获取session
getAttribute(CURRENT_SESSION_ATTR);
* 此方法的默认行为是在包装请求对象上调用getAttribute(字符串名称)。
public Object getAttribute(String name) {
//这里的request就是上面封装的
return this.request.getAttribute(name);
3 .wrappedSession.getSession
//返回 RedisSession
S session = wrappedSession.getSession();
//-------------------------
public S getSession() {
return this.
class ExpiringSessionHttpSession&S extends ExpiringSession& implements HttpSession {
final class RedisSession implements ExpiringSession {
4.save,实际是调用 RedisOperationsSessionRepository的 RedisOperations 操作
SessionRepositoryFilter.this.sessionRepository.save(session);
//this.sessionRepository =
SessionRepository&S& sessionR
//--------------------------------
//这个RedisOperationsSessionRepository是之前就创建好的
public class RedisOperationsSessionRepository implements
FindByIndexNameSessionRepository&RedisOperationsSessionRepository.RedisSession&,
MessageListener {
public interface FindByIndexNameSessionRepository&S extends Session&
extends SessionRepository&S& {
//---------------------------
public void save(RedisSession session) {
//4.1saveDelta
session.saveDelta();
if (session.isNew()) {
String sessionCreatedKey = getSessionCreatedChannel(session.getId());
//4.3convertAndSend
//RedisOperations = this.sessionRedisOperations
this.sessionRedisOperations.convertAndSend(sessionCreatedKey, session.delta);
session.setNew(false);
其中RedisOperationsSessionRepository 里面介绍保存的详细过程,具体请看文档说明:
因为 RedisTemplate implements RedisOperations,实际进行操作的是RedisTemplate,RedisTemplate通过RedisConnection进行数据add和remove等
public class RedisTemplate&K, V&
extends RedisAccessor
implements RedisOperations&K, V&, BeanClassLoaderAware
本系列到这里也就结束了,本次话的整个流程图,会上传到github上,使用Jude打开就可以看!
如果有什么地方写的不对或者有想和我一起探讨一下的,欢迎加我的QQ或者QQ群!
记录一个小点:
Spring Session + Redis实现分布式Session共享 有个非常大的缺陷, 无法实现跨域名共享session , 只能在单台服务器上共享session , 因为是依赖cookie做的 , cookie 无法跨域 pring Session一般是用于多台服务器负载均衡时共享Session的,都是同一个域名,不会跨域。你想要的跨域的登录,可能需要SSO单点登录。
本系列教程
如果您觉得这篇博文对你有帮助,请点个赞,让更多的人看到,谢谢!
如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!祝你今天开心愉快!
欢迎访问我的csdn博客,我们一同成长!
"不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"
博客首页:最近在学习Spring boot,写了个读写分离。并未照搬网文,而是独立思考后的成果,写完以后发现从零开始写读写分离并不难! 我最初的想法是: 读方法走读库,写方法走写库(一般是主库),保证在Spring提交事务之前确定数据源.
保证在Spring提交事务之前确定数据源,这个简单,利用AOP写个切换数据源的切面,让他的优先级高于Spring事务切面的优先级。至于读,写方法的区分可以用2个注解。 但是如何切换数据库呢? 我完全不知道!多年经验告诉我 当完全不了解一个技术时,先搜索学习必要知识,之后再动手尝试。
我搜索了一些网文,发现都提到了一个AbstractRoutingDataSource类。查看源码注释如下 /** Abstract {@link javax.sql.DataSource} implementation that routes {@link #getConnection()}
* calls to one of various target DataSources based on a lookup key. The latter is usually
* (but not necessarily) determined through some thread-...
摘要: 原创出处 http://www.iocoder.cn/TCC-Transaction/dubbo-support/ 「芋道源码」欢迎转载,保留摘要,谢谢! **本文主要基于 TCC-Transaction 1.2.3.3 正式版** - [1. 概述](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2. Dubbo 代理](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.1 JavassistProxyFactory](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.1.1 Javassist](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.1.2 TccJavassistProxyFactory](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.1.3 TccProxy & TccClassGenerator](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.1.4 配置 Dubbo Proxy](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.2 JdkProxyFactory](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.2.1 JDK Proxy](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.2.2 TccJdkProxyFactory](http://www.iocoder.cn/TCC-Transaction/dubbo-support/) - [2.2.3 TccInvokerInvocationHandler](http://www...
合约实现了报名,退出,参加人数控制,竞猜次数控制,公布答案,获奖名单等等功能
1 文档说明 该文档描述的是以storm为主体的实时处理架构,该架构包括了数据收集部分,实时处理部分,及数据落地部分。 关于不同部分的技术选型与业务需求及个人对相关技术的熟悉度有关,会一一进行分析。 该架构是本人所掌握的一种架构,可能会与其他架构有相似的部分,个人会一一解释对其的理解。 这个文章写的很详细,相信对大家在实时处理整体理解上会有帮助的。
2 实时处理架构 2.1 整体架构图 架构说明: 整个数据处理流程包括四部分,一部分是数据接入层,该部分从前端业务系统获取数据;中间部分是最重要的storm实时处理部分,数据从接入层接入,经过实时处理后传入数据落地层;第三部分为数据落地层,该部分指定了数据的落地方式;第四部分元数据管理器。
2.2 数据接入层 该部分有多种数据收集方式,包括使用消息队列(MetaQ),直接通过网络Socket传输数据,前端业务系统专有数据采集API,对Log问价定时监控。 2.2.1 MetaQ 为什么选择消息队列? 这或许是大家比较疑惑的地方,会疑惑为什么不把数据直接导入storm中。使用消息队列作为数据中间处理组件的原因是,在大批量数据处理时,前端业务数据产生速度可能会很快,而实时处理或者其他处理速度跟不上...
SpringDataJPA是Spring Data的一个子项目,通过提供基于JPA的Repository极大的减少了JPA作为数据访问方案的代码量,你仅仅需要编写一个接口集成下SpringDataJPA内部定义的接口即可完成简单的CRUD操作。
# 准备阶段 ## 下载 Flutter SDK 新建 Flutter 文件夹,克隆 Flutter SDK: ```bash git clone -b beta https://github.com/flutter/flutter.git ``` ## 配置 Flutter 环境 我是 Mac 系统,Flutter SDK 下载完后的路径:Users/wuxiaolong/Flutter/flutter/ 。 ### 在命令行下,进入用户目录 ```bash cd $HOME ``` ### 打开.bash_profile文件 执行命令打开文件: ```bash open -e .bash_profile ``` 打开文件后,添加 Flutter SDK 安装的路径: ```bash export PATH=${PATH}:/Users/wuxiaolong/Flutter/flutter/bin:$PATH ``` ### 更新刚配置的环境变量 ```bash source .bash_profile ``` ### 验证 终端直接输入 flutter,没有提示该命令找不到,则配置成功。 ## flutter doctor 命令行输入`flutter doctor`,安装 Futter 剩余依赖项。 ## 安装 Flutter 和 Dart 插件 启动 Android Studio,搜索 Flutter 插件并单击 install,系统提示您安装 Dart 插件,点击 Yes 安装即可。 **提示**:安装 Dart 插件可能会提示下载失败,多试几次。 ## 第一个项目 Android Studio - File - New - New Flutter Project,等待创建成功后,运行效果如下: ![](http://7q5c2h.com1.z0.glb.clou...
JDK 10 是 Java 10 标准版的部分实现,将于 2018 年 3 月 20 日发布,改进的关键点包括一个本地类型推断、一个垃圾回收的“干净”接口。
![](https://ws3.sinaimg.cn/large/006tNc79gy1fp5xm7uykoj30v90kugng.jpg) ## 前言 不管是在面试还是实际开发中 `volatile` 都是一个应该掌握的技能。 首先来看看为什么会出现这个关键字。 ## 内存可见性 由于 `Java` 内存模型(`JMM`)规定,所有的变量都存放在主内存中,而每个线程都有着自己的工作内存(高速缓存)。 线程在工作时,需要将主内存中的数据拷贝到工作内存中。这样对数据的任何操作都是基于工作内存(效率提高),并且不能直接操作主内存以及其他线程工作内存中的数据,之后再将更新之后的数据刷新到主内存中。 & 这里所提到的主内存可以简单认为是**堆内存**,而工作内存则可以认为是**栈内存**。 如下图所示: ![](https://ws2.sinaimg.cn/large/006tKfTcly1fmouu3fpokj31ae0osjt1.jpg) 所以在并发运行时可能会出现线程 B 所读取到的数据是线程 A 更新之前的数据。 显然这肯定是会出问题的,因此 `volatile` 的作用出现了: & 当一个变量被 `volatile` 修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据。 *`volatile` 修饰之后并不是让线程直接从主内存中获取数据,依然需要将...
你一个真的的Kotlin开发者吗?
& 今天继续来聊Spring Boot 2.0的新特性。本文将具体说说2.0版本中的事件模型,尤其是新增的事件:`ApplicationStartedEvent`。 & & 原文首发:http://blog.didispace.com/Spring-Boot-2-0-feature-2-ApplicationStartedEvent/ 在Spring Boot 2.0中对事件模型做了一些增强,主要就是增加了`ApplicationStartedEvent`事件,所以在2.0版本中所有的事件按执行的先后顺序如下: - `ApplicationStartingEvent` - `ApplicationEnvironmentPreparedEvent` - `ApplicationPreparedEvent` - `ApplicationStartedEvent` &= 新增的事件 - `ApplicationReadyEvent` - `ApplicationFailedEvent` 从上面的列表中,我们可以看到`ApplicationStartedEvent`位于`ApplicationPreparedEvent`之后,`ApplicationReadyEvent`之前。 下面我们通过代码的方式来直观的感受这个事件的切入位置,以便与将来我们在这个切入点加入自己需要的逻辑。 第一步:我们可以编写`ApplicationPreparedEvent`、`ApplicationStartedEvent`以及`ApplicationReadyEvent`三个事件的监听器,然后在这三个事件触发的时候打印一些日志来观察它们各自的切入点,比如: ```java @Slf4j public class ApplicationPreparedEve...
上一篇博文中,我们介绍了如何搭建一个Eureka服务的架构,但是服务提供者我们只用了一个单例,完全不能体现高并发高可用。本文我们尝试在上一篇文章示例Eureka项目的基础上继续完善,让它可以做到一个集群的部署。 Eureka集群架构 我们先看一下我们这次示例打算改造成的架构图: 在我们的Eureka服务器里面会启动两个实例,这两个实例会相互注册。 然后服务提供者也会启动两个实例,这两个实例都会注册到我们服务器的两个实例,是的,像图中那样一个服务提供者实例分别向两个服务器实例注册。 服务调用者也会注册到两个服务器实例上面。 最后我们会编写一个Rest客户端,去调用服务调用者的站点端口,来测试服务调用的过程。 我们还用上文的比方继续比喻,Eureka服务器相当于114电话查询平台,而两个Eureka服务器实例相当于两个114接线员。某某酒店现在要提供电话服务,于是在114注册,它就是服务提供者。由于业务扩大,十分繁忙,我们需要提供接听电话的效率和及时性,类似于服务提供者需要高并发高可用,于是酒店也弄了两个接线员,相当于两个服务提供者实例。而一个客户想请求酒店服务,首先回去114查询这家酒店的电话,但是114是哪位接线员提供的服务信息和电话号码,我们...
如何将区块链嫁接到游戏领域,我做了很多思考,经过分析总结,发现下面几项内容非常适合上链。
前言 数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能;对于MySQL来说,标准的读写分离是主从模式,一个写节点Master后面跟着多个读节点,其中包含两个步骤,其一是数据源的主从同步,其二是sql的读写分发;而Mycat不负责任何数据的同步,具体的数据同步还是依赖Mysql数据库自身的功能。 Mysql主从复制 准备两台主机,安装相同版本的Mysql数据库,下面准备配置Mysql的主从复制配置: 1.配置Master 配置my.ini或者my.conf如下: server-id=1
binlog_format=STATEMENT
log_bin=D:/mysql/bin-log.log server-id:一般设置为IP,注意要唯一;binlog_format:设置binlog的格式;log_bin:开启log_bin 2.配置Slave 配置my.ini或者my.conf如下: server-id=2
binlog_format=STATEMENT
relay_log=mysql-relay-bin relay_log:从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后SQL线程会读取relay-log日志的内容并应用到从服务器; 更多binlog的配置:https://my.oschina.net/OutOfMemory/blog/.分别重启Master和Slave se 4.查询Master的状态 mysql&
+----------...
1、故障发现 通过ping/pong消息实现故障发现:不需要Sentinel 跟Sentinel一样,有主观下线和客观下线 2、主观下线 定义:某个节点认为另一个节点不可用,“偏见” 主观下线流程: 3、客观下线 定义:当半数以上持有槽的主节点都标记某节点主观下线 客观下线流程: 4、尝试客观下线 通知集群内所有节点标记故障节点为客观下线 通过故障节点的从节点触发故障转移流程
5、故障恢复 (1)资格检查 每个从节点检查与故障主节点的断线时间 超过 cluster-node-timeout * cluster-slave-validity-factor 取消资格。 cluster-slave-validity-factor : 默认是10 (2)准备选举时间 (3)选举投票 (4)替换主节点 当前从节点取消复制变为主节点(slaveof no one) 执行clusterDelSlot撤销故障主节点负责的槽,并执行clusterAddSlot把这些槽分配给自己。 向集群广播自己的pong消息,表明已经替换了故障从节点 6、故障演练 7、具体步骤 执行kill -9 节点模拟拖机 观察客户端故障恢复时间 观察各个节点的日志...
先看代码: https://play.golang.org/p/GlM23bSW6zf
可见: 1. for 循环变量只有一份
2. 单行的defer和go都是在当前时刻求值。
如果方法的修饰符是一个指针,那么求值得到的必报是保存了这个指针的值的,如果指针指向内存发生变化,后续取得的数据也会变。
如果方法的修饰符是一个对象,那么单行的defer和go在求值时刻,会保存这个对象,无论后续这个对象怎么变,取得数值是不变的。 3. 如果是 go/defer 后面跟一个 func()的形式,那么func()内部代码捕获的外部变量都是指针引用,我之前的Blog已经有详述,这里不再重复。
OAuth2.0之OLTU实现举例
首次接触 Springboot,只能从官方文档开始。现在是文档的开始部分,记录一下。
对于无状态的web服务,要做分布式部署相对比较简单,很多时候只要架一个反向代理就行。但是对于有状态的web服务,尤其是包含WebSocket成分的web应用,要做分布式部署一直是一个麻烦。传统做法是搞一个中间层,例如Redis之类的做pubsub,但是这样做就不得不改动源码。Erlang/Elixir这种“面向并发编程”的语言在这方面会不会高人一筹?Phoenix框架是否已经支持WebSocket的横向扩展了呢?下面我们就来做个实验。
1、其实elasticsearch就像是一个数据库一样,index相当于mysql里的数据库database,type相当于mysql的table,field相当于表里面的字段。只不过elasticsearch擅长长文本的存储和查询,mysql擅长处理数据之间的关系。 2、pom文件 &properties&
&spring.version&4.2.0.RELEASE&/spring.version&
&findbugs.annotations&2.0.0&/findbugs.annotations&
&checkstyle.maven.plugin&2.11&/checkstyle.maven.plugin&
&pmd.maven.plugin&3.0&/pmd.maven.plugin&
&findbugs.maven.plugin&2.5.3&/findbugs.maven.plugin&
&java.version&1.7&/java.version&
&/properties&
&dependencies&
&dependency&
&groupId&junit&/groupId&
&artifactId&junit&/artifactId&
&version&4.12&/version&
&scope&test&/scope&
&/dependency&
&!-- spring begin --&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-context&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-context-support&/artifactId&
&version&${...
笔记和代码都放在码云:https://gitee.com/tangijia/anguarjs_learning_notes
############################# System ############################# #唯一标识在集群中的ID,要求是正数。 broker.id=0 #服务端口,默认9092 port=9092 #监听地址,不设为所有地址 host.name=debugo01 #处理网络请求的最大线程数 num.network.threads=2 #处理磁盘I/O的线程数 num.io.threads=8 #一些后台线程数 background.threads = 4 #等待IO线程处理的请求队列最大数 queued.max.requests = 500 #socket的发送缓冲区(SO_SNDBUF) socket.send.buffer.bytes=1048576 #socket的接收缓冲区 (SO_RCVBUF) socket.receive.buffer.bytes=1048576 #socket请求的最大字节数。为了防止内存溢出,message.max.bytes必然要小于 socket.request.max.bytes =
############################# Topic ############################# #每个topic的分区个数,更多的partition会产生更多的segment file num.partitions=2 #是否允许自动创建topic ,若是false,就需要通过命令创建topic auto.create.topics.enable =true #一个topic ,默认分区的replication个数 ,不能大于集群中broker的个数。 default.replication.factor =1 #消息体的最大大小,单位是字节 message.max.by...
由于众所周知的原因,至今仍有大量生产环境的代码跑在 Python 2.7 之上,在 Python 2 的世界里,并没有一个官方的类型系统实现。那么生产环境的类型系统是如何实现的呢,为什么一定要在在线服务上实现类型系统?下文将针对这两个问题进行深入讨论。
一、出错情况
Navicat远程连接Oracle错误:ORA-28547:connection to server failed, probable Oracle Net admin error 二、解决方案 1、查找oralce安装目录中app\Administrator\product\11.2.0\dbhome_1\BIN中的oci.dll 2、复制oci.dll到Navicat的安装目录,并备份原本的oci.dll 3、打开Navicat中的工具-&选项-&OCI (直接指到复制的oci.dll中,若直接指到Oracle的oci.dll,可略过第二步骤) 参考地址:http://blog.csdn.net/dmaker1993/article/details/
**本文为原创文章,转载请标明[出处](http://metaphors.name/coding//Ionic16.html)** 个人做的开源 Demo 登录注册模块采用的是 [Wilddog 野狗通讯云](https://www.wilddog.com)的身份认证服务,不得不说各方面和 Google 收购的 Firebase 很像,十分简单易用。其中 `User` 有个 `photoURL` 字段是用来存放用户头像 URL 的,所以寻思着找了个免费的第三方图床([SM.MS](https://sm.ms))来存放用户头像。 用到的 Cordova 插件是 [Camera](https://ionicframework.com/docs/native/camera/) 和 [File Transfer](https://ionicframework.com/docs/native/file-transfer/),分别用来拍照、相册选择和上传图片,Cordova 插件的安装、导入、使用我就不赘述了,文档里都有,so 直接上关键代码。 ``` getPictureAndUpload(sourceType: number) { const cameraOptions: CameraOptions = { quality: 80, destinationType: this.camera.DestinationType.FILE_URI, sourceType: sourceType, allowEdit: true, encodingType: this.camera.EncodingType.JPEG, targetWidth: 200, targetHeight: 200, mediaType: this.camera.MediaType.PICTURE, correctOrientation: true, sa...
## 环境 系统: CentOS7 - 下载 websocketd [websocketd-0.3.0-linux_amd64.zip](https://github.com/joewalnes/websocketd/releases/download/v0.3.0/websocketd-0.3.0-linux_amd64.zip) - 安装 nc 命令 ```bash yum install nmap-ncat ``` - 生成监听脚本 ```bash cat & cmd.sh &&-END #!/bin/bash pid=65536 while :; do if [ -f /proc/$pid/stat ]; then sleep 2 continue fi pkill -x nc && sleep 2 nc -l -p 10089 & pid=$! done ``` - 启动 websocketd ```bash ./websocketd --port=8002 --staticdir=. ./cmd.sh ``` - 编辑 log.html ```html 实时日志清空 ``` - 把 log.html 放在 websocketd 的 staticdir 位置,用浏览器访问该页面 - 在其他应用服务器,传输实时日志 ```bash tail -f /tomcat/logs/catalina.out | nc {ws-server} 10089 ```...
在项目运行过程中,是不是各种异常,如果我们每个都需要用 try{}catch(Exception e){}
的话,那么就会写特别特别多的重复代码,就会显得非常low,所以Spring为我们提供了全局异常处理机制,我们只需要往外抛异常就可以了: 1: 自定义异常类(没有不影响,只演示一下) package com.gy.demo.common.
* Description: 参数异常类
* @author geYang
public class ParamException extends RuntimeException {
public ParamException(ResultEnum resultEnum){
super(resultEnum.getMessage());
this.code = resultEnum.getCode();
public int getCode () {
public void setCode (int code) {
this.code =
2: 自定义返回状态枚举 package com.gy.demo.common.
* Description: 返回结果状态码
* @author geYang
public enum ResultEnum {
PARAM_NULL(401,"参数为空"),
PARAM_ERROR(402,"参数异常"),
SUCCESS(200,"SUCCESS"),
RETURN_NULL(201,"返回值为空"),
private String messa...
## 序 本文主要研究怎么在docker的java9镜像上运行springboot2并精简jdk. ## maven ``` org.springframework.boot spring-boot-starter-parent 2.0.0.RC2 UTF-8 UTF-8 9 com.example.demo.DemoApplication ``` &注意springboot得2版本才能支持java9,另外这个java.version设置为9 &这里maven用的版本是3.3.3 ## mvn package ``` mvn clean package -Dmaven.test.skip=true //...... WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by lombok.javac.apt.LombokProcessor to field com.sun.tools.javac.processing.JavacProcessingEnvironment.discoveredProcs WARNING: Please consider reporting this to the maintainers of lombok.javac.apt.LombokProcessor WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release ``` &可以看到这里可以编译成功,但是有WARNING ## docker构建 ### Dockerfile ``` FROM dekstroza/openjdk9-alpine as packager # First stage: JDK 9 with modules ...
SpringMVC的工作原理图: SpringMVC流程 1、
用户发送请求至前端控制器DispatcherServlet。 2、
DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、
处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 4、
DispatcherServlet调用HandlerAdapter处理器适配器。 5、
HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。 6、
Controller执行完成返回ModelAndView。 7、
HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。 8、
DispatcherServlet将ModelAndView传给ViewReslover视图解析器。 9、
ViewReslover解析后返回具体View。 10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 11、 DispatcherServlet响应用户。 组件说明: 以下组件通常使用框架提供实现: DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。 HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式...
设置 tab为4个空格 hard-tabs是硬件tab,就是按一个tab键,soft-tabs是软件tab,通过按4个space键实现。
设置编码为gbk(如果使用utf8有中文乱码的话)
设置exe文件不显示,将*.exe加入即可,在setting 中 tree-view 设置不显示指定类型文件
安装 插件 activate-power-mode
atom-beautify
去sorceforge上找uncrustify项目下载并解压,之后将解压好的uncrustify插件复制到.atom/packages/目录下面。
将uncrustify的目录添加到环境变量path路径下。
修改atom编辑器中的atom-beautify插件中对应的开发语言中的config path配置文件路径,若为空则是默认的代码格式化格式,个人觉得太丑了。这时候应该去C:\Users\Administrator.atom\packages\atom-beautify\examples\nested-jsbeautifyrc目录下找到uncrustify.cfg文件,将其添加到对应开发语言下的config path路径中。博主是将uncrustify.cfg文件拷贝到uncrustify插件目录下了。
file-icons gcc-make-run
配置g++路径,需要安装mingw
gpp-compiler
运行c++ Windows 使用 linter-cnew 代替linter-gcc,但是会出现一些bug,于是没有使用。。。...
公布OPMS、CSOA、CSCRM、CSPM、EPMS、EPMS SASS六款应用系统的平台的帐号与密码,用户可以进行体验和试用,有好的意见可进行反馈。 OPMS: 网址:http://opms.demo.milu365.cn 用户名:libai 密码:opmsopms123 CSOA: 网址:http://csoa.demo.milu365.cn 用户名:libai 密码:123456 CSPM: 网址:http://cspm.demo.milu365.cn 用户名:libai 密码:123456 CSCRM: 网址:http://cscrm.demo.milu365.cn 用户名:libai 密码:123456 EPMS企业版与EPMS 云平台: 网址:http://epms.demo.milu365.cn 用户名:libai 密码:123456
================================== EPMS云平台: 网址:http://epms.milu365.cn
编译一套LAMP服务器
系统文件,用户文件两种选择。 1.系统级: (1)/etc/profile:该文件是用户登录时,操作系统定制用户环境时使用的第一个文件,应用于登录到系统的每一个用户。该文件一般是调用/etc/bash.bashrc文件。   /etc/bash.bashrc:系统级的bashrc文件。 (2)/etc/environment:在登录时操作系统使用的第二个文件,系统在读取你自己的profile前,设置环境文件的环境变量。 2.用户级(这些文件处于home目录下): (1)~/.profile:【推荐】每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件。这里是推荐放置个人设置的地方 (2)~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被读取。不推荐放到这儿,因为每开一个shell,这个文件会读取一次,效率肯定有影响。   ~/.bash_profile or ~./bash_login:当这个文件存在时,在登录shell时会读取./bash_profile文件,而不是.profile文件。我认为该文件实现的目的 跟.profile文件是一样的,当查找的资料中需要你修改.bash_profile文件,但却你没有该文件的时候,也可以修改.profile来完成 实现...
### 问题背景 &我们的项目要拿到客户机上做私有化安装,服务器操作系统客户指定只能使用redhat7.2版本,且客户机为了保密需要不能访问外网,而操蛋的redhat系统自带的curl支持的是nss协议的https,而非openssl协议的https,执行curl访问https站点的时候会出现无法load key的报错。 网上查了一下解决方案,Stack Overflow上有答案说是生成的key的问题,需要将key转换成RSA的加密方式,我试了一下,curl命令不会报错,但我们的服务端代码实现不能正常的初始化相关加解密容器。 还有部分答案推荐重装curl,由于对redhat系统并不熟悉,且向来听说linux上离线安装的时候需要处理的依赖比较复杂,我的内心其实是拒绝的,但没有更好的解决办法,只能硬着头皮上了。。。 ### 安装zlib 1. 访问zlib官网,下载最新的zlib包,这里由于我的rhel是较新的7.2版本,因此直接使用了zlib的最新版,如果是老版本,可能需要考虑linux内核的兼容性问题; 2. 解压缩zlib安装包,cd到解压缩的zlib包目录下,运行以下命令: ```shell ./configure make test make install #这里安装的是静态库 make clean ./configure --shared make test make install #这里先clean,然后安装的是共享库 cp zutil.h...
这两天公司项目部署阿里云k8s器生产环境,底包用的是java:8,Dockerfile文件为: ```dockerfile FROM java:8 VOLUME /var/xxx/xxx-point-log/ COPY app.jar /var/xxx/xxx-point/app.jar ENV RUN_LIB="/var/xxx/xxx-point/app.jar" ENV JAVA_OPTS=" -server -Xmx2048m -Xms1500m -Xmn1024m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 " RUN sh -c 'touch $RUN_LIB' ENTRYPOINT [ "sh", "-c", "nohup java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar $RUN_LIB &/var/xxx/xxx-point-log/xxx-point-log.log 2&&1" ] ``` 联调发现接口输出的时间戳总是比数据库中保存的时间多了8个小时,阿里云的sit和uat环境均没有问题,对比两边环境的时间配置也没发现问题,一时很疑惑。 突然想起来,sit和uat都是用虚机环境,只有生产是docker,结果进docker一看,果然时区不对。网上也很多相关的文章,处理方式也很简单,Docke...
PhpDesignPatterns 【PHP 中的设计模式】 一、 Introduction【介绍】 设计模式:提供了一种广泛的可重用的方式来解决我们日常编程中常常遇见的问题。设计模式并不一定就是一个类库或者第三方框架,它们更多的表现为一种思想并且广泛地应用在系统中。它们也表现为一种模式或者模板,可以在多个不同的场景下用于解决问题。设计模式可以用于加速开发,并且将很多大的想法或者设计以一种简单地方式实现。当然,虽然设计模式在开发中很有作用,但是千万要避免在不适当的场景误用它们。 二、 Category【分类】 根据目的和范围,设计模式可以分为五类。 按照目的分为:创建设计模式,结构设计模式,以及行为设计模式。 按照范围分为:类的设计模式,以及对象设计模式。 1. 按照目的分,目前常见的设计模式主要有23种,根据使用目标的不同可以分为以下三大类: 创建设计模式(Creational Patterns)(5种):用于创建对象时的设计模式。更具体一点,初始化对象流程的设计模式。当程序日益复杂时,需要更加灵活地创建对象,同时减少创建时的依赖。而创建设计模式就是解决此问题的一类设计模式。 单例模式【Singleton】 工厂模式【Factory】 抽象工厂模式【AbstractFactory】 建造者模式...
原因:小编写了一个项目想共享出来采用oschina的码云,采用idea编辑器,为了方便有需要的盆友上传特此记录 在oschina上创建一个项目,填写基础信息 复制创建项目的链接地址并打开idea编辑器选择check out from Version Control && git,把拷贝的路径复制到Git Repository URL && clone 会下载项目,中间编码过程小编就不介绍了,当我们编码一定程度后需要上传到git作为存储 选中项目 右键 && Git && 先Add 所有文件进行添加 && Commit Dierctory && 选择要上传的文件信息 && Commit 当我们Commit后并没有把数据推送给git 服务器 需要进行push操作 选中项目 右键 && Git && Repository &&
push 然后就上传成功了
允许网页获得来自服务器的更新,可用于服务器向客户端推送消息等,但客户端不能向服务器反推,即是单向通道,想使用双向通道,可使用WebSocket
在帮助小白解决了很多开源使用的问题后,我总结了小白的不科学的提问方式,以遭受9种伤害夸张的手法一一道来
我是程序猿,我的征途是星辰大海!
# 环境要求 1、Java SDK 1.8 [下载](http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html) 2、Eclipse IDE for Java EE Mars 2 (4.5.2) [下载](https://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/mars2) 3、Apache Maven 3.3+ [下载](https://maven.apache.org/download.cgi) 4、MySql 5.7+ [下载](https://dev.mysql.com/downloads/windows/installer/5.7.html) # 导入到Eclipse 1、检出JeeSite4源代码: ``` git clone https://gitee.com/thinkgem/jeesite4.git ``` 2、拷贝`web`文件夹,到你的工作目录(不包含中文和空格的目录)下,重命名为你的工程名,如:`jeesite-demo` 3、打开`pom.xml`文件,修改第13行,artifactId为你的工程名,如:`jeesite-demo` 4、导入到Eclipse,菜单 File -& Import,然后选择 Maven -& Existing Maven Projects,点击 Next& 按钮,选择第2步的`jeesite-demo`文件夹,然后点击 Finish 按钮,即可成功导入 5、这时,Eclipse会自动加载Maven依赖包,初次加载会比较慢(根据自身网络情况而定),若工程上有小叉号,请打开Problems窗口,查看具体错误内容,直到无错误为...
由于众所周知的原因,至今仍有大量生产环境的代码跑在 Python 2.7 之上,在 Python 2 的世界里,并没有一个官方的类型系统实现。那么生产环境的类型系统是如何实现的呢,为什么一定要在在线服务上实现类型系统?下文将针对这两个问题进行深入讨论。
微信自15年年底上线FOOM上报,每天FOOM次数与登录用户数比例接近3%,同期crash率1%不到。而16年年初某东老大反馈微信频繁闪退,接着16年8月不少外部用户反馈微信启动不久后闪退,分析大量日志还是不能找到FOOM原因。微信急需一个有效的内存监控工具来发现问题。
小光是一名私家侦探,是小光侦探事务所的负责人。这天,他正在事务所中喝茶,突然接到警官M的电话,说接到线上总共三台机器,有一台机器报警,Java堆内存占用超过95%,无法正常得到服务器的响应。小光安排警官M保留好现场,急匆匆的赶往了现场...
### Logstash ##### 使用yum安装 ###### 编辑 repo ``` vim /etc/yum.repos.d/elasticsearch.repo # 内容如下 [elasticsearch-6.x] name=Elasticsearch repository for 6.x packages baseurl=https://artifacts.elastic.co/packages/6.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md ``` ###### 安装 ``` sudo yum install logstash ``` #### 配置 Logstash ``` # 参考 https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html # input项配置源数据,此处为监听 "/log"目录下满足"insert.*.log"匹配的所有日志文件 # filter项过滤input输入的数据, "insert.*.log"中每条日志形式如:" | type | cid | src | eventId | reason", 所以使用" | "拆分每条日志 # output项是输出数据,此处为输出至ElasticSearch # 新建配置文件 insert.conf vim conf.d/insert.conf # 内容如下 input { file { path =& "/log/insert.*.log" } } filter { mutate{ split=&["message"," | "] add_field =& { "date" =& "%{[message][0]}" } add_field =& { "type" =& "%{[message][1]...
### 拷贝文件或文件夹 ``` /** * 拷贝文件 * * @param source 源文件 * @param target 目标文件 */ public void copyFile(String source, String target) { // 源文件 File sourceFile = new File(source); if (!sourceFile.exists()) { } // 目标文件 File targetFile = new File(target); // 文件拷贝 if (sourceFile.isFile()) { copyFromChanel(sourceFile, targetFile); } // 文件夹拷贝 if (!targetFile.exists()) { targetFile.mkdirs(); } for (File file: sourceFile.listFiles()) { copyFile(file.getAbsolutePath(), target + File.separator + file.getName()); } } ``` ### 利用文件管道拷贝文件 ``` /** * 利用文件管道拷贝文件 * * @param source 源文件 * @param target 目标文件 */ public void copyFromChanel(File source, File target) { // 文件流 FileInputStream fis = FileOutputStream fos = // 文件管道 FileChannel fci = FileChannel fco = try { // 文件流 fis = new FileInputStream(source); fos = new FileOutputStream(target); // 文件管道 fci = fis.getChannel(); fco = fos.getChannel(); ...
### 一.使用脚本切割 ##### 编辑脚本 ``` tianshl@tianshl nginx $ vim nginx_log_division.sh ``` ##### 脚本内容 ``` #! /bin/sh # 昨天日期 yesterday=`date -v -1d +%Y%m%d` # 日志目录 log_path="/usr/local/var/log/nginx/" # SDK日志路径 sdk_path=${log_path}sdk # 以天为单位切分日志 mv -f ${sdk_path}.log ${sdk_path}_${yesterday}.log # 重新生成日志文件 pid_path="/usr/local/var/run/nginx.pid" sudo kill -USR1 `cat ${pid_path}` ``` ##### 定时任务 ###### 切换到root身份 ``` tianshl@tianshl nginx $ sudo su root ``` ###### 编辑 crontab ``` sh-3.2# crontab -e ``` ###### crontab 添加一行 ``` 0 0 * * * sh /usr/local/var/log/nginx/nginx_log_division.sh ``` ###### 查看是否添加成功 ``` sh-3.2# crontab -l ``` ### 二.不使用脚本切割 ##### server 段增加以下代码 ``` if ($time_iso8601 ~ "(\d{4})-(\d{2})-(\d{2})") { set $time $1$2$3; } ``` ##### 日志文件路径中增加日期参数 ``` access_log /var/log/nginx/api-$time. ``` ##### 举个栗子 ``` events { worker_connections 1024; } http { server { # 监听88端口 listen 88;...
### 需求 ``` 对MySQL数据库中某个表的某个字段执行k-means算法,将处理后的数据写入新表中。 ``` ### 源码及驱动 ``` http://download.csdn.net/download/xiaobuding007/ ``` ### 源码 ```java import java.sql.*; import java.util.*; /** * @author tianshl * @version
上午11:13 */ public class Kmeans { // 源数据 private List origins = new ArrayList&&(); // 分组数据 private Map& // 初始质心列表 private L // 数据源 private String tableN private String colN /** * 构造方法 * * @param tableName 源数据表名称 * @param colName 源数据列名称 * @param cores 质心列表 */ private Kmeans(String tableName, String colName,List cores){ this.cores = this.tableName = tableN this.colName = colN } /** * 重新计算质心 * * @return 新的质心列表 */ private List newCores(){ List newCores = new ArrayList&&(); for(List v: grouped.values()){ newCores.add(v.stream().reduce(0, (sum, num) -& sum + num) / (v.size() + 0.0)); } Collections.sort(newCores); return newC } /...
## 更新model #### 需求 ``` 概览表增加"创建时间,修改时间,软删除" ``` #### 以往的方式 ###### 1. 修改model.jh, 在实体 Overview 中增加三个属性 ``` /** * 数据概览 -- 概览 */ entity Overview { id Long, ... /* 以下属性为新增的属性 */ /* 创建时间 */ createTime ZonedDateTime, /* 更新时间 */ updateTime ZonedDateTime, /* 是否删除 */ delFlag Boolean, } ``` ###### 2. 生成配置文件 ``` jhipster import-jdl model.jh ``` ###### 3. 运行项目使配置生效 ``` 运行项目时提示"Validation Failed",原因是配置文件的MD5值不同, 此时需要以下操作 1. 修改 DATABASECHANGELOG 表中相关记录的 MD5SUM 2. 在overview表中手动新增三个属性. ``` #### 现在的方式 ###### 1. 修改model.h, 在实体 Overview 中增加三个属性 ###### 2. 生成配置文件 ###### 3. 修改生成的配置文件 ``` src/main/resources/config/liquibase/changelog/15_added_entity_Overview.xml 将 changeSet中新增的三个column提取至新的changeSet中, 如下: 注意: changeSet的id不能与之前的相同 ``` ###### 4. 运行项目使配置生效 ``` 不需要手动修改MySQL,自动生效 ```...
### ElasticSearch ``` 现有三台服务器[192.168.1.30, 192.168.1.31, 192.168.1.32],使用这三台服务器搭建ElasticSearch集群 ``` #### CentOS 使用 yum 安装 ###### 编辑 repo ``` vim /etc/yum.repos.d/elasticsearch.repo # 内容如下 [elasticsearch-6.x] name=Elasticsearch repository for 6.x packages baseurl=https://artifacts.elastic.co/packages/6.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md ``` ###### 使用yum安装 ``` yum install elasticsearch ``` ###### 创建用户 ``` useradd elastic ``` ###### 修改权限 ``` # 数据 chown -R elastic:elastic /var/lib/elasticsearch # 日志 chown -R elastic:elastic /var/log/elasticsearch # 配置 chown -R elastic:elastic /etc/elasticsearch chown -R elastic:elastic /etc/sysconfig/elasticsearch # 指令 chown -R elastic:elastic /usr/share/elasticsearch ``` ###### 配置 ``` # 主节点 192.168.1.30 vim /etc/elasticsearch/elasticsearch.yml # 修改以下几项 cluster.name: etl_es node.name: node-30 node.master: true node.d...
知乎上有一个问题,内容是已知空间三个点的坐标,求三个点所构成的圆的圆心坐标(编程实现)? 根据圆的定义,这道题的核心就是找到一个点,到已知的三个点的距离相等,利用数学知识可以求解如下: 例如 :给定a(x1,y1) b(x2,y2) c(x3,y3)求外接圆心坐标O(x,y) 1. 首先,外接圆的圆心是三角形三条边的垂直平分线的交点,我们根据圆心到顶点的距离相等,可以列出以下方程:
(x1-x)*(x1-x)+(y1-y)*(y1-y)=(x2-x)*(x2-x)+(y2-y)*(y2-y);
(x2-x)*(x2-x)+(y2-y)*(y2-y)=(x3-x)*(x3-x)+(y3-y)*(y3-y); 2.化简得到:
2*(x2-x1)*x+2*(y2-y1)y=x2^2+y2^2-x1^2-y1^2;
2*(x3-x2)*x+2*(y3-y2)y=x3^2+y3^2-x2^2-y2^2;
令:A1=2*(x2-x1);
B1=2*(y2-y1);
C1=x2^2+y2^2-x1^2-y1^2;
A2=2*(x3-x2);
B2=2*(y3-y2);
C2=x3^2+y3^2-x2^2-y2^2;
即:A1*x+B1y=C1;
A2*x+B2y=C2; 3.最后根据克拉默法则:
x=((C1*B2)-(C2*B1))/((A1*B2)-(A2*B1));
y=((A1*C2)-(A2*C...
### 新增Python3编译环境 ``` Tools & Build System & New Build System 将默认内容替换为: { "cmd": ["python3", "-u", "$file"], "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", "selector": "source.python" } 保存为 Python3.sublime-build ``` ### 选中Python3环境 ``` Tools & Build System & Python3 ``` ### 使用Python3编译运行 ``` Ctrl + b ``` ### 可能遇到的问题 ##### 问题 ``` UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) ``` ##### 原因 ``` 默认是ascii编码但是输出中包含中文 ``` ##### 解决 ``` Preferences & Browse Packages & Users & Python3.sublime-build 修改配置文件, 配置文件中新增一条 "env": {"LANG": "en_US.UTF-8"} 修改后如下: { "cmd": ["python3", "-u", "$file"], "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", "selector": "source.python", "env": {"LANG": "en_US.UTF-8"} } ```...
1. 格式化日志内容 2. 日志文件切割
# django ``` # 刚写的就不复制粘贴了 https://my.oschina.net/tianshl/blog/1611257 # 列一下目录结构 root@tianshl:~# cd server/ root@tianshl:~/server# tree server server ├── db.sqlite3 ├── manage.py └── server ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ``` # gunicorn ##### 安装 ``` pip install gunicorn ``` ##### 配置 ``` # 修改django项目的settings.py INSTALLED_APPS = [ ...... 'gunicorn', ] ``` ##### 运行 ``` root@tianshl:~# cd /root/server/server/ root@tianshl:~/server/server# gunicorn --pythonpath /root/server/venv/bin/python3 -w 3 -b 0.0.0.0:80 server.wsgi # 测试能否正常运行, 然后ctrl+c结束进程 ``` # supervisor ##### 安装 ``` pip install supervisor ``` ##### 配置 ``` # 默认配置 # 使用echo_supervisord_conf命令查看默认配置 root@tianshl:~# echo_supervisord_conf # 自定义配置 root@tianshl:~# mkdir /etc/supervisor root@tianshl:~# mkdir /etc/supervisor/conf.d root@tianshl:~# echo_supervisord_conf & /etc/supervisor/supervisor.conf root@tianshl:~# vim /etc/su...
### 写在开头 ``` 使用jhipster声明的OneToMany在One的一方DTO中是没有与Many的DTO的映射关系的, 为了在One的一方DTO中使用Many的DTO, 使用以下三步解决此问题。 ``` ### 步骤 ``` 1. OneDTO 中的"mark 1"处为自己写的一对多的关系, 此处变量名称不能与实体One中相应的变量名称一致,否则编译失败。 2. OneMapper 中的"mark 2"处 uses属性添加ManyMapper。 2. OneMapper 中的"mark 3"处使用@Mapping注解声明 Entity 转 DTO 的映射关系。 ``` ### Entity ``` @Entity @Table(name = "one") public class One { ... @OneToMany(mappedBy = "one") private Set manys = new HashSet&&(); ... public void setManys(Set manys) { this.manys = } public Set getManys() { } } @Entity @Table(name = "many") public class Many { ... @ManyToOne private O } ``` ### DTO ``` public class OneDTO { ... // mark 1 private Set manyDTOS = new HashSet&&(); ... public void setManyDTOS(Set manyDTOS) { this.manyDTOS = manyDTOS; } public Set getManyDTOS() { return manyDTOS; } } public class ManyDTO { ... private Long oneId; ... public...
如何快速申请免费的阿里云服务器
### 1.虚拟环境 ``` tianshl:workspace tianshl$ mkdir server tianshl:workspace tianshl$ cd server/ tianshl:server tianshl$ virtualenv venv --python=python3 tianshl:server tianshl$ source venv/bin/activate ``` ### 2. 安装依赖 ``` (venv) tianshl:server tianshl$ pip install django (venv) tianshl:server tianshl$ pip install djangorestframework ``` ### 3. 创建项目 ``` (venv) tianshl:server tianshl$ django-admin.py startproject server (venv) tianshl:server tianshl$ tree server/ server ├── manage.py └── server ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ``` ### 4. 更新配置 ``` (venv) tianshl:server tianshl$ cd server/ (venv) tianshl:server tianshl$ vim server/settings.py # 1.修改 INSTALLED_APPS = ( ... 'rest_framework', ) # 2.添加 REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' ] }...
每周为您推送最有价值的开源技术内参!
原文:[www.spring4all.com](http://www.spring4all.com) ### 1 线程中断 #### 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 `interrupt()` 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,到底该线程生命周期是去终止,还是继续运行,由线程根据标志位属性自行处理。 #### 1.2 线程中断操作 调用线程的 `interrupt()` 方法,根据线程不同的状态会有不同的结果。 下面新建 InterruptedThread 对象,代码如下: ```java /** * 一直运行的线程,中断状态为 true * * @author Jeff Lee @ bysocket.com * @since 日19:03:02 */ public class InterruptedThread implements Runnable { @Override // 可以省略 public void run() { // 一直 run while (true) { } } public static void main(String[] args) throws Exception { Thread interruptedThread = new Thread(new InterruptedThread(), "InterruptedThread"); interruptedThread.start(); TimeUnit.SE...
本文将对几种音频混音的方法进行详细的介绍和比较,读完之后你应该可以对混音有个基本的认识,针对不同情形知道应该采用哪种具体的处理方法了。
支持document.currentScript的浏览器,用document.currentScript 和document.currentScript.src ie的低版本遍历script标签判断readyState的值是否为"interactive", 上面两种是可以完美获取的 两者都不支持的,通过stack获取路径,但是无法完美获取元素,通过遍历script标签判断src的值, 存在的问题是,多个相同路径的script同时加载,不能正确判断,不过这种情况很少见。 如果stack也不支持,只能获取最后一个元素了,
一些测试结果: firefox的e.fileName和safari的e.sourceURL,获取到的地址是报错的地址,只能直接用,比如a.js调用b.js里的getCurrentPath函数,获取到的地址是b.js。所以不行用。 IE的onerror事件获取到的地址,ie8是js地址,ie7和ie6都是html的地址,所以用onerror不行
—— 原文发布于本人的微信公众号“大数据与人工智能Lab”(BigdataAILab),欢迎关注。
近几年来,卷积神经网络(Convolutional Neural Networks,简称CNN)在图像识别中取得了非常成功的应用,成为深度学习的一大亮点。CNN发展至今,已经有很多变种,其中有几个经典模型在CNN发展历程中有着里程碑的意义,它们分别是:LeNet、Alexnet、Googlenet、VGG、DRL等,接下来将分期进行逐一介绍。 在之前的文章中,已经介绍了卷积神经网络(CNN)的技术原理,细节部分就不再重复了,有兴趣的同学再打开链接看看,在此简单回顾一下CNN的几个特点:局部感知、参数共享、池化。 1、局部感知 人类对外界的认知一般是从局部到全局、从片面到全面,类似的,在机器识别图像时也没有必要把整张图像按像素全部都连接到神经网络中,在图像中也是局部周边的像素联系比较紧密,而距离较远的像素则相关性较弱,因此可以采用局部连接的模式(将图像分块连接,这样能大大减少模型的参数),如下图所示:
2、参数(权值)共享 每张自然图像(人物、山水、建筑等)都有其固有特性,也就是说,图像其中一部分的统计特性与其它部分是接近的。这也意味着这一部分学习的特征也能用在另一部分上,...
## 环境 系统: CentOS7 - 下载 websocketd [websocketd-0.3.0-linux_amd64.zip](https://github.com/joewalnes/websocketd/releases/download/v0.3.0/websocketd-0.3.0-linux_amd64.zip) - 安装 nc 命令 ```bash yum install nmap-ncat ``` - 生成监听脚本 ```bash cat & cmd.sh &&-END #!/bin/bash pid=65536 while :; do if [ -f /proc/$pid/stat ]; then sleep 2 continue fi pkill -x nc && sleep 2 nc -l -p 10089 & pid=$! done ``` - 启动 websocketd ```bash ./websocketd --port=8002 --staticdir=. ./cmd.sh ``` - 编辑 log.html ```html 实时日志清空 ``` - 把 log.html 放在 websocketd 的 staticdir 位置,用浏览器访问该页面 - 在其他应用服务器,传输实时日志 ```bash tail -f /tomcat/logs/catalina.out | nc {ws-server} 10089 ```...
**本文为原创文章,转载请标明[出处](http://metaphors.name/coding//Ionic16.html)** 个人做的开源 Demo 登录注册模块采用的是 [Wilddog 野狗通讯云](https://www.wilddog.com)的身份认证服务,不得不说各方面和 Google 收购的 Firebase 很像,十分简单易用。其中 `User` 有个 `photoURL` 字段是用来存放用户头像 URL 的,所以寻思着找了个免费的第三方图床([SM.MS](https://sm.ms))来存放用户头像。 用到的 Cordova 插件是 [Camera](https://ionicframework.com/docs/native/camera/) 和 [File Transfer](https://ionicframework.com/docs/native/file-transfer/),分别用来拍照、相册选择和上传图片,Cordova 插件的安装、导入、使用我就不赘述了,文档里都有,so 直接上关键代码。 ``` getPictureAndUpload(sourceType: number) { const cameraOptions: CameraOptions = { quality: 80, destinationType: this.camera.DestinationType.FILE_URI, sourceType: sourceType, allowEdit: true, encodingType: this.camera.EncodingType.JPEG, targetWidth: 200, targetHeight: 200, mediaType: this.camera.MediaType.PICTURE, correctOrientation: true, sa...
本测试需要3台服务器,1,2,3 1.NFS客户端,RSYNC客户端 2.NFS服务端,RSYNC客户端,inotify软件 3.NFS客户端,RSYNC服务端 以下是各个服务器的安装脚本: NFS客户端 #!/bin/bash
Path1=/data/a_w_lin
Path2=/data/a_r_lin
### nfs rpcbind install ###
yum -y install nfs-utils rpcbind &&\
rpm -qa nfs-utils rpcbind
### mkdir dir ###
mkdir $Path1 -p
mkdir $Path2 -p
### check nfs ###
showmount -e 10.0.137.145
### mount ###
mount -t nfs
10.0.137.145:/data/w_shared
mount -t nfs
10.0.137.145:/data/r_shared
### rc.local ###
echo "mount -t nfs
10.0.137.145:/data/w_shared
$Path1" &&/etc/rc.local
echo "mount -t nfs
10.0.137.145:/data/r_shared
$Path2" &&/etc/rc.local NFS服务端 #/bin/bash!
### nfs install ###
yum -y install nfs-utils rpcbind
rpm -qa nfs-utils rpcbind
### nfs start ###
/etc/init.d/rpcbind start &&\
/etc/init.d/nfs start
/usr/sbin/rpcinfo -p localhost
### mkdir dir ###
mkdir /data/w_shared -p
mkdir /data/r_shared -p
chown -R nfsnobody.nfsnobody /data/w_shared
系统信息 [root@backup ~]# uname -r
2.6.32-696.el6.x86_64
[root@backup ~]# uname -m
[root@backup ~]# cat /etc/redhat-release
CentOS release 6.9 (Final)
根据端口号22查找对应的服务名称 telnet 10.0.0.41 22
nmap -p 22 10.0.0.41
nc 10.0.0.41 22
ss -lntup | grep 22
netstat -lntup | grep 22
lsof -i :22
根据进程名sshd查找对应的端口号 ss -lntup | grep sshd
netstat -lntup | grep sshd
查找一台服务器开放的所有端口 nmap -p 1-.0.41
可能要花费一点时间 ,不妨把1-65535改为1-100,再尝试一下 注:读者可根据自己的需求,进行修改命令,查找想要的结果
笔记和代码都放在码云:https://gitee.com/tangijia/anguarjs_learning_notes
多谢关注! http://blog.sciencenet.cn/u/oychw 欢迎继续关注!
一、出错情况
Navicat远程连接Oracle错误:ORA-28547:connection to server failed, probable Oracle Net admin error 二、解决方案 1、查找oralce安装目录中app\Administrator\product\11.2.0\dbhome_1\BIN中的oci.dll 2、复制oci.dll到Navicat的安装目录,并备份原本的oci.dll 3、打开Navicat中的工具-&选项-&OCI (直接指到复制的oci.dll中,若直接指到Oracle的oci.dll,可略过第二步骤) 参考地址:http://blog.csdn.net/dmaker1993/article/details/
前言: 我们在项目开发过程中一般都有"分页加载"的需求,分页加载就是以列表的方式显示数据,在有网络的前提下,我们可以通过下拉刷新手动获取更多的数据;没有更多的数据的时候,会提醒我们没有更多数据。
用到的知识点: Retrofit实现网络请求 Recyclerview展示列表信息 Swiperefreshlayout实现下拉刷新,上拉加载更多 Picasso加载图片 实现代码 1.配置gradle依赖 //retrofit
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
//recyclerview
compile 'com.android.support:recyclerview-v7:25.0.1'
compile 'com.squareup.picasso:picasso:2.3.2' 2.在layout布局文件中添加SwipyRefreshLayout &LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFECECEB"
android:orientation="vertical"&
&uk.co.common.ui.pull.SwipyRefreshLayout
android:id="@+id/refreshLayout"
mysql静默更新timestamp类型数据的问题
sed 练习题
把/etc/passwd 复制到/root/test.txt,用sed打印所有行 打印test.txt的3到10行 打印test.txt 中包含 ‘root’ 的行 删除test.txt 的15行以及以后所有行 删除test.txt中包含 ‘bash’ 的行 替换test.txt 中 ‘root’ 为 ‘toor’ 替换test.txt中 ‘/sbin/nologin’ 为 ‘/bin/login’ 删除test.txt中5到10行中所有的数字 删除test.txt 中所有特殊字符(除了数字以及大小写字母) 把test.txt中第一个单词和最后一个单词调换位置 把test.txt中出现的第一个数字和最后一个单词替换位置 把test.txt 中第一个数字移动到行末尾 在test.txt 20行到末行最前面加 ‘aaa:’
1:cp /etc/passwd /root/test.txt
sed -n '1,$'p /root/test.txt
2:sed -n '3,10'p test.txt
3:sed -n '/root/'p test.txt
'15,$'d test.txt
'/bash/'d test.txt
's/root/toor/g' test.txt
's/\/sbin\/nologin/\/bin\/login/g'
8:sed '5,10s/[0-9]//g'
9:sed 's/[^0-9a-zA-Z]//g'
10:sed -r 's/([^:])(.*:)([^:])/\3\2\1/g'
11.sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*\)\([^a-zA-Z]\)
\([a-zA-Z][a-zA-Z]*$\)#\1\5\3\4\2#' test.txt
Torrents(种子):你需要知道的一切事情 Torrents(种子) — 每次听到这个词时,在我的脑海里想到的唯一的事情就是免费的电影、游戏、和被破解的软件。但是我们并不知道它们是如何工作的,在“种子”中涉及到各种概念。因此,通过这篇文章我们从技术的角度来了解种子下载是什么。 “种子”是什么? “种子”是一个到因特网上文件位置的链接。它们不是一个文件,它们仅仅是动态指向到你想去下载的原始文件上。 例如:如果你点击 Google Chrome[1],你可以从谷歌的服务器上下载 Google Chrome 浏览器。 如果你明天、或者下周、或者下个月再去点击那个链接,这个文件仍然可以从谷歌服务器上去下载。 但是当我们使用“种子”下载时,它并没有固定的服务器。文件是从以前使用“种子”下载的其它人的个人电脑上下载的。 Torrents 是如何工作的? 假设 ‘A’ 上有一些视频,它希望以“种子”方式去下载。因此,他创建了一个“种子”,并将这个链接发送给 ‘B’,这个链接包含了那个视频在因特网上的准确 IP 地址的信息。因此,当 ‘B’ 开始下载那个文件的时候,‘B’ 连接到 ‘A’ 的计算机。在 ‘B’ 下载完成这个视频之后,‘B’ 将开始做为种子,也就是 ‘B’ 将允许其它的...
LuaJIT虚拟机中函数与函数原型的结构和实现方式
http://blog.csdn.net/ly6cyh/article/details/ http://blog.csdn.net/hblfyla/article/details/
package org.apache.http.examples.
import org.apache.http.HttpH
import org.apache.http.client.config.RequestC
import org.apache.http.client.methods.CloseableHttpR
import org.apache.http.client.methods.HttpG
import org.apache.http.impl.client.CloseableHttpC
import org.apache.http.impl.client.HttpC
import org.apache.http.util.EntityU
* How to send a request via proxy.
* @since 4.0
public class ClientExecuteProxy {
public static void main(String[] args)throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpHost target = new HttpHost("httpbin.org", 443, "https");
HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http");
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build()...
最近在LeetCode刷题,有的题目还是挺有意思的,贴上来和大家分享一下。
经常发现有人在网上提出这样的问题,现实中也确实有不少人在经历了3-5年的Windows开发之后就开始迷失方向,每天浑浑噩噩混日子,可能是因为这个问题粒度太大,没人愿意花时间回答,希望本文可以抛砖引玉,给大家节省些时间,同时也希望园子里面的兄弟们能尽力的补充,从而使这篇文章可以帮助更多的后来人。 首先说明的是,本文提到的各种技术不分先后,没有顺序,虽然先学什么,再学什么对某些人来说可能更方便,但是这些都不是绝对的,因为每个人的情况不同。 Windows开发首先必须学习的就是操作系统的API,因为其他的一切都是构建于OS之上,所谓九层之台,起于垒土,如果你对linux的系统调用很熟悉就会发现其实他们大同小异,都是应用程序在使用系统提供的功能。 接下来是MFC,有了MFC你才真正的可以干点开发,因为MFC实在是太全了,几乎封装了所有的Windows API, 消息循环,COM实现… 到了此地,你可以开始学习调试技术了,熟悉了调试的各种技巧才可以做到事半功倍,得心应手。 接下来是组建对象模型COM,作为windows的基石,不懂COM,很难说自己精通windows编程,因为即使现在的.NET framework也是构建于COM之上,很多问题还是需要SOS到底层去调试。 当你懂得了COM的精...
对于无状态的web服务,要做分布式部署相对比较简单,很多时候只要架一个反向代理就行。但是对于有状态的web服务,尤其是包含WebSocket成分的web应用,要做分布式部署一直是一个麻烦。传统做法是搞一个中间层,例如Redis之类的做pubsub,但是这样做就不得不改动源码。Erlang/Elixir这种“面向并发编程”的语言在这方面会不会高人一筹?Phoenix框架是否已经支持WebSocket的横向扩展了呢?下面我们就来做个实验。
在帮助小白解决了很多开源使用的问题后,我总结了小白的不科学的提问方式,以遭受9种伤害夸张的手法一一道来
微信自15年年底上线FOOM上报,每天FOOM次数与登录用户数比例接近3%,同期crash率1%不到。而16年年初某东老大反馈微信频繁闪退,接着16年8月不少外部用户反馈微信启动不久后闪退,分析大量日志还是不能找到FOOM原因。微信急需一个有效的内存监控工具来发现问题。
原文:[www.spring4all.com](http://www.spring4all.com) ### 1 线程中断 #### 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 `interrupt()` 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,到底该线程生命周期是去终止,还是继续运行,由线程根据标志位属性自行处理。 #### 1.2 线程中断操作 调用线程的 `interrupt()` 方法,根据线程不同的状态会有不同的结果。 下面新建 InterruptedThread 对象,代码如下: ```java /** * 一直运行的线程,中断状态为 true * * @author Jeff Lee @ bysocket.com * @since 日19:03:02 */ public class InterruptedThread implements Runnable { @Override // 可以省略 public void run() { // 一直 run while (true) { } }

我要回帖

更多关于 servlet中文帮助文档 的文章

 

随机推荐