首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

《码出高效》学习笔记与书中错误记录

今天在阅读《码出高效》的时候看到了一个问题,我也是第一次知道,而且有点颠覆我的认知。所以做了一些测试,并记录下来。 然而测试的结果发现,好像事实并不如书中说的那么简单。 问题是这样的: if (true) int x; for (; ; ) int y; while (true) int z; 这三句话,能通过编译吗,如果能,会给出 Warning 吗,如果不能,那么错误信息是什么。 书中给出的答案是,不能通过编译,会给出 Declaration not allowed here 编译错误信息,并对此,书中解释为: 单语句在没有加大括号的情况下,声明的变量不可能再被使用,编译器认为没有任何意义。 Every declaration that introduces a name has a scope, in which they can be used. 我做了一些测试,发现事情好像并不是那么简单。 我一开始也是这样认为的。我本来以为,至少应该通过编译,最多是给一个 Warning 说 variable is never used。 我比较好奇,除了 Java,其他语言会不会有同样的编译错误。 首先是是测试 C、C++、Java 是不是都对这句话有相同的结果。 先来看 C,测试环境是 CentOS 7.3 x64,GCC 版本是 gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)。 C,不管是 ANSI C 还是 C99,都无法通过编译,直接给出 Error。 error: expected expression before ‘int’ 如果加上大括号,那么能够通过编译,遇到大家常见的 Warning。 warning: unused variable ‘x’ [-Wunused-variable] 同样的结果在环境中(我测试环境是 CodeBlocks,Windows)得到了相同的结果。 我相信,CLion 等 IDE 也有一样的结果,如果没有,那么可能是 IDE 帮忙优化了,毕竟有些时候,写 C 代码漏 include 一些头文件,编译和运行的结果也是正确的(IDE 帮你自动补上了)。 原因稍后分析,下面继续测试。 C++。 结果是,编译通过,给出 Warning。 事实上与代码无关,即使是对刚才的 .c 文件,只要使用 g++ 编译器,也是通过的。 再来看 Java。 public class Main { public static void main(String args[]) { if (true) int jxtxzzw; } } 如果是 Eclipse,直接给出错误。 强行运行,编译失败,无法运行。 Unresolved compilation problem: Syntax error on token “)”, Statement expected after this token at … 如果是 IDEA,会给出编译错误信息。 Declaration not allowed here 至于为什么 C 就不行呢?难道 C 的语法什么地方说了这是不合法的吗?闻所未闻啊? 但是既然 C 的编译器说不行,那肯定是 C 的哪个标准说了这是不合法的,如果这是真的,那么就不是作用域的问题,而是语法、文法的问题。 换句话说,如果 if (true) {int x;} 是合法的,那为什么 if (true) int x; 就不符合语法呢? 我查阅了很多资料(链接见文末),最后找到一个比较信服的答案——确实,根据 C 标准,这就是错的,彻底的语法错误。 首先来澄清一个概念,if 条件句后面,必须跟一个语句。 int x 是一个声明,Declaration。 int x = 10; 是一个定义,Definition。 {int x;} 或者 {int x = 10;} 由于有了 {},是一条语句,Statement。 这是 3 个完全不同的概念,也是绝大多数程序员从一开始就分不清的,而且也始终分不清,从来分不清。 所以,现在的问题的答案就很显然了,C 要求 if 后面是一条语句,然而文章一开始那种写法,是 Declaration,不是 Statement,所以语法就是错的。 这也印证了那句 Error:expected expression,我需要一个表达式。 表达式 Expression,显然是一句语句 Statement。 同时,这与 Eclipse 的报错信息是一致的——if 后面需要一个 Statement。( Statement expected after this token at … ) 如果从这个角度考虑,那么,IDEA 的错误提示,Declaration not allowed 就不应该从变量作用域的角度考虑这里的变量声明不合法,而是应该理解成,这是一个 Declaration,而我需要一个 Statement,所以 Declaration 在这里是不被允许的。 这是一个 Declaration,而我需要一个 Statement,所以 Declaration 在这里是不被允许的 至于为什么 g++ 就可以,我想这个问题,可能和 为什么有些 IDE 这么写就可以通过编译,我猜想的是(是的,只是猜想,没有验证过),恐怕是这个编译器,包括绝大多数的 IDE,都自动优化了这个地方,把所有的 if 等语句后面,默认当作套上了大括号在处理,即使是单语句,也假装有了一个大括号作用域,然后再编译的。 所以,有些 gcc 的编译器,也有可能可以,但是从我的测试情况来看,MinGW、Cygwin、Windows、Window 的 Ubuntu 子系统、CentOS 下,gcc 都会给出 error。 I guess the counter-intuitive part of the question is: if this is correct C:if (a == 1) { int b = 10;}then why is this not also correct C?if (a == 1) int b = 10;I mean, a one-line conditional if statement should be fine either with or without braces, right?The answer lies in the grammar of the if statement, as defined by the C standard. The relevant parts of the grammar I’ve quoted below. > Succinctly: the int b = 10 line is a declaration, not a statement, and the grammar for the if statement requires a statement after the conditional that it’s testing. But if you enclose the declaration in braces, it becomes a statement and everything’s well.见: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf 以及 https://www.quora.com/What-does-error-expected-expression-before-int-mean-in-C

优秀的个人博客,低调大师

基于Spark的机器学习实践 (三) - 实战环境搭建

0 相关源码 1 Spark环境安装 ◆ Spark 由scala语言编写,提供多种语言接口,需要JVM ◆ 官方为我们提供了Spark 编译好的版本,可以不必进行手动编译 ◆ Spark安装不难,配置需要注意,并且不一定需要Hadoop环境 下载 解压 tar zxvf spark-2.4.1-bin-hadoop2.7.tgz 2 Spark配置 ◆ 在配置前尽量先阅读官方文档,避免直接从网上找配置教程 ◆ 要为节点设 置好使用的内存,否则可能导致节点利用率低; ◆ 注意spark中IP与端口号的配置,以免UnknownHostException [官网配置]() 应用默认配置 配置文件 复制两份模板,开启自行配置 单机环境配置 本地IP shell进行验证 bin/spark-shell 3 Spark shell ◆ Spark shell是一个bash脚本,在

优秀的个人博客,低调大师

实战深度强化学习DQN-理论和实践

本文来自云栖社区官方钉群“Python技术进阶”,了解相关信息可以关注“Python技术进阶”。 1、Q-learning回顾 Q-learning 的 算法过程如下图所示: 在Q-learning中,我们维护一张Q值表,表的维数为:状态数S * 动作数A,表中每个数代表在当前状态S下可以采用动作A可以获得的未来收益的折现和。我们不断的迭代我们的Q值表使其最终收敛,然后根据Q值表我们就可以在每个状态下选取一个最优策略。 Q值表的更新公式为: 公式中,Q(S,A) 我们可以称做Q估计值,即我们当前估计的Q值,而: 称为Q-target,即我们使用贝尔曼方程加贪心策略认为实际应该得到的奖励,我们的目标就是使我们的Q值不断的接近Q-target值。 2、深度Q网络(Deep - Q - Network) 2.1 DQN简介 为什么会出现DQN呢 在普通的Q

优秀的个人博客,低调大师

Java学习笔记——dubbo服务之底层通讯协议Protocol

我们先来找到通讯协议的入口点吧。通过Protocol接口查找通讯协议入口点,我们根据接口的export方法搜索发现入口了,在ServiceConfig的doExportUrlsFor1Protocol方法,如下图: 然后我们进入 protocol.export(invoker)方法发现有很多实现类,根据spi(不懂的请看之前写的容器篇)查看配置文件能找到如下 registry=com.alibaba.dubbo.registry.integration.RegistryProtocol dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol//这个是默认的,我们在Protocol接口上可以看到spi的注解 filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper mock=com.alibaba.dubbo.rpc.support.MockProtocol injvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol com.alibaba.dubbo.rpc.protocol.http.HttpProtocol com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol memcached=com.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol redis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol rest=com.alibaba.dubbo.rpc.protocol.rest.RestProtocol 进入DubboProtocol.export(Invoker<T> invoker)方法里面有个 openServer(url); 代码: privatevoidopenServer(URLurl){ //findserver. Stringkey=url.getAddress(); //client也可以暴露一个只有server可以调用的服务。 booleanisServer=url.getParameter(Constants.IS_SERVER_KEY,true); if(isServer){ ExchangeServerserver=serverMap.get(key); if(server==null){ serverMap.put(key,createServer(url));//createServer是创建服务 }else{ //server支持reset,配合override功能使用 server.reset(url); } } } 继续进入createServer,上源码 privateExchangeServercreateServer(URLurl){ //默认开启server关闭时发送readonly事件 url=url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY,Boolean.TRUE.toString()); //默认开启heartbeat url=url.addParameterIfAbsent(Constants.HEARTBEAT_KEY,String.valueOf(Constants.DEFAULT_HEARTBEAT)); Stringstr=url.getParameter(Constants.SERVER_KEY,Constants.DEFAULT_REMOTING_SERVER); if(str!=null&&str.length()>0&&!ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) thrownewRpcException("Unsupportedservertype:"+str+",url:"+url); url=url.addParameter(Constants.CODEC_KEY,Version.isCompatibleVersion()?COMPATIBLE_CODEC_NAME:DubboCodec.NAME); ExchangeServerserver; try{ server=Exchangers.bind(url,requestHandler); }catch(RemotingExceptione){ thrownewRpcException("Failtostartserver(url:"+url+")"+e.getMessage(),e); } str=url.getParameter(Constants.CLIENT_KEY); if(str!=null&&str.length()>0){ Set<String>supportedTypes=ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions(); if(!supportedTypes.contains(str)){ thrownewRpcException("Unsupportedclienttype:"+str); } } returnserver; } dubbo从要暴漏的服务的URL中取得相关的配置(host,port等)进行服务端server的创建,同上面的server = Exchangers.bind(url, requestHandler) 正式创建服务。 所以基本的创建步骤是 export() --> openServer() --> createServer() --> server = Exchangers.bind(url, requestHandler); 我们进行来看 Exchangers.bind(url, requestHandler) 源码: publicstaticExchangeServerbind(URLurl,ExchangeHandlerhandler)throwsRemotingException{ if(url==null){ thrownewIllegalArgumentException("url==null"); } if(handler==null){ thrownewIllegalArgumentException("handler==null"); } url=url.addParameterIfAbsent(Constants.CODEC_KEY,"exchange"); returngetExchanger(url).bind(url,handler); } 然后通过getExchanger(url).bind(url, handler)的bing进入 HeaderExchanger类 publicExchangeServerbind(URLurl,ExchangeHandlerhandler)throwsRemotingException{ returnnewHeaderExchangeServer(Transporters.bind(url,newDecodeHandler(newHeaderExchangeHandler(handler)))); } 在进入Transporters类的bing的 publicstaticServerbind(URLurl,ChannelHandler...handlers)throwsRemotingException{ if(url==null){ thrownewIllegalArgumentException("url==null"); } if(handlers==null||handlers.length==0){ thrownewIllegalArgumentException("handlers==null"); } ChannelHandlerhandler; if(handlers.length==1){ handler=handlers[0]; }else{ handler=newChannelHandlerDispatcher(handlers); } returngetTransporter().bind(url,handler); } 通过bing可以知道他讲调用:GrizzlyTransporter,MinaTransporter,NettyTransporter 通过spi默认是调用NettyTransporter 到这里我们基本明白dubbo的通讯默认是交给了netty来处理, 我们在看下doOPen方法 @Override protectedvoiddoOpen()throwsThrowable{ NettyHelper.setNettyLoggerFactory(); ExecutorServiceboss=Executors.newCachedThreadPool(newNamedThreadFactory("NettyServerBoss",true)); ExecutorServiceworker=Executors.newCachedThreadPool(newNamedThreadFactory("NettyServerWorker",true)); ChannelFactorychannelFactory=newNioServerSocketChannelFactory(boss,worker,getUrl().getPositiveParameter(Constants.IO_THREADS_KEY,Constants.DEFAULT_IO_THREADS)); bootstrap=newServerBootstrap(channelFactory); finalNettyHandlernettyHandler=newNettyHandler(getUrl(),this); channels=nettyHandler.getChannels(); //https://issues.jboss.org/browse/NETTY-365 //https://issues.jboss.org/browse/NETTY-379 //finalTimertimer=newHashedWheelTimer(newNamedThreadFactory("NettyIdleTimer",true)); bootstrap.setPipelineFactory(newChannelPipelineFactory(){ publicChannelPipelinegetPipeline(){ NettyCodecAdapteradapter=newNettyCodecAdapter(getCodec(),getUrl(),NettyServer.this); ChannelPipelinepipeline=Channels.pipeline(); /*intidleTimeout=getIdleTimeout(); if(idleTimeout>10000){ pipeline.addLast("timer",newIdleStateHandler(timer,idleTimeout/1000,0,0)); }*/ pipeline.addLast("decoder",adapter.getDecoder());//解码 pipeline.addLast("encoder",adapter.getEncoder());//编码 pipeline.addLast("handler",nettyHandler); returnpipeline; } }); //bind channel=bootstrap.bind(getBindAddress()); } 了解netty的同学,肯定早已习惯这个方法的写法,就是创建了netty的server嘛,到这里dubbo的服务创建完毕了,这个时候控制台见打印: [DUBBO]StartNettyServerbind/0.0.0.0:20880,export/192.168.4.241:20880,dubboversion:2.8.4,currenthost:127.0.0.1

优秀的个人博客,低调大师

Python零基础学习笔记(四十)—— datetime和Calendar

import datetime import time ''' datetime比time高级了不少,可以理解为date time基于time进行了封装, 提供了各种实用的函数,date time模块的接口更为直观,更容易调用 模块中的类: datetime 同时有时间和日期 timedelta 主要用于计算时间跨度 tzinfo 时区相关 time 只关注时间 date 只关注日期 ''' #获取当前时间 d1 = datetime.datetime.now() print(d1) # d2 = datetime.datetime(1995, 4, 28,10,23,34,123355) print(d2) # d3 = datetime.datetime.time(d1) print(d3) #将时间转换为字符串 #d4 = d1.strptime("%Y-%m-%d %X") #print(d4) #时间加减 d5 = d1 - d2 print(d5) #间隔的天数 print(d5.days) #间隔天数除外的秒数 print(d5.seconds) import calendar ''' 日历 ''' #使用 print(calendar.month(2019, 7)) #返回指定年的日历 print(calendar.calendar(2019)) #判断闰年,返回True print(calendar.isleap(2000)) #返回某个月的weekday的第一天和这个月的天数 print(calendar.monthrange(2018, 12)) #返回某个月以每一周为元素的列表 print(calendar.monthcalendar(2017, 12))

优秀的个人博客,低调大师

Python零基础学习笔记(三十五)—— 内存修改

今天利用这个小功能做了个植物大战僵尸的外挂,哈哈哈 等以后学了GUI编程的时候做成图形化界面 #进程模块 import win32process #系统 import win32api import win32con import win32gui import ctypes #获取最高权限,\位运算 PROCESS_ALL_ACCESS = (0x000F000|0x00100000|0xFFF) #找窗体 win = win32gui.FindWindow("MainWindow","植物大战僵尸中文版") #根据窗体找到进程号 hid, pid = win32process.GetWindowThreadProcessId(win) #以最高权限打开进程 p = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid) data = ctypes.c_long() #c语言中的长整形 #加载内核模块 md = ctypes.windll.LoadLibrary("C:\\Windows\\System32\\kernel32") #读取内存 md.ReadProcessMemory(int(p),0x12508678, ctypes.byref(data), 4, None) print("data =", data) #设置新值 newData = ctypes.c_long(1000) #修改 md.WriteProcessMemory(int(p), 0x12508678, ctypes.byref(newData), 4, None)

优秀的个人博客,低调大师

Python零基础学习笔记(三十一)—— 写文件

import time path = r"C:\Users\Administrator\PycharmProjects\untitled\day011\文件读写\file1" f = open(path,"w") ''' #写文件 #1、 f.write("Hello !!!") f.write("and") #2、刷新缓冲区 #直接把内部缓冲区数据立刻写入文件,而不是被动等待自动刷新缓冲区写入 f.flush() while True: f.write("Hello!\n") f.flush() time.sleep(1) f.close() #写文件 with open(path,"a") as f2: f2.write("aaa$$%##%##%") ''' #编码 with open(path, "wb") as f3: str = "My name is jjking.你好" f3.write(str.encode("utf-8")) with open(path, "rb") as f4: data = f4.read() print(data) print(type(data)) newData = data.decode("utf-8") print(newData) print(type(newData))

优秀的个人博客,低调大师

Python零基础学习笔记(二十四)—— 函数

''' 认识函数:在以恶完整的项目中,某些功能会反复的使用,那么 会将功能封装成函数,当我们要使用这些功能的时候 直接调用函数即可 本质:函数就是对功能的封装 优点: 1、简化代码结构,增加了代码的复用度(重复使用的程度) 2、如果想修改某些功能或修改某个bug只需要修改相应的函数即可 ''' ''' 定义函数: 格式: def 函数名(参数列表): 语句 return 表达式 def:函数代码块从def关键字开始 函数名:遵循标识符规则 参数列表(参数1, 参数2,……参数n):任何传入函数的参数和变量 必须放在圆括号之间 语句:执行的功能 return:以return为结束 ''' ''' 函数的调用 格式:函数名(参数列表) 函数名:是要使用的功能的函数 '''

优秀的个人博客,低调大师

Python零基础学习笔记(二十二)—— set

''' set:类似dict,是一组key的集合,不存储value 本质:无序和无重复元素的集合 用途:经常用于去除list和tuple中的重复元素 ''' #创建 #创建set 需要一个list或者tuple或者dict作为输入集合 #重复元素在set中会自动被过滤 set1 = set([1, 2, 2, 2, 3, 4, 5]) print(set1) set2 = set((1, 2, 3, 1, 2, 3)) print(set2) set3 = set({1:"2" , 3: "4", 5: "2"}) print(set3) #添加 注意;列表不能作为key,而set里面存的就是key,所以不能添加list[] set1.add(5) print(set1) set2.add((1,2,1,5)) print(set2) #set3.add({1,2}) #会报错 #插入整个list tuple 字符串,打碎插入 set1.update([12,3]) print(set1) set1.update((22,23,24,24)) print(set1) set1.update("name") print(set1) #删除 set1.remove("n") print(set1) set1.remove(2) print(set1) #遍历 for i in set1: print(i) #注意:set没有索引 for index, data in enumerate(set1): print(index,data) s1 = set([1, 2, 3]) s2 = set([2, 3, 4]) #交集 a1 = s1 & s2 print(a1) print(type(a1)) #并集 a2 = s1 | s2 print(a2) print(type(a2)) #list -> set l1 = [1, 2, 3, 4] set3 = set(l1) #tuple -> set t1 = (1, 2, 3) s4 =set(t1) print(s4) #去重 list5 =[1, 1, 2, 3, 4, 3, 4] print(list5) list6 = list(set(list5)) print(list6)

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册