-
第 4 章 一 程序计数器、为什么使用程序计数器来记录当前线程的执行地址呢?
2020-12-20 15:03:33线程私有, 运行速度最快的存储区域, 程序计数器会存储当前线程正在执行的Java方法的JVM指令地址 PC寄存器不会出现OOM(OutofMemoryError), StackOverFlow 字节码解释器工作时就是通过改变这个计数器的值来选取下一条...第 4 章 程序计数器 (PC寄存器)
1、PC寄存器概述
(重点)
文档网址
PC寄存器介绍 以及 作用 :
线程私有
, 运行速度最快的存储区域,程序计数器
会存储
当前线程正在执行的Java方法的JVM指令地址
- PC寄存器不会出现OOM(OutofMemoryError) 内存溢出, StackOverFlow 栈溢出 的情况
- 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令
- 当CPU并发执行, cpu时间片轮训执行不同的线程(或者发生中断操作), 使用
pc寄存器
中存储的指令地址, 来恢复到原来的执行位置
- JVM中的
程序计数寄存器(Program Counter Register)
中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。 - 这里,并非是广义上所指的物理寄存器,或许将其翻译为
PC计数器(或指令计数器)
会更加贴切(也称为程序钩子),并且也不容易引起一些不必要的误会。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。 - 它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。
- 在
JVM规范中,每个线程都有它自己的程序计数器,是线程私有的
,生命周期与线程的生命周期保持一致。 - 任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法 (虚拟机栈的栈顶栈帧)。
程序计数器会存储当前线程正在执行的Java方法的JVM指令地址
,或者,如果是在执行native方法,则是未指定值(undefned)。 - 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
- 它是唯一一个在Java虚拟机规范中没有规定任何OutofMemoryError情况的区域。
PC 寄存器的作用
PC寄存器
用来存储指向下一条指令的地址,也即将要执行的指令代码。由执行引擎将指令解释为机器码交由cpu进行处理
2、代码示例
- 代码
public class PCRegisterTest { public static void main(String[] args) { int i = 10; int j = 20; int k = i + j; String s = "abc"; System.out.println(i); System.out.println(k); } }
- 反编译:
javap -v xxx.class
// 常量池 Constant pool: #1 = Methodref #6.#26 // java/lang/Object."<init>":()V #2 = String #27 // abc #3 = Fieldref #28.#29 // java/lang/System.out:Ljava/io/PrintStream; #4 = Methodref #30.#31 // java/io/PrintStream.println:(I)V #5 = Class #32 // com/atguigu/java/PCRegisterTest #6 = Class #33 // java/lang/Object #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 Lcom/atguigu/java/PCRegisterTest; #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = Utf8 args #17 = Utf8 [Ljava/lang/String; #18 = Utf8 i #19 = Utf8 I #20 = Utf8 j #21 = Utf8 k #22 = Utf8 s #23 = Utf8 Ljava/lang/String; #24 = Utf8 SourceFile #25 = Utf8 PCRegisterTest.java #26 = NameAndType #7:#8 // "<init>":()V #27 = Utf8 abc #28 = Class #34 // java/lang/System #29 = NameAndType #35:#36 // out:Ljava/io/PrintStream; #30 = Class #37 // java/io/PrintStream #31 = NameAndType #38:#39 // println:(I)V #32 = Utf8 com/atguigu/java/PCRegisterTest #33 = Utf8 java/lang/Object #34 = Utf8 java/lang/System #35 = Utf8 out #36 = Utf8 Ljava/io/PrintStream; #37 = Utf8 java/io/PrintStream #38 = Utf8 println #39 = Utf8 (I)V { public com.atguigu.java.PCRegisterTest(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 7: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/atguigu/java/PCRegisterTest; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=5, args_size=1 0: bipush 10 2: istore_1 3: bipush 20 5: istore_2 6: iload_1 7: iload_2 8: iadd 9: istore_3 10: ldc #2 // String abc 12: astore 4 14: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 17: iload_1 18: invokevirtual #4 // Method java/io/PrintStream.println:(I)V 21: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 24: iload_3 25: invokevirtual #4 // Method java/io/PrintStream.println:(I)V 28: return LineNumberTable: line 10: 0 line 11: 3 line 12: 6 line 14: 10 line 15: 14 line 16: 21 line 18: 28 LocalVariableTable: Start Length Slot Name Signature 0 29 0 args [Ljava/lang/String; 3 26 1 i I 6 23 2 j I 10 19 3 k I 14 15 4 s Ljava/lang/String;
- 左边的数字代表指令地址(指令偏移),即
PC寄存器中可能存储的值
,然后执行引擎读取 PC 寄存器中的值,并执行该指令
3、两个面试题
(重要)
- 使用PC寄存器存储字节码指令地址有什么用呢?
- 为什么使用 PC 寄存器来记录当前线程的执行地址呢?
- 因为线程是一个个的顺序执行流,
CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行
- JVM的字节码解释器就需要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令
PC寄存器为什么被设定为私有的?
- 总结下面: 为了保证当并发执行的多个线程的时候, cpu时间片疯狂切换, 当切换到别的线程的时候, 我们要记录上一个线程执行到哪个指令了. 所以使用pc寄存器来存储; 如果设置为
线程共享
的pc寄存器, 当切换到上一个线程的时候, 它恢复到原来执行的位置. 就不准确了
- 我们都知道
所谓的多线程在一个特定的时间段内只会执行其中某一个线程的方法(并发操作)
,CPU会不停地做任务切换,这样必然导致经常中断或恢复,如何保证分毫无差呢? 为了能够准确地记录各个线程正在执行的当前字节码指令地址,最好的办法自然是为每一个线程都分配一个PC寄存器
,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。- 由于CPU时间片轮限制,众多线程在
并发
执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条指令。 - 这样
必然导致经常中断或恢复
,如何保证分毫无差呢?每个线程在创建后,都会产生自己的
程序计数器和
栈帧,程序计数器在各个线程之间互不影响
。
4、CPU 时间片
- 并发执行的时候: 宏观上来说, 同时执行; 微观上来说, 串行执行
- CPU时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片。
- 在
宏观
上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行
。 - 在
微观
上:由于只有一个CPU(当有多核,多个CPU的时候, 真正意义上存在并行, 但也存在并发的现象.),一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。
-
git修改远程源_Git修改远程仓库地址
2021-01-13 09:56:52至于为什么要从Github切换到Gitee,主要是因为Github有时确实太慢了,页面打不开,代码提交不上去。还有就是因为自己很多项目是私有的,总会出现两个网站来回切换。尽管Github是一个程序员的标配,但是在这种背景下...最近项目搬家,从Github搬到Gitee,所以大批项目需要修改仓库地址。至于为什么要从Github切换到Gitee,主要是因为Github有时确实太慢了,页面打不开,代码提交不上去。还有就是因为自己很多项目是私有的,总会出现两个网站来回切换。尽管Github是一个程序员的标配,但是在这种背景下,使用Gitee到也是不得已!
修改Git远程分支的方法有很多,这里只介绍几种
方法一:通过命令行修改远程地址
> cd json
> git remote set-url origin https://gitee.com/jouypub/json.git
方法二:先删除原有仓库地址,然后添加新地址
> cd json
> git remote rm origin
> git remote add origin https://gitee.com/jouypub/json.git
方法三:修改配置文件
> cd json/.git
> vim config
[core]
repositoryformatversion = 0
filemode = true
logallrefupdates = true
precomposeunicode = true
[remote "origin"]
# 修改成新的仓库地址
url = https://gitee.com/jouypub/json.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
欢迎订阅「K叔区块链」 - 专注于区块链技术学习
博客地址:http://www.jouypub.com
简书主页:https://www.jianshu.com/u/756c9c8ae984
segmentfault主页:https://segmentfault.com/blog/jouypub
腾讯云主页:https://cloud.tencent.com/developer/column/72548
-
linux 析构函数地址获取_linux C++ 线程安全的单例模式总结
2020-11-27 12:20:47在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。如何保证线程安全?给共享的资源加把锁,保证每个资源变量每时每刻至多...什么是线程安全?
在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
如何保证线程安全?
- 给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用。
- 让线程也拥有资源,不用去共享进程中的资源。如: 使用threadlocal可以为每个线程的维护一个私有的本地变量。
什么是单例模式?
单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性。
单例模式分类
单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同:
- 懒汉式:指系统运行中,实例并不存在,只有当需要使用该实例时,才会去创建并使用实例。(这种方式要考虑线程安全)
- 饿汉式:指系统一运行,就初始化创建实例,当需要时,直接调用即可。(本身就线程安全,没有多线程的问题)
单例类特点
- 构造函数和析构函数为private类型,目的禁止外部构造和析构
- 拷贝构造和赋值构造函数为private类型,目的是禁止外部拷贝和赋值,确保实例的唯一性
- 类里有个获取实例的静态函数,可以全局访问
01 普通懒汉式单例 ( 线程不安全 )
/// 普通懒汉式实现 -- 线程不安全 // #include <iostream> // std::cout #include <mutex> // std::mutex #include <pthread.h> // pthread_create class SingleInstance { public: // 获取单例对象 static SingleInstance *GetInstance(); // 释放单例,进程退出时调用 static void deleteInstance(); // 打印单例地址 void Print(); private: // 将其构造和析构成为私有的, 禁止外部构造和析构 SingleInstance(); ~SingleInstance(); // 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值 SingleInstance(const SingleInstance &signal); const SingleInstance &operator=(const SingleInstance &signal); private: // 唯一单例对象指针 static SingleInstance *m_SingleInstance; }; //初始化静态成员变量 SingleInstance *SingleInstance::m_SingleInstance = NULL; SingleInstance* SingleInstance::GetInstance() { if (m_SingleInstance == NULL) { m_SingleInstance = new (std::nothrow) SingleInstance; // 没有加锁是线程不安全的,当线程并发时会创建多个实例 } return m_SingleInstance; } void SingleInstance::deleteInstance() { if (m_SingleInstance) { delete m_SingleInstance; m_SingleInstance = NULL; } } void SingleInstance::Print() { std::cout << "我的实例内存地址是:" << this << std::endl; } SingleInstance::SingleInstance() { std::cout << "构造函数" << std::endl; } SingleInstance::~SingleInstance() { std::cout << "析构函数" << std::endl; } /// 普通懒汉式实现 -- 线程不安全 // // 线程函数 void *PrintHello(void *threadid) { // 主线程与子线程分离,两者相互不干涉,子线程结束同时子线程的资源自动回收 pthread_detach(pthread_self()); // 对传入的参数进行强制类型转换,由无类型指针变为整形数指针,然后再读取 int tid = *((int *)threadid); std::cout << "Hi, 我是线程 ID:[" << tid << "]" << std::endl; // 打印实例地址 SingleInstance::GetInstance()->Print(); pthread_exit(NULL); } #define NUM_THREADS 5 // 线程个数 int main(void) { pthread_t threads[NUM_THREADS] = {0}; int indexes[NUM_THREADS] = {0}; // 用数组来保存i的值 int ret = 0; int i = 0; std::cout << "main() : 开始 ... " << std::endl; for (i = 0; i < NUM_THREADS; i++) { std::cout << "main() : 创建线程:[" << i << "]" << std::endl; indexes[i] = i; //先保存i的值 // 传入的时候必须强制转换为void* 类型,即无类型指针 ret = pthread_create(&threads[i], NULL, PrintHello, (void *)&(indexes[i])); if (ret) { std::cout << "Error:无法创建线程," << ret << std::endl; exit(-1); } } // 手动释放单实例的资源 SingleInstance::deleteInstance(); std::cout << "main() : 结束! " << std::endl; return 0; }
普通懒汉式单例运行结果:
从运行结果可知,单例构造函数创建了两个,内存地址分别为0x7f3c980008c0和0x7f3c900008c0,所以普通懒汉式单例只适合单进程不适合多线程,因为是线程不安全的。
普通懒汉式
02 加锁的懒汉式单例 ( 线程安全 )
/// 加锁的懒汉式实现 // class SingleInstance { public: // 获取单实例对象 static SingleInstance *&GetInstance(); //释放单实例,进程退出时调用 static void deleteInstance(); // 打印实例地址 void Print(); private: // 将其构造和析构成为私有的, 禁止外部构造和析构 SingleInstance(); ~SingleInstance(); // 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值 SingleInstance(const SingleInstance &signal); const SingleInstance &operator=(const SingleInstance &signal); private: // 唯一单实例对象指针 static SingleInstance *m_SingleInstance; static std::mutex m_Mutex; }; //初始化静态成员变量 SingleInstance *SingleInstance::m_SingleInstance = NULL; std::mutex SingleInstance::m_Mutex; SingleInstance *&SingleInstance::GetInstance() { // 这里使用了两个 if判断语句的技术称为双检锁;好处是,只有判断指针为空的时候才加锁, // 避免每次调用 GetInstance的方法都加锁,锁的开销毕竟还是有点大的。 if (m_SingleInstance == NULL) { std::unique_lock<std::mutex> lock(m_Mutex); // 加锁 if (m_SingleInstance == NULL) { m_SingleInstance = new (std::nothrow) SingleInstance; } } return m_SingleInstance; } void SingleInstance::deleteInstance() { std::unique_lock<std::mutex> lock(m_Mutex); // 加锁 if (m_SingleInstance) { delete m_SingleInstance; m_SingleInstance = NULL; } } void SingleInstance::Print() { std::cout << "我的实例内存地址是:" << this << std::endl; } SingleInstance::SingleInstance() { std::cout << "构造函数" << std::endl; } SingleInstance::~SingleInstance() { std::cout << "析构函数" << std::endl; } /// 加锁的懒汉式实现 //
加锁的懒汉式单例的运行结果:
从运行结果可知,只创建了一个实例,内存地址是0x7f28b00008c0,所以加了互斥锁的普通懒汉式是线程安全的
加锁
03 内部静态变量的懒汉单例(C++11 线程安全)
/// 内部静态变量的懒汉实现 // class Single { public: // 获取单实例对象 static Single &GetInstance(); // 打印实例地址 void Print(); private: // 禁止外部构造 Single(); // 禁止外部析构 ~Single(); // 禁止外部复制构造 Single(const Single &signal); // 禁止外部赋值操作 const Single &operator=(const Single &signal); }; Single &Single::GetInstance() { // 局部静态特性的方式实现单实例 static Single signal; return signal; } void Single::Print() { std::cout << "我的实例内存地址是:" << this << std::endl; } Single::Single() { std::cout << "构造函数" << std::endl; } Single::~Single() { std::cout << "析构函数" << std::endl; } /// 内部静态变量的懒汉实现 //
内部静态变量的懒汉单例的运行结果:
-std=c++0x编译是使用了C++11的特性,在C++11内部静态变量的方式里是线程安全的,只创建了一次实例,内存地址是0x6016e8,这个方式非常推荐,实现的代码最少!
[root@lincoding singleInstall]#g++ SingleInstance.cpp -o SingleInstance -lpthread -std=c++0x
局部静态
04 饿汉式单例 (本身就线程安全)
// 饿汉实现 / class Singleton { public: // 获取单实例 static Singleton* GetInstance(); // 释放单实例,进程退出时调用 static void deleteInstance(); // 打印实例地址 void Print(); private: // 将其构造和析构成为私有的, 禁止外部构造和析构 Singleton(); ~Singleton(); // 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值 Singleton(const Singleton &signal); const Singleton &operator=(const Singleton &signal); private: // 唯一单实例对象指针 static Singleton *g_pSingleton; }; // 代码一运行就初始化创建实例 ,本身就线程安全 Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton; Singleton* Singleton::GetInstance() { return g_pSingleton; } void Singleton::deleteInstance() { if (g_pSingleton) { delete g_pSingleton; g_pSingleton = NULL; } } void Singleton::Print() { std::cout << "我的实例内存地址是:" << this << std::endl; } Singleton::Singleton() { std::cout << "构造函数" << std::endl; } Singleton::~Singleton() { std::cout << "析构函数" << std::endl; } // 饿汉实现 /
饿汉式单例的运行结果:
从运行结果可知,饿汉式在程序一开始就构造函数初始化了,所以本身就线程安全的
饿汉式
特点与选择
- 懒汉式是以时间换空间,适应于访问量较小时;推荐使用内部静态变量的懒汉单例,代码量少
- 饿汉式是以空间换时间,适应于访问量较大时,或者线程比较多的的情况
需要C/C++ Linux服务器架构师学习资料加群获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
-
“NAT映射”和“打洞机制”
2019-09-04 09:08:49上篇文章讲了路由器寻路过程,今天说说“NAT映射”和“打洞机制”。 一,NAT映射 ...要描述NAT, 要先讲讲私有地址和全局地址。我们说现在要从主机A给主机B发送...我们ipconfig出来都是私有IP地址,为什么会出现私有...上篇文章讲了路由器寻路过程,今天说说“NAT映射”和“打洞机制”。
一,NAT映射
参考文章:https://www.cnblogs.com/penghuwan/p/7753022.html
要描述NAT, 要先讲讲私有地址和全局地址。我们说现在要从主机A给主机B发送消息,需要依赖的是主机A和主机B的端口号与IP地址。但是我们平常在电脑上
我们
ipconfig
出来都是私有IP地址,为什么会出现私有IP呢?就是因为IP地址不够用了,给你一台PC就分配一个公有IP地址太浪费了,而私有IP是不能直接在网络上进行通信的,你可以把私有IP看做是门牌号,假设你的门牌号是11号,但是北京有11号,上海也有11号,所以如果你直接说你是11号,快递员怎么可能知道你到底在呢!所以我们如果想在网络上进行通信,是需要将私有IP转为公网IP,那么谁来做这个工作呢?NAT映射表NAT映射表存在在路由器里面,实现的是私有IP与公有IP之间的转换;实际上可能是你家一台路由器拥有一个公网IP,而所有连在这台路由器上的所有设备都共享一个公网IP。那么问题又来了,既然共享一个公网IP,那接受回来的数据又怎么知道到底应该是哪一台设备接受呢?我们说过了在网络上唯一表示一个进程需要的是IP地址+端口号,既然IP地址一样,我们就对端口号做文章就可以了,就如下图(同理我们也可以对A1,A2,A3进行拓展,这样IP地址就够用了)
二,打洞机制
比如说我用QQ给妈妈发个消息,实际上并不是我的主机和妈妈的主机直接通讯,我们之间要通过腾讯的服务器来帮助我们通讯,我的主机并不知道妈妈主机的IP以及端口号,妈妈主机也不知道我的。但是假如说我和妈妈现在要进行视频通话,如果中间再隔个腾讯服务器,就很难达到即时通讯的目标,所以腾讯借助公网IP就会帮我的主机和妈妈的主机打个洞来提高提高数据传输的效率。
有个问题是为什么是腾讯帮助打洞?这是因为路由器的保护机制:对于陌生IP第一次发送过来的数据包,路由器会进行屏蔽或丢弃,这是为了防止网络的恶意攻击。
打洞机制我认为可以这样:没有打洞机制前,就相当于腾讯是接线员,它知道我的电话也知道妈妈的电话,我和妈妈之间通讯需要打电话先给接线员,再有接线员转接才可以;但是打洞机制就相当于接线员把我的电话和妈妈的电话发给彼此,这样我们就可以直接联络了。
-
ifconfig命令
2019-05-10 09:39:164. 为什么会出现无类型域间选路? 5. 什么是无类型域间选路? 6. 公有IP地址和私有IP地址 7. 如何获得公有IP、公网地址? 8. 如何理解私有网络的出口地址? 9. 如何理解ip addr的输出? 1. net-tools和iproute... -
UDP打洞学习
2009-08-27 15:54:00因为在UDP打动技术里面,NAT设备是不可缺少的,所以,先简单介绍一下NATNAT俗称网络地址转换,为什么会出现这个技术?是因为随着互联网技术的发展,IP地址明显的不够,于是NAT技术应时而生,它不仅解决了IP地址不住... -
Linux下系统调用execl会等待一段时间才执行指定的可执行程序?
2015-09-11 08:08:22fork子进程后,使用execl或者execlp调用可执行程序会出现等待一段时间才进入可执行程序,为什么会出现等待,有猿友遇到这个问题吗?很是奇怪,并非每一次都会出现这样的问题,如果重启电脑后,就不会出现,但是运行... -
由于误操作,将仓库设置为私有导致之前500star丢失,欢迎大家从新star github地址:https://github.com/scxwhite/hera 数据平台打造的任务调度系统(HERA) 目前接入hera的公司(点我接入): 杭州二维火科技有限...
-
【虚拟内存】虚拟内存概述
2021-03-04 19:27:26共享主存会出现的问题就是太多的进程需要太多的内存,而内存已经不够了,那么进程就会无法运行。其次,可能会发生内存的覆盖问题,即一个进程写进了另一个进程的内存空间,这会导致无法预知的错误。 所以,为了有效... -
无穷小应该从何处放飞?
2013-08-16 06:03:55为保证《微积分阅览室》8月18日对外开放(试运行),15日我们开始加载上传数据。...图片原来的地址被高网站打上了私有“印记”,不利于其他网站的转载,同时,读者下载之后图片也会自动消失。那么,我们 -
Java学习笔记(必看经典)
2013-01-31 22:54:38为什么会存在overloading技术呢?作为应对方法的细节。 利用类型的差异来影响对方法的调用。 吃()可以分为吃肉,吃菜,吃药,在一个类中可以定义多个吃方法。 构造方法也可以实现overloading。例: public void ... -
计算机网络复习题
2014-12-29 19:01:351.简述计算机网络和互联网的定义 答:计算机网络是一些互相连接的、自治(自主)的计算机的集合。为用户提供资源共享和...4).NAT,一个公用IP 地址代理多个私有地址 5).使用更大地址空间的新版本IP 协议,如IPv6. -
c++ 面试题 总结
2009-09-16 08:44:40为什么? int n; if (n == 10) // 第一种判断方式 if (10 == n) // 第二种判断方式 如果少了个=号,编译时就会报错,减少了出错的可能行,可以检测出是否少了= -------------------------------------------------... -
语言程序设计课后习题答案
2012-12-27 17:02:37二进制是基数为2,每位的权是以2 为底的幂的进制,遵循逢二进一原则,基本符号为0和1。采用二进制码表示信息,有如下几个优点:1.易于物理实现;2.二进制数运算简单;3.机器可靠性高;4.通用性强。其缺点是它表示数... -
C/C++程序员面试指南.杨国祥(带详细书签).pdf
2018-04-08 02:46:41面试题6:判断程序会出现什么问题 第7章 嵌入式编程 面试题1:编码实现某一变量某位清或置 面试题2:用C编写一个死循环程序 面试题3:用变量a给出下面的定义 面试题4:设置地址为0x67a9的整型变量的值为0xaa66 面试... -
图解CSS3核心技术与案例实战.大漠(带详细书签)
2017-12-18 18:33:58为什么会选择这个时候编写这样一本图书呢?原因很简单。对于希望Web应用开发者而言,CSS3可以说是众望所归,这也是技术变更的硬性需求。在实际Web应用中新标准的采纳程度正在以令人目眩的速度不断地变更着,众多... -
net学习笔记及其他代码应用
2010-11-16 18:15:0911.用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层? 答:一般为3层 数据访问层,业务层,表示层。 数据访问层对数据库进行增删查改。 业务层一般分为二层,业务表观层... -
java 面试题 总结
2009-09-16 08:45:34为什么要有GC? GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域... -
kubernetes/k8s+SpringCloud全栈技术
2021-02-06 12:12:34为什么要用微服务? 单体架构下的所有代码模块都耦合在一起,代码量大,维护困难,想要更新一个模块的代码,也可能会影响其他模块,不能很好的定制化代码。微服务中可以有java编写、有Python编写的,他们都是靠... -
超级有影响力霸气的Java面试题大全文档
2012-07-18 09:47:04为什么要有GC? GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域... -
SynergyInstaller-1.3.1
2015-09-15 14:40:26其实仔细看你的终端命令行前面写的应该是:"XXX@XXX-desktop:~/"(这里有个误区会让你以为你的登录名就是计算机名,其实不是,计算机名应该是@后面的内容)所以我在这里把凡是出现office-1的地方替代成office-1-... -
有时候我们会遇到jar包冲突的bug,或者说就是想单纯的看看我那简单的一句implementations到底导入了多少个jar包,这也是为什么Groovy语言的Gradle和XML语言的Maven相比,前者就能如此简洁。这时候,就可以去Android...
-
跨项目区块复用方案实践
2020-12-08 23:39:39为什么是区块复用而不是组件复用? 为了解答这个问题,我们先明确下这些概念的定义,下面直接引用阿里飞冰相关的定义: 组件(component):功能比较确定同时复杂度较高... -
Qt Creator 的安装和hello world 程序+其他程序的编写--不是一般的好
2011-01-28 17:02:0810.程序运行会出现空白的对话框,如下图。 11.我们双击文件列表的dialog.ui 文件,便出现了下面所示的图形界面编辑界 面。 12.我们在右边的器件栏里找到Label 标签器件 13.按着鼠标左键将其拖到设计窗口上,如下图。... -
C#微软培训教材(高清PDF)
2009-07-30 08:51:17C#--微软.NET的第一语言 本书着重介绍语言本身,比较少涉及应用,不错的入门书,从头讲起,不怕不明白。 <<page 1>> page begin==================== 目 ...1.1.1 什么是.NET 2000 年 6 月 ... -
【。net 专业】 面试题
2010-05-19 14:48:46如果一个密封类被指定为其它类的基类,则会发生编译时错误。 密封类不能同时为抽象类。 sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。具体说来,由于密封类永远不会有任何派生类,所以对... -
C#微软培训资料
2014-01-22 14:10:17<<page 1>> page begin==================== 目 ...1.1.1 什么是.NET 2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得纪念的一天 这一天 微软公司正式推出了其下一代... -
java经典面试2010集锦100题(不看你后悔)
2011-02-21 12:43:25B) Test类的对象t可以直接访问month变量,但是不能直接访问day变量,因为day为私有变量,只有类内可以访问。 C) 该程序能通过编译并运行,但是如果想得到输出“I am print in Test”的结果,需要在横线处填写t.show... -
Hybrid App 离线包方案实践
2021-01-02 19:51:42则会出现离线包平台已经上传了了未经验证的前端资源,而静态资源服务器却没有更新的情况。因此仍需要手动上传离线包。当然读者可以根据实际情况选择合适的上传方式。 <h4>2. 多 App 情况下如何区分离线包属于... -
本例中以校验MAC地址(格式:080027004C44)为例,实现参数校验自定义注解及检验规则。 详情请见:https://github.com/higminteam/practice/blob/master/src/main/java/com/practice/spring/customizeValid 1.5 ...