## 网络

### Q：从socket收发的数组，到序列化反序列化对象实例，需要拷贝几次？怎么分配内存？（`高性能网络架构最核心问题`）

A：字节拷贝，效率很高，不是性能的主要问题，1次或者2次拷贝都可以接受。性能主要消耗在内存申请和回收。

- 发送过程：  
	1次或0次拷贝，有必要使用内存池，可以做到发送过程0分配内存。
- 接受过程：  
	0拷贝，1次构造消息实例对象，1次反序列化赋值过程。
	1次构造对象实例（没法优化，因为不知道实例的用途，无法控制生命周期和回收，无法使用池。要么手动归还池对象，要么就new）。  

	一种解决方案思路如下（没有实际意义）：
	目前来看，消息类池是可以实现的，把字节数组直接反序列化到指定实例可以通过修改序列化类库实现。从而实现0拷贝。
	
	```cs
	[MessagePackObject]
	public class MyClass:ReBase
	{
		/// Key is serialization index, it is important for versioning.
		[Key(0)]
		public int Age { get; set; }

		[Key(1)]
		public string FirstName { get; set; }

		[Key(2)]
		public string LastName { get; set; }

		/// public members and does not serialize target, mark IgnoreMemberttribute
		[IgnoreMember]
		public string FullName { get { return FirstName + LastName; } }
	}

	public class ReBase
	{
		~ReBase()
		{
			///此处还需要重置字段默认值
			Pool.Return(this);
			GC.ReRegisterForFinalize(this);
		}
	}
	```

	然而终结器回收对象也有性能问题：
	- 没有办法控制对象什么时候回收。
	- 对象可能会由0代对象变为1代对象甚至2代对象，大量的可复活对象加长了GC运行时间，得不偿失。  
	 
	结论，反序列化过程中new 对象可以容忍。

# GraphQL
经过调研，GraphQL不是很适合游戏网络程序。对于游戏来说，API变动频率还是很低。