`
canonical
  • 浏览: 368146 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

D语言与tpl之编译期动作

阅读更多
   最近D语言发布了1.0版,这是一个由编译器开发者所设计的编译语言,语法类似C++, 但是针对C++的弊病作了大量修正,并增加了很多现代特征,其中还是有一些新意在其中的。http://www.digitalmars.com/d/overview.html 我对其比较感兴趣的部分是D语言明确提出的编译期运行的概念。虽然C++让大众了解了meta programming技术,很多人因此认为meta programming的威力在于类型演算,但是在我看来meta programming的真正作用在于在编译期可以“动态”产生或调整代码结构。它依赖于类型是因为我们只能利用类型来承载一些额外信息, 这无疑也是对于类型的一种滥用。在D语言中template所接受的不仅仅是类型, 或者类型的类型,它可以是任何符号.
  template MixInAttr(T, char[] name){ 
     mixin(" T _" ~ name ~";");
     mixin(" T "~name~"(){ return _"~name~"; }");
     mixin(" void "~name~"(T v){ _"~name~" = v;}");
  } 
 
  template MixInOtherAttr(T, T v){
    T _otherAttr = v;
   
    int otherAttr(){ return _otherAttr; }
  }
 
  const int myValue = 1;
 
  int addFunc(int x){
    return x + 1;
  }
  
  class MyTest{ 
     mixin MixInAttr!(int, "myAttr"); 
     mixin MixInOtherAttr!(int,4);
    
     static if(addFunc(myValue) 〉 0){
        int testFunc(){ return 5;}
     }
  }
 
  void main(){ 
     auto t = new MyTest;
     t.myAttr = 3;
     int v = t.myAttr;   
     v = t.otherAttr;
     t.testFunc();
  }  
  不过现在编译期运行无疑是一个正在探索的方向, 在D语言中的使用方式并不是非常理想的, 在形式和功能实现上都存在着重大改进的可能. 
 
  在witrix平台的tpl模板语言中,我们也引入了编译期运行的概念,只是tpl的语言特征非常简单再加上xml格式特殊的规范性,编译期运行在tpl中的实现是非常直接和明确的.在tpl中定义了<cp:run〉标签,它的内容在编译期运行, 输出结果(xml字符串)将被继续编译. 在<cp:run〉中可以执行任何有效的tpl代码, 它们在编译期状态空间中运行. 例如
 〈cp:run〉
   〈c:forEach var="_x" items="${tagBody.children()}"〉
       bla bla bla...
   〈/c:forEach〉
 〈/cp:run〉
在EL表达式中我们通过cp前缀实现普通调用和编译期调用的混杂.
  〈cp:const class="mypkg.MyConstantClass"/〉
  〈c:eval expr="${myFunc(cp:const.MY_CONST, commonVar, cp:funcInCompileTime())}" /〉
  〈cp:compile test="${exprInCompileTime}"〉
     any tpl ...
  〈/cp:compile〉

 其实当我们把改进的目光开始放到编译期的结构方面的时候, 可以做的工作是非常多的. 例如从结构上看, 继承策略相当是类结构的一种一阶替换策略.
  类B(methodB) extends 类A(methodA, methodB)  ==〉 类B(methodA[inA], methodB[inB])
如果我们放弃概念层面上的纠缠,而如同template那样只关注语法结构, 则可以发展出更加复杂的替换操作.
  NODE_B(                              NODE_A(                                    NODE_B(
    SUB_NODE_A1        〉〉    SUB_NODE_A1             ==〉    SUB_NODE_A1
      SUB_NODE_B11                   SUB_NODE_A11                         SUB_NODE_B11
                                                         SUB_NODE_A12                          SUB_NODE_A12
  )                                                  )                                                  )
C++中及D语言中的template技术在某种意义上相当于是在代码结构中预留了空洞, 可以实现跨越类结构的替换填充. 只是D语言挖洞的能力无疑比C++强大的多. 
  如果我们考察的再细致一些, 就会发现两个语法节点的融合也是存在多种策略的.
  B 〉〉 A ==〉 (remove_A, replace_A, insert_B_before_A, insert_B_after_A, insert_B_into_A, insert_A_into_B)
而通过insert_A_into_B/insert_B_into_A策略既可实现所谓的AOP intercept操作http://canonical.iteye.com/blog/34941 在witrix平台的BizFlow技术中, 我们通过高级的结构融合策略实现为任意实体引入流程支持. 最简单的情况下我们所需要做的工作只是增加一个语法元素
 〈bizflow extends="myflow"〉
引入流程意味着对界面的一系列修正, 例如增加,删除某些菜单, 同时要增加很多流程相关函数, 对某些函数实施AOP操作, 在各处引入权限控制等等, 这些都可以通过extends操作引入.

  在传统上, 编译器结构是固化的, 它所编译的代码结构是固化的, 而它所编译出的代码也是固化的, 但是现代语言的各种发展正致力于在各个层面引入动态性. 编译期运行抑或是编译期结构操纵技术的引入是在一个层面上打开了潘多拉魔盒. 它让我们看到了前所未有的技术可能性, 但它无疑也是危险的,难以控制的. 我们目前的做法是尽量克制,只在局部使用, 但我相信它在很多语言中都是可以在理论上严格定义,并精确实现的, 我们最终也能够找到合适的形式来约束它的破坏性. 在这个过程中我们需要引入更多的物理化的视角。
分享到:
评论
21 楼 hyf 2007-05-08  
一种方法是忘掉他,
在你觉得很需要他的时候,一般都是恰当时机。
20 楼 weixiao 2007-05-08  
hyf 写道
七猫 写道
hyf 写道
七猫 写道
我只是认为C++开发者更需要的是一大堆库,而不是一些语法上的改变。

两者都需要。
象c++Ox中的一条关于引入lambda的建议,如果不接受。像boost这样搞下去也没有活路
语法有没有,大家可以绕道走。
但没有库,就得自己写了。

其实现有的语法已经能满足大部分人需要了,对于所谓的原编程之类的,我很少看到大量使用,而且这种风格的代码的阅读性和可维护性我想大家心里都有数的。

对于要完成一个项目,库当然重要。
但依靠语法的逻辑抽象能力,我可以做到更细致的复用设计,有些是功能库做不到的。

MP之所没有大量使用,
一来是没有这种习惯,所以就没有需要
二来是现在的语法导致这样做 复杂、鸡肋

其实,现在的C++只要适当使用,不会降低可读性和可维护性。

“只要适当使用”,几个字,包含了多少血和泪。一个资质中上的程序员,没个三几年时间,如何能够“适当使用”?
19 楼 qiezi 2007-03-09  
qiezi 写道
hyf 写道
假设变参模板用TArgs表示
除非你有一种方法能把类型转化成字符串,实现
mixin(str(head(TArgs)) ~ " item" ~ i;

你说D语言的mixin表达式要求参数字符串必须是一个完整的表达式
head(TArgs) mixin("item" ~ i); 应该不行吧


等待你的例子。

出差在外,上网不方便,这边网吧连USB也禁了。已经完成了,加上空行和整个文件大概60行左右,包括一个简单的使用测试。

完整代码:
import std.stdio;
import std.metastrings;

private template attr_accessor(T, char[] name){
	mixin("
		private T _" ~ name ~ ";
		public T " ~ name ~ "(){
			return _" ~ name ~ ";
		}
		public void " ~ name ~ "(T v){
			_" ~ name ~ " = v;
		}"
	);
}

template attrs(T){
	mixin attr_accessor!(T, "item1");
}

template attrs(T, Args ...){
	mixin attrs_without_names!(0, T, Args);
}

template attrs(T, char[] s, Args ...){
	mixin attrs_with_names!(0, T, s, Args);
}

// 这个模板参数n是为了避免mixin递归错误。
private template attrs_with_names(int n, T, Args ...){
	static if (Args.length){
		mixin attr_accessor!(T, Args[0]);
		mixin attrs_with_names!(n + 1, T, Args[1..$]);
	}
}

private template attrs_without_names(int n, Args ...){
	static if (Args.length){
		mixin attr_accessor!(Args[0], "item" ~ ToString!(n + 1));
		mixin attrs_without_names!(n + 1, Args[1..$]);
	}
}

void main(){
	class Foo{
		mixin attrs!(int, "aaa");
		mixin attrs!(int, float, char[]);
	}

	auto foo = new Foo;
	foo.aaa = 1;
	foo.item1 = 3;
	foo.item2 = 5;
	foo.item3 = "abc";

	writefln(foo.aaa);
	writefln(foo.item1);
	writefln(foo.item2);
	writefln(foo.item3);
	writefln(typeid(typeof(foo.tupleof)));
}
18 楼 canonical 2007-03-07  
to Elminster:
  meta programming对于C++而言是基于类型运算的,或者你把meta programming等价于C++中的类型运算。而在我的概念中,meta programming意味着对编译期运算能力的开发。在tpl语言中,编译期运算是个明确的概念,而它是符合一定的形式要求的,但是并不是类型运算,实际上在tpl中通过其他渠道来传递信息。
17 楼 hyf 2007-03-07  
看了你attr_accessor模板,明白你的意思了
16 楼 qiezi 2007-03-07  
hyf 写道

我还以为可以做到 mixin(typeof(T).fullname() ~ ...
qiezi 写道
template foo(Args ...){
    static if (is(Args[0] == char[]))
        ...
}

这个判断总是不能为真,不知是D的问题还是我使用上的问题,我改用匹配的方法:
template attrs(T, Args ...){
}

template attrs(T, char[] s, Args ...){
}

如果是手工枚举所有类型的话就没没法用于自定义类型了。


这个并不是手工枚举所有类型,而是判断第2个模板参数,如果是字符串值,就把它和后面的参数作为属性的名称。否则就把所有模板参数当作类型,依次定义item1, item2 ...

全部用字符串来生成是最差的做法,即便能够实现,实现起来也不方便。
15 楼 hyf 2007-03-07  

我还以为可以做到 mixin(typeof(T).fullname() ~ ...
qiezi 写道
template foo(Args ...){
    static if (is(Args[0] == char[]))
        ...
}

这个判断总是不能为真,不知是D的问题还是我使用上的问题,我改用匹配的方法:
template attrs(T, Args ...){
}

template attrs(T, char[] s, Args ...){
}

如果是手工枚举所有类型的话就没没法用于自定义类型了。
14 楼 qiezi 2007-03-07  
hyf 写道
假设变参模板用TArgs表示
除非你有一种方法能把类型转化成字符串,实现
mixin(str(head(TArgs)) ~ " item" ~ i;

你说D语言的mixin表达式要求参数字符串必须是一个完整的表达式
head(TArgs) mixin("item" ~ i); 应该不行吧


等待你的例子。

出差在外,上网不方便,这边网吧连USB也禁了。已经完成了,加上空行和整个文件大概60行左右,包括一个简单的使用测试。

对字符串的判断似乎有问题:
template foo(Args ...){
    static if (is(Args[0] == char[]))
        ...
}

这个判断总是不能为真,不知是D的问题还是我使用上的问题,我改用匹配的方法:
template attrs(T, Args ...){
}

template attrs(T, char[] s, Args ...){
}

来进行区分,在里面调用一个递归的mixin模板,把各个成员生成出来。在这个mixin模板中,不断调用attr_accessor模板(我的blog中有),并递归地调用同一个模板,把剩余参数传递过去,递归是模板中使用非常频繁的技术。有一点要注意的是,递归mixin在D中是不允许的,但可以传递一个多余的整数模板参数避开这个问题。

并不需要把类型转成字符串,当然如果想做也能做成,参考pyd里面的实现代码,我的blog中有一篇讲了这个,只是不知道是否适用所有类型。

最后的调用方式如下:

class Foo{
  mixin attrs!(int, "foo");
  mixin attrs!(float, "bar");
  mixin attrs!(char, char[], float, short);
}

auto foo = new Foo;
foo.foo = 1;
foo.bar = 3.0f;
foo.item1 = 'c';
foo.item2 = "cc";
foo.item3 = 5.0f;
foo.item4 = 7;
13 楼 Elminster 2007-03-07  
<br/>
<strong>canonical 写道:</strong><br/>
<div class='quote_div'>   最近D语言发布了1.0版,这是一个由编译器开发者所设计的编译语言,语法类似C++, 但是针对C++的弊病作了大量修正,并增加了很多现代特征,其中还是有一些新意在其中的。<a href='http://www.digitalmars.com/d/overview.html '>http://www.digitalmars.com/d/overview.html </a>我对其比较感兴趣的部分是D语言明确提出的编译期运行的概念。虽然C++让大众了解了meta programming技术,很多人因此认为meta programming的威力在于类型演算,但是在我看来meta programming的真正作用在于在编译期可以“动态”产生或调整代码结构。它依赖于类型是因为我们只能利用类型来承载一些额外信息, 这无疑也是对于类型的一种滥用。在D语言中template所接受的不仅仅是类型, 或者类型的类型,它可以是任何符号. <br/>
...</div>
<div class='quote_div'/>
<div class='quote_div'/>
<div class='quote_div'/>
<p class='quote_div'>我很奇怪你为什么认为你下面列举的这些不是对类型的计算。meta-programming 所带来的新东西,就是我们可以通过一些类型或是编译时常量为参数,让编译器在编译的时候生成某些我们想要的类型。D 的 mixin 也好,C++ 的 Policy Based Design 和 Expression-Template 也好,都是这种新的表达能力的体现。</p>
12 楼 hyf 2007-03-06  
假设变参模板用TArgs表示
除非你有一种方法能把类型转化成字符串,实现
mixin(str(head(TArgs)) ~ " item" ~ i;

你说D语言的mixin表达式要求参数字符串必须是一个完整的表达式
head(TArgs) mixin("item" ~ i); 应该不行吧


等待你的例子。
11 楼 qiezi 2007-03-06  
hyf 写道
  template MixInAttr(T, char[] name){ 
     mixin(" T _" ~ name ~";");
     mixin(" T "~name~"(){ return _"~name~"; }");
     mixin(" void "~name~"(T v){ _"~name~" = v;}");
  }  


问几个问题,
我要MixInAttr!(int, ["myAttr1", "myAttr2", ..]); 
可以?

MixInAttr!(int, string, float);
得到 int item1; string item2; float item3;
可以?


完全可以,这有两个方面的问题,一是变参模板,二是对于模板参数是类型还是字符串的判断,这在D里面都是轻而易举。现在没有时间,有空我写个简单的例子。

hyf 写道

要真是那么追求code generate的能力,那就索性把整个D语言弄进编译时执行算了.

D语言目前正在把更多的东西加进编译时执行。D语言模板到现在已经和C++大不相同了,编译期计算也是为了解决以前编译时和执行时要写两套代码而作的。
hyf 写道

况且, 你展示的这些代码, 让我想起MACRO, C++不推荐使用MACRO就是因为它可以随意产生代码, 类型不安全, 可见性(可读)差.

D语言的mixin表达式要求参数字符串必须是一个完整的表达式,这和MACRO完全不同。MACRO也不是C++语言的一部分,如果你愿意,你也可以把C宏用在任何语言中,调用一个预处理器程序进行处理。这些东西都是强大的工具,会用就能用好,不会用不用它就是了。


hyf 写道

我觉得C++的MP设计非常适合,
在C++0x出来之后, 就可以更好的应付MP的复杂性. (现在已经够复杂了)
你可以去看看OpenC++, 他的元编程在语法树上做文章, 灵活性最强了.  是啥下场?

在这个世界上有好多工具可以做代码生成, (生成我还可以看到整个结果, 怎么不对一目了然)
在语言中做这种事情, 一来IDE智能提示废了, 而且没有编译期调试还玩不转.

D并不是做了这个就扔了那个,你不使用编译期执行,它还是一种类似C++的语言,一个项目中编译期执行的部分也不会太多。IDE的智能提示和调试这两种东西并不是人人都必须要用,编译期执行也还是可以写单元测试的。
10 楼 canonical 2007-03-05  
实际上因为C++的复杂性,以至于设计师很难有余裕在语法上再做创新。C++对于计算是够用的,但是对于描述性内容并不适当。MP其实很有用,只是受技术限制一般人想不到它的用处而已。
9 楼 hyf 2007-03-05  
注意,某些观点我跟你一致。
我不是说库不重要,也不是想证明Boost可读性好。

我想说语法的改进一样很重要,他的能力直接影响我们如何设计库,如何复用代码。
而这次C++改良正是要降低这些复杂性。
8 楼 hyf 2007-03-05  
我是说适当使用,而不是所有。

我在项目中对引入外部的模板库很谨慎,即使是STL也不是全部用上。

Boost来和Qt这些应用库很难比较,大家的方向不一样。
比方,Qt为了可用性,signal/solt是外部编译器做代码生成的。
7 楼 七猫 2007-03-05  
我觉得比较boost和qt的原代码可以得到一些启示。

到底哪种代码可读性和可维护性更好。
6 楼 hyf 2007-03-05  
七猫 写道
hyf 写道
七猫 写道
我只是认为C++开发者更需要的是一大堆库,而不是一些语法上的改变。

两者都需要。
象c++Ox中的一条关于引入lambda的建议,如果不接受。像boost这样搞下去也没有活路
语法有没有,大家可以绕道走。
但没有库,就得自己写了。

其实现有的语法已经能满足大部分人需要了,对于所谓的原编程之类的,我很少看到大量使用,而且这种风格的代码的阅读性和可维护性我想大家心里都有数的。

对于要完成一个项目,库当然重要。
但依靠语法的逻辑抽象能力,我可以做到更细致的复用设计,有些是功能库做不到的。

MP之所没有大量使用,
一来是没有这种习惯,所以就没有需要
二来是现在的语法导致这样做 复杂、鸡肋

其实,现在的C++只要适当使用,不会降低可读性和可维护性。
5 楼 七猫 2007-03-05  
hyf 写道
七猫 写道
我只是认为C++开发者更需要的是一大堆库,而不是一些语法上的改变。

两者都需要。
象c++Ox中的一条关于引入lambda的建议,如果不接受。像boost这样搞下去也没有活路
语法有没有,大家可以绕道走。
但没有库,就得自己写了。

其实现有的语法已经能满足大部分人需要了,对于所谓的原编程之类的,我很少看到大量使用,而且这种风格的代码的阅读性和可维护性我想大家心里都有数的。
4 楼 hyf 2007-03-05  
七猫 写道
我只是认为C++开发者更需要的是一大堆库,而不是一些语法上的改变。

两者都需要。
象c++Ox中的一条关于引入lambda的建议,如果不接受。像boost这样搞下去也没有活路
3 楼 七猫 2007-03-05  
我只是认为C++开发者更需要的是一大堆库,而不是一些语法上的改变。
2 楼 canonical 2007-03-04  
关于D语言的语法问题建议自己去试验, 我并不精通。

关于tpl的编译期运行能力问题,我只能说我们需要这些能力。我们也基于这些能力作了很多工作。 并不是简单的“把整个D语言弄进编译时执行"或者 使用  MACRO就可以了。 这里的关键是如何定义合适的形式约束。OpenC++的失败是它自己的问题,而不是meta programming的问题。 就如同EJB的失败不意味着它所对应的理想的失败。

相关推荐

    基于智能温度监测系统设计.doc

    基于智能温度监测系统设计.doc

    搜广推推荐系统中传统推荐系统方法思维导图整理-完整版

    包括userCF,itemCF,MF,LR,POLY2,FM,FFM,GBDT+LR,阿里LS-PLM 基于深度学习推荐系统(王喆)

    2023-04-06-项目笔记 - 第三百五十五阶段 - 4.4.2.353全局变量的作用域-353 -2025.12.22

    2023-04-06-项目笔记-第三百五十五阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.353局变量的作用域_353- 2024-12-22

    和美乡村城乡融合发展数字化解决方案.docx

    和美乡村城乡融合发展数字化解决方案.docx

    CNN基于Python的深度学习图像识别系统

    基于Python的深度学习图像识别系统是一个利用卷积神经网络(CNN)对图像进行分类的先进项目。该项目使用Python的深度学习库,如TensorFlow,构建和训练一个模型,能够自动识别和分类图像中的对象。系统特别适合于图像处理领域的研究和实践,如计算机视觉、自动驾驶、医疗影像分析等。 项目的核心功能包括数据预处理、模型构建、训练、评估和预测。用户可以上传自己的图像或使用预定义的数据集进行训练。系统提供了一个直观的界面,允许用户监控训练进度,并可视化模型的性能。此外,系统还包括了一个模型优化模块,通过调整超参数和网络结构来提高识别准确率。 技术层面上,该项目使用了Python编程语言,并集成了多个流行的机器学习库,如NumPy、Pandas、Matplotlib等,用于数据处理和可视化。模型训练过程中,系统会保存训练好的权重,以便后续进行模型评估和预测。用户可以通过简单的API调用,将新的图像输入到训练好的模型中,获取预测结果。

    拳皇97.exe拳皇972.exe拳皇973.exe

    拳皇97.exe拳皇972.exe拳皇973.exe

    基于python和协同过滤算法的电影推荐系统

    基于python和协同过滤算法的电影推荐系统 基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法的电影推荐系统基于python和协同过滤算法

    DEV-CPP-RED-PANDA

    DEV-CPP-RED-PANDA

    Python语言求解旅行商(TSP)问题,算法包括禁忌搜索、蚁群算法、模拟退火算法等

    Python语言求解旅行商问题,算法包括禁忌搜索、蚁群算法、模拟退火算法等。

    pdfjs2.5.207和4.9.155

    pdfjs 用于在浏览器中查看/预览/打印pdf。 pdfjs 2.5.207 支持firefox/chrome/edge/ie11以上版本。 如果需要支持旧版本浏览器,可以使用这个,是未修改过的原版,支持打印和下载按钮。亲测有效。 pdf 4.9.155分两个包: pdfjs-4.9.155-dist.zip pdfjs-4.9.155-legacy-dist.zip

    建设项目现场高温人员中暑事故应急预案.docx

    建设项目现场高温人员中暑事故应急预案

    数据结构上机实验大作业-线性表选题.zip

    数据结构上机实验大作业-线性表选题.zip

    基于高德地图的校园导航全部资料+详细文档+高分项目.zip

    【资源说明】 基于高德地图的校园导航全部资料+详细文档+高分项目.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    全自动批量建站快速养权重站系统【纯静态html站群版】:(GPT4.0自动根据关键词写文章+自动发布+自定义友链+自动文章内链+20%页面加提权词)

    【静态站群程序视频演示,只有视频,不含程序,下载须知】【静态站群程序视频演示,只有视频,不含程序,下载须知】全自动批量建站快速养权重站系统【纯静态html站群版】:(GPT4.0自动根据关键词写文章+自动发布+自定义友链+自动文章内链+20%页面加提权词)

    9.30 SWKJ 男头7张+女头2张.zip

    9.30 SWKJ 男头7张+女头2张.zip

    基于java+springboot+vue+mysql的技术交流和分享平台 源码+数据库+论文(高分毕业设计).zip

    项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea、vscode 数据库:MySql5.7以上 部署环境:maven 数据库工具:navicat

    一个通过单片机在各种屏幕上显示中文的解决方案.7z

    一个通过单片机在各种屏幕上显示中文的解决方案.7z

    Halcon模板匹配图像包

    图像

    线上辅导班系统-JAVA-基于springboot的线上辅导班系统的开发与设计(毕业论文)

    一、用户管理功能 用户注册与登录 学生注册:学生可以通过手机号、邮箱、社交账号等方式注册,填写个人信息(如姓名、年龄、学校等)。 家长/监护人账户:支持家长/监护人注册并管理学生账户,查看学习进度和成绩。 教师账户:教师可以注册并设置个人资料,上传资质认证文件。 管理员账户:管理员负责整个系统的管理,包括用户管理、课程管理、平台设置等。 用户权限管理 角色权限:系统根据用户类型(学生、家长、教师、管理员)分配不同权限,确保信息安全。 家长监督:家长可以查看子女的学习进度、成绩和教师反馈,参与学习监督。 个人资料管理 用户可以在个人中心更新基本信息,设置个人头像、联系方式、密码等。 支持学籍信息的维护,例如学生的年级、班级、课程历史等。 二、课程管理功能 课程设置 课程创建与编辑:教师或管理员可以创建和编辑课程内容,上传课件、视频、文档等教学材料。 课程分类:根据学科、年级、难度等维度进行课程分类,方便学生浏览和选择。 课程排课:管理员可以设置课程的时间表、教学内容和授课教师,并调整上课时间和频率。 课程安排与通知 课程预约:学生可以在线选择并预约感兴趣的课程,系统根据学生的时

    英特尔2021-2024年网络连接性和IPU路线图

    内容概要:本文档介绍了英特尔2021年至2024年的网络连接性产品和智能处理单元(IPU)的战略和技术路线图。涵盖了从10GbE到200GbE的不同系列以太网适配器的特性、性能和发布时间。详细列出了各个产品的关键功能,如PCIe接口、安全特性、RDMA支持等。同时,介绍了IPU的发展计划,包括200G、400G和800G的不同代次产品的性能提升和新的功能特点。 适合人群:从事网络工程、数据中心管理、IT架构设计的专业技术人员。 使用场景及目标:本文档主要用于了解英特尔未来几年在以太网适配器和IPU领域的技术和产品规划,帮助企业在采购和部署网络设备时做出决策。同时,为研究人员提供最新技术发展趋势的参考。 其他说明:文档内容涉及的技术细节和时间表可能会有变动,请以英特尔官方发布的最新信息为准。

Global site tag (gtag.js) - Google Analytics